buldthensnip/pkg/base/lib_va.lua
2015-02-20 17:23:20 +13:00

297 lines
7.8 KiB
Lua

--[[
This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]]
-- Vertex array API stuff
-- Basically, loaders and whatnot.
-- VA API available since 0.2a-1.
CAM_SHADING = {
0xC0/255.0,
0xA0/255.0,
0xD0/255.0,
0xE0/255.0,
0xFF/255.0,
0xD0/255.0,
}
--function parsekv6(pkt, name, ptsize, ptspacing)
function model_loaders.kv6(isfile, pkt, extra)
extra = extra or {}
if isfile then pkt = common.bin_load(pkt) end
if not pkt then return nil end
local scale = extra.scale or 1.0
local ptspacing = scale
if pkt:sub(1,4) ~= "Kvxl" then
error("not a KV6 model")
end
local _
-- load header
local xsiz, ysiz, zsiz
_, xsiz, ysiz, zsiz, pkt = common.net_unpack("IIII", pkt)
local xpivot, ypivot, zpivot
xpivot, ypivot, zpivot, pkt = common.net_unpack("fff", pkt)
local blklen
blklen, pkt = common.net_unpack("I", pkt)
-- load blocks
local l = {}
local i
for i=1,blklen do
local r,g,b,z,vis
b,g,r,_,z,vis,_,pkt = common.net_unpack("BBBBHBB", pkt)
local vnx = (math.floor(vis/1 ) % 2) ~= 0
local vpx = (math.floor(vis/2 ) % 2) ~= 0
local vnz = (math.floor(vis/4 ) % 2) ~= 0
local vpz = (math.floor(vis/8 ) % 2) ~= 0
local vny = (math.floor(vis/16) % 2) ~= 0
local vpy = (math.floor(vis/32) % 2) ~= 0
l[i] = {
--radius = ptsize,
x = nil, z = nil, y = (z-zpivot)*ptspacing,
r = r, g = g, b = b,
vnx = vnx, vny = vny, vnz = vnz,
vpx = vpx, vpy = vpy, vpz = vpz,
}
end
-- skip x offsets
pkt = pkt:sub(4*xsiz+1)
-- load xy offsets
-- TODO: check order
local x,y,i,j
i=1
for x=1,xsiz do
for y=1,ysiz do
local ct
ct, pkt = common.net_unpack("H", pkt)
for j=1,ct do
l[i].x = (x-xpivot)*ptspacing
l[i].z = (y-ypivot)*ptspacing
i = i + 1
end
end
end
-- create model
--[[
local mdl, mdl_bone
mdl = common.model_new(1)
mdl, mdl_bone = common.model_bone_new(mdl, #l)
common.model_bone_set(mdl, mdl_bone, name, l)
print("model data len:", #l)
return mdl
]]
local spx = extra.shading_off and 1 or CAM_SHADING[1]
local spy = extra.shading_off and 1 or CAM_SHADING[2]
local spz = extra.shading_off and 1 or CAM_SHADING[3]
local snx = extra.shading_off and 1 or CAM_SHADING[4]
local sny = extra.shading_off and 1 or CAM_SHADING[5]
local snz = extra.shading_off and 1 or CAM_SHADING[6]
-- make
return (function (settings)
local this = {
fmt = "kv6",
tex = settings.tex or nil,
filt = settings.filt or nil,
} this.this = this
local inscale = settings.inscale or 1.0
local scale0 = scale*(0.5 - inscale/2)
local scale1 = scale*(0.5 + inscale/2)
-- apply filter
local srcl = l
local l = {}
if this.filt then
local i
for i=1,#srcl do
l[i] = {}
l[i].r, l[i].g, l[i].b = this.filt(srcl[i].r, srcl[i].g, srcl[i].b)
l[i].x = srcl[i].x
l[i].y = srcl[i].y
l[i].z = srcl[i].z
l[i].vpx = srcl[i].vpx
l[i].vpy = srcl[i].vpy
l[i].vpz = srcl[i].vpz
l[i].vnx = srcl[i].vnx
l[i].vny = srcl[i].vny
l[i].vnz = srcl[i].vnz
end
else
l = srcl
end
local vl = {}
for i=1,#l do
local x0 = l[i].x+scale0
local y0 = l[i].y+scale0
local z0 = l[i].z+scale0
local x1 = l[i].x+scale1
local y1 = l[i].y+scale1
local z1 = l[i].z+scale1
local r = l[i].r/255.0
local g = l[i].g/255.0
local b = l[i].b/255.0
if l[i].vnx then
vl[1+#vl] = {x0,y0,z0,r*snx,g*snx,b*snx,-1,0,0}
vl[1+#vl] = {x0,y1,z0,r*snx,g*snx,b*snx,-1,0,0}
vl[1+#vl] = {x0,y0,z1,r*snx,g*snx,b*snx,-1,0,0}
vl[1+#vl] = {x0,y0,z1,r*snx,g*snx,b*snx,-1,0,0}
vl[1+#vl] = {x0,y1,z0,r*snx,g*snx,b*snx,-1,0,0}
vl[1+#vl] = {x0,y1,z1,r*snx,g*snx,b*snx,-1,0,0}
end
if l[i].vpx then
vl[1+#vl] = {x1,y0,z0,r*spx,g*spx,b*spx,1,0,0}
vl[1+#vl] = {x1,y0,z1,r*spx,g*spx,b*spx,1,0,0}
vl[1+#vl] = {x1,y1,z0,r*spx,g*spx,b*spx,1,0,0}
vl[1+#vl] = {x1,y1,z0,r*spx,g*spx,b*spx,1,0,0}
vl[1+#vl] = {x1,y0,z1,r*spx,g*spx,b*spx,1,0,0}
vl[1+#vl] = {x1,y1,z1,r*spx,g*spx,b*spx,1,0,0}
end
if l[i].vny then
vl[1+#vl] = {x0,y0,z0,r*sny,g*sny,b*sny,0,-1,0}
vl[1+#vl] = {x0,y0,z1,r*sny,g*sny,b*sny,0,-1,0}
vl[1+#vl] = {x1,y0,z0,r*sny,g*sny,b*sny,0,-1,0}
vl[1+#vl] = {x1,y0,z0,r*sny,g*sny,b*sny,0,-1,0}
vl[1+#vl] = {x0,y0,z1,r*sny,g*sny,b*sny,0,-1,0}
vl[1+#vl] = {x1,y0,z1,r*sny,g*sny,b*sny,0,-1,0}
end
if l[i].vpy then
vl[1+#vl] = {x0,y1,z0,r*spy,g*spy,b*spy,0,1,0}
vl[1+#vl] = {x1,y1,z0,r*spy,g*spy,b*spy,0,1,0}
vl[1+#vl] = {x0,y1,z1,r*spy,g*spy,b*spy,0,1,0}
vl[1+#vl] = {x0,y1,z1,r*spy,g*spy,b*spy,0,1,0}
vl[1+#vl] = {x1,y1,z0,r*spy,g*spy,b*spy,0,1,0}
vl[1+#vl] = {x1,y1,z1,r*spy,g*spy,b*spy,0,1,0}
end
if l[i].vnz then
vl[1+#vl] = {x0,y0,z0,r*snz,g*snz,b*snz,0,0,-1}
vl[1+#vl] = {x1,y0,z0,r*snz,g*snz,b*snz,0,0,-1}
vl[1+#vl] = {x0,y1,z0,r*snz,g*snz,b*snz,0,0,-1}
vl[1+#vl] = {x0,y1,z0,r*snz,g*snz,b*snz,0,0,-1}
vl[1+#vl] = {x1,y0,z0,r*snz,g*snz,b*snz,0,0,-1}
vl[1+#vl] = {x1,y1,z0,r*snz,g*snz,b*snz,0,0,-1}
end
if l[i].vpz then
vl[1+#vl] = {x0,y0,z1,r*spz,g*spz,b*spz,0,0,1}
vl[1+#vl] = {x0,y1,z1,r*spz,g*spz,b*spz,0,0,1}
vl[1+#vl] = {x1,y0,z1,r*spz,g*spz,b*spz,0,0,1}
vl[1+#vl] = {x1,y0,z1,r*spz,g*spz,b*spz,0,0,1}
vl[1+#vl] = {x0,y1,z1,r*spz,g*spz,b*spz,0,0,1}
vl[1+#vl] = {x1,y1,z1,r*spz,g*spz,b*spz,0,0,1}
end
end
-- make
--local i for i=1,#vl do vl[i][7] = 0.4 end
--this.va = common.va_make(vl, nil, "3v,4c")
if client.glsl_create then
this.va = common.va_make(vl, nil, "3v,3c,3n")
else
this.va = common.va_make(vl, nil, "3v,3c")
end
-- conserve memory
vl = {}
function this.render_global(x, y, z, r1, r2, r3, s)
client.va_render_global(this.va, x, y, z, r1, r2, r3, s, this.tex)
end
function this.render_local(x, y, z, r1, r2, r3, s)
client.va_render_local(this.va, -x, y, z, r1, r2, r3, s, this.tex)
end
return this
end)
end
function model_loaders.pmf(isfile, pkt, extra)
extra = extra or {}
--print(pkt)
if isfile then pkt = common.fetch_block("pmf", pkt) end
if not pkt then return nil end
return (function(settings)
local this = {
fmt = "pmf",
filt=settings.filt or nil,
}
this.pmf = pkt
this.bone = extra.bone or 0
if this.filt then
local dname, data = common.model_bone_get(this.pmf, this.bone)
local i
for i=1,#data do
data[i].r, data[i].g, data[i].b
= this.filt(data[i].r, data[i].g, data[i].b)
end
this.pmf = common.model_new(1)
this.pmf, this.bone = common.model_bone_new(this.pmf)
common.model_bone_set(this.pmf, this.bone, dname, data)
end
function this.render_global(x, y, z, r1, r2, r3, s)
client.model_render_bone_global(this.pmf, this.bone, x, y, z, r1, r2, r3, s)
end
function this.render_local(x, y, z, r1, r2, r3, s)
client.model_render_bone_local(this.pmf, this.bone, x, y, z, r1, r2, r3, s)
end
return this
end)
end
function model_loaders.lua(isfile, pkt, extra)
extra = extra or {}
--print(pkt)
if isfile then pkt = loadfile(pkt) end
if not pkt then return nil end
--print(pkt)
return pkt
end
--[[
function loadkv6(fname, name, ptsize, ptspacing)
return parsekv6(common.bin_load(fname), name, ptsize, ptspacing)
end
]]
function loadkv6(fname, scale, filt)
print("loadkv6", fname, scale, filt)
return model_loaders.kv6(true, fname, {scale=scale})({filt=filt})
end