primitive compat

This commit is contained in:
shadowscion 2022-05-20 13:21:13 -05:00
parent 68c1e48554
commit 870bbb0e59
2 changed files with 203 additions and 87 deletions

View File

@ -32,61 +32,6 @@ function prop2mesh.getBodygroupMask(ent)
return mask
end
function prop2mesh.triangulate(vertices, indices, uv)
uv = uv or (2 / 48) --math.max(1, math.floor(math.abs(uv or 48)))
local tris = {}
for k, face in ipairs(indices) do
local t1 = face[1]
local t2 = face[2]
for j = 3, #face do
local t3 = face[j]
local v1, v2, v3 = vertices[t1], vertices[t3], vertices[t2]
local normal = (v3 - v1):Cross(v2 - v1)
normal:Normalize()
v1 = {pos = v1, normal = normal}
v2 = {pos = v2, normal = normal}
v3 = {pos = v3, normal = normal}
local nx, ny, nz = math.abs(normal.x), math.abs(normal.y), math.abs(normal.z)
if nx > ny and nx > nz then
local nw = normal.x < 0 and -1 or 1
v1.u = v1.pos.z*nw*uv
v1.v = v1.pos.y*uv
v2.u = v2.pos.z*nw*uv
v2.v = v2.pos.y*uv
v3.u = v3.pos.z*nw*uv
v3.v = v3.pos.y*uv
elseif ny > nz then
local nw = normal.y < 0 and -1 or 1
v1.u = v1.pos.x*uv
v1.v = v1.pos.z*nw*uv
v2.u = v2.pos.x*uv
v2.v = v2.pos.z*nw*uv
v3.u = v3.pos.x*uv
v3.v = v3.pos.z*nw*uv
else
local nw = normal.z < 0 and 1 or -1
v1.u = v1.pos.x*nw*uv
v1.v = v1.pos.y*uv
v2.u = v2.pos.x*nw*uv
v2.v = v2.pos.y*uv
v3.u = v3.pos.x*nw*uv
v3.v = v3.pos.y*uv
end
tris[#tris + 1] = v1
tris[#tris + 1] = v2
tris[#tris + 1] = v3
t2 = t3
end
end
return tris
end
--[[

View File

@ -1,37 +1,5 @@
----------------------------------------------------------------
local math = math
local pi = math.pi
local tau = math.pi*2
local Vector = Vector
local function map(x, in_min, in_max, out_min, out_max)
return (x - in_min)*(out_max - out_min)/(in_max - in_min) + out_min
end
--[[
local name = "generic"
shapes[name] = function(vars, nophys)
local vertex, index, phys
--local dx = (vars.dx or 1)*0.5
--local dy = (vars.dy or 1)*0.5
--local dz = (vars.dz or 1)*0.5
if CLIENT then
end
if not nophys then
end
return {vertex = vertex, index = index, phys = {phys}}
end
]]
----------------------------------------------------------------
prop2mesh.primitive = {}
@ -108,6 +76,96 @@ end
addon.primitive_triangulate = primitive_triangulate
----------------------------------------------------------------
local math = math
local pi = math.pi
local tau = math.pi*2
local Vector = Vector
local function map(x, in_min, in_max, out_min, out_max)
return (x - in_min)*(out_max - out_min)/(in_max - in_min) + out_min
end
local function primitive_triangulate(vertices, indices)
local uv = 1/48
local tris = {}
for k, face in ipairs(indices) do
local t1 = face[1]
local t2 = face[2]
for j = 3, #face do
local t3 = face[j]
local v1, v2, v3 = vertices[t1], vertices[t3], vertices[t2]
local normal = (v3 - v1):Cross(v2 - v1)
normal:Normalize()
v1 = {pos = v1, normal = normal}
v2 = {pos = v2, normal = normal}
v3 = {pos = v3, normal = normal}
local nx, ny, nz = math.abs(normal.x), math.abs(normal.y), math.abs(normal.z)
if nx > ny and nx > nz then
local nw = normal.x < 0 and -1 or 1
v1.u = v1.pos.z*nw*uv
v1.v = v1.pos.y*uv
v2.u = v2.pos.z*nw*uv
v2.v = v2.pos.y*uv
v3.u = v3.pos.z*nw*uv
v3.v = v3.pos.y*uv
elseif ny > nz then
local nw = normal.y < 0 and -1 or 1
v1.u = v1.pos.x*uv
v1.v = v1.pos.z*nw*uv
v2.u = v2.pos.x*uv
v2.v = v2.pos.z*nw*uv
v3.u = v3.pos.x*uv
v3.v = v3.pos.z*nw*uv
else
local nw = normal.z < 0 and 1 or -1
v1.u = v1.pos.x*nw*uv
v1.v = v1.pos.y*uv
v2.u = v2.pos.x*nw*uv
v2.v = v2.pos.y*uv
v3.u = v3.pos.x*nw*uv
v3.v = v3.pos.y*uv
end
tris[#tris + 1] = v1
tris[#tris + 1] = v2
tris[#tris + 1] = v3
t2 = t3
end
end
return tris
end
addon.primitive_triangulate = primitive_triangulate
----------------------------------------------------------------
--[[
local name = "generic"
shapes[name] = function(vars, nophys)
local vertex, index, phys
--local dx = (vars.dx or 1)*0.5
--local dy = (vars.dy or 1)*0.5
--local dz = (vars.dz or 1)*0.5
if CLIENT then
end
if not nophys then
end
return {vertex = vertex, index = index, phys = {phys}}
end
]]
----------------------------------------------------------------
local name = "cube"
shapes[name] = function(vars, nophys)
@ -740,3 +798,116 @@ shapes[name] = function(vars, nophys)
vars.isdome = true
return shapes["sphere"](vars, nophys)
end
----------------------------------------------------------------
local name = "cube_tube"
shapes[name] = function(vars, nophys)
local vertex, index, phys
local dx = (vars.dx or 1)*0.5
local dy = (vars.dy or 1)*0.5
local dz = (vars.dz or 1)*0.5
local dt = math.min(vars.dt or 1, dx, dy)
if dt == dx or dt == dy then
return shapes["cube"](vars, nophys)
end
local numseg = vars.numseg or 4
if numseg > 4 then numseg = 4 elseif numseg < 1 then numseg = 1 end
local numring = 4*math.Round((vars.numring or 32)/4)
if numring < 4 then numring = 4 elseif numring > 32 then numring = 32 end
local cube_angle = Angle(0, 90, 0)
local cube_corner0 = Vector(1, 0, 0)
local cube_corner1 = Vector(1, 1, 0)
local cube_corner2 = Vector(0, 1, 0)
local ring_steps0 = numring/4
local ring_steps1 = numring/2
local capped = numseg ~= 4
if CLIENT then
index = capped and {{8, 7, 1, 4}} or {}
end
vertex = {}
if not nophys then
phys = {}
end
for i = 0, numseg - 1 do
cube_corner0:Rotate(cube_angle)
cube_corner1:Rotate(cube_angle)
cube_corner2:Rotate(cube_angle)
local part
if not nophys then part = {} end
vertex[#vertex + 1] = Vector(cube_corner0.x*dx, cube_corner0.y*dy, -dz)
vertex[#vertex + 1] = Vector(cube_corner1.x*dx, cube_corner1.y*dy, -dz)
vertex[#vertex + 1] = Vector(cube_corner2.x*dx, cube_corner2.y*dy, -dz)
vertex[#vertex + 1] = Vector(cube_corner0.x*dx, cube_corner0.y*dy, dz)
vertex[#vertex + 1] = Vector(cube_corner1.x*dx, cube_corner1.y*dy, dz)
vertex[#vertex + 1] = Vector(cube_corner2.x*dx, cube_corner2.y*dy, dz)
local count_end0 = #vertex
if CLIENT then
index[#index + 1] = {count_end0 - 5, count_end0 - 4, count_end0 - 1, count_end0 - 2}
index[#index + 1] = {count_end0 - 4, count_end0 - 3, count_end0 - 0, count_end0 - 1}
end
local ring_angle = -i*90
for j = 0, ring_steps0 do
local a = math.rad((j/numring)* -360 + ring_angle)
vertex[#vertex + 1] = Vector(math.sin(a)*(dx - dt), math.cos(a)*(dy - dt), -dz)
vertex[#vertex + 1] = Vector(math.sin(a)*(dx - dt), math.cos(a)*(dy - dt), dz)
end
local count_end1 = #vertex
if not nophys then
phys[#phys + 1] = {
vertex[count_end0 - 0],
vertex[count_end0 - 3],
vertex[count_end0 - 4],
vertex[count_end0 - 1],
vertex[count_end1 - 0],
vertex[count_end1 - 1],
vertex[count_end1 - ring_steps1*0.5],
vertex[count_end1 - ring_steps1*0.5 - 1],
}
phys[#phys + 1] = {
vertex[count_end0 - 2],
vertex[count_end0 - 5],
vertex[count_end0 - 4],
vertex[count_end0 - 1],
vertex[count_end1 - ring_steps1],
vertex[count_end1 - ring_steps1 - 1],
vertex[count_end1 - ring_steps1*0.5],
vertex[count_end1 - ring_steps1*0.5 - 1],
}
end
if CLIENT then
index[#index + 1] = {count_end0 - 1, count_end0 - 0, count_end1 - 0}
index[#index + 1] = {count_end0 - 1, count_end1 - ring_steps1, count_end0 - 2}
index[#index + 1] = {count_end0 - 4, count_end1 - 1, count_end0 - 3}
index[#index + 1] = {count_end0 - 4, count_end0 - 5, count_end1 - ring_steps1 - 1}
for j = 0, ring_steps0 - 1 do
local count_end2 = count_end1 - j*2
index[#index + 1] = {count_end0 - 1, count_end2, count_end2 - 2}
index[#index + 1] = {count_end0 - 4, count_end2 - 3, count_end2 - 1}
index[#index + 1] = {count_end2, count_end2 - 1, count_end2 - 3, count_end2 - 2}
end
if capped and i == numseg - 1 then
index[#index + 1] = {count_end0, count_end0 - 3, count_end1 - 1, count_end1}
end
end
end
return {vertex = vertex, index = index, phys = phys}
end