Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions lua/entities/starfall_hologram/cl_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,13 @@ function ENT:Draw(flags)
end

function ENT:GetRenderMesh()
local selfTbl = self:GetTable()
if selfTbl.custom_mesh then
if selfTbl.custom_mesh_data[selfTbl.custom_mesh] then
return { Mesh = selfTbl.custom_mesh, Material = selfTbl.Material--[[, Matrix = self.HoloMatrix]] }
local ent_tbl = self:GetTable()
local custom_mesh = ent_tbl.custom_mesh
if custom_mesh then
if custom_mesh.mesh then
return { Mesh = custom_mesh.mesh, Material = ent_tbl.Material--[[, Matrix = self.HoloMatrix]] }
else
selfTbl.custom_mesh = nil
ent_tbl.custom_mesh = nil
end
end
end
Expand Down
7 changes: 4 additions & 3 deletions lua/entities/starfall_prop/cl_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ end

function ENT:GetRenderMesh()
local ent_tbl = Ent_GetTable(self)
if ent_tbl.custom_mesh then
if ent_tbl.custom_mesh_data[ent_tbl.custom_mesh] then
return { Mesh = ent_tbl.custom_mesh, Material = ent_tbl.Material--[[, Matrix = ent_tbl.render_matrix]] }
local custom_mesh = ent_tbl.custom_mesh
if custom_mesh then
if custom_mesh.mesh then
return { Mesh = custom_mesh.mesh, Material = ent_tbl.Material--[[, Matrix = ent_tbl.render_matrix]] }
else
ent_tbl.custom_mesh = nil
end
Expand Down
1 change: 0 additions & 1 deletion lua/starfall/libs_sh/entities.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ if CLIENT then
checkpermission(instance, ent, "entities.setRenderProperty")
if mesh then
ent_tbl.custom_mesh = instance.Types.Mesh.Unwrap(mesh)
ent_tbl.custom_mesh_data = instance.data.meshes
else
ent_tbl.custom_mesh = nil
end
Expand Down
157 changes: 100 additions & 57 deletions lua/starfall/libs_sh/mesh.lua
Original file line number Diff line number Diff line change
Expand Up @@ -804,24 +804,31 @@ function mesh_library.findConvexHull(vertices, threaded)
end

if CLIENT then
local meshData = {}
instance.data.meshes = meshData

local function destroyMesh(ply, mesh)
plyTriangleCount:free(ply, meshData[mesh].ntriangles)
plyMeshCount:free(ply, 1)
mesh:Destroy()
meshData[mesh] = nil
local mesh_methods, mesh_meta, wrap, unwrap = instance.Types.Mesh.Methods, instance.Types.Mesh, instance.Types.Mesh.Wrap, instance.Types.Mesh.Unwrap

local instanceMeshes = {}

local function registerMesh(mesh, ntriangles, isskinned)
local meshdata = { ntriangles = ntriangles, mesh = mesh }
if isskinned then meshdata.matrices = {} end
instanceMeshes[meshdata] = true
Comment thread
thegrb93 marked this conversation as resolved.
return meshdata
end

local function destroyMesh(meshdata)
plyTriangleCount:free(instance.player, meshdata.ntriangles)
plyMeshCount:free(instance.player, 1)
meshdata.mesh:Destroy()
meshdata.mesh = nil
instanceMeshes[meshdata] = nil
end

instance:AddHook("deinitialize", function()
for mesh in pairs(meshData) do
destroyMesh(instance.player, mesh)
for meshdata in pairs(instanceMeshes) do
destroyMesh(meshdata)
end
end)

local mesh_methods, mesh_meta, wrap, unwrap = instance.Types.Mesh.Methods, instance.Types.Mesh, instance.Types.Mesh.Wrap, instance.Types.Mesh.Unwrap

local vertexCheck = {
color = function(v) return dgetmeta(v) == col_meta end,
normal = function(v) return dgetmeta(v) == vec_meta end,
Expand Down Expand Up @@ -877,12 +884,13 @@ if CLIENT then
end

if threaded then thread_yield(0) end
local mesh = Mesh()
mesh:BuildFromTriangles(unwrapped)
meshData[mesh] = { ntriangles = ntriangles }

plyTriangleCount:use(instance.player, ntriangles)
plyMeshCount:use(instance.player, 1)
return wrap(mesh)

local mesh = Mesh()
mesh:BuildFromTriangles(unwrapped)
return wrap(registerMesh(mesh, ntriangles, false))
end

--- Creates a mesh from an obj file. Only supports triangular meshes with normals and texture coordinates.
Expand All @@ -907,8 +915,7 @@ if CLIENT then

local mesh = Mesh()
mesh:BuildFromTriangles(vertices)
meshData[mesh] = { ntriangles = ntriangles }
meshes[name] = wrap(mesh)
meshes[name] = wrap(registerMesh(mesh, ntriangles, false))
if threaded then thread_yield() end
end
return meshes
Expand All @@ -919,12 +926,17 @@ if CLIENT then
-- @client
function mesh_library.createEmpty()
checkpermission(instance, nil, "mesh")

plyMeshCount:use(instance.player, 1)
return wrap(registerMesh(Mesh(), 0, false))
end

local mesh = Mesh()
meshData[mesh] = { ntriangles = 0 }
return wrap(mesh)
--- Creates a skinned mesh without any vertex data.
-- @return Mesh Mesh object
-- @client
function mesh_library.createEmptySkinned()
checkpermission(instance, nil, "mesh")
plyMeshCount:use(instance.player, 1)
return wrap(registerMesh(Mesh(nil, 2), 0, true))
end

local function wrapVertex(p)
Expand Down Expand Up @@ -1031,20 +1043,17 @@ if CLIENT then
if mesh_obj == nil then
if not instance.data.render.isRendering then SF.Throw("Not in rendering hook.", 2) end
plyTriangleRenderBurst:use(instance.player, tri_count)
meshgenerating = true
mesh.Begin(prim_type, prim_count)
else
mesh_obj = unwrap(mesh_obj)
local mesh_tbl = meshData[mesh_obj]
if not mesh_tbl then SF.Throw("Tried to use invalid mesh.", 2) end
local meshdata = unwrap(mesh_obj)
-- Garrysmod bug, crash if mesh isn't empty
if mesh_tbl.ntriangles ~= 0 then SF.Throw("mesh.generate requires an empty mesh to populate.", 2) end
if meshdata.ntriangles ~= 0 then SF.Throw("mesh.generate requires an empty mesh to populate.", 2) end
plyTriangleCount:use(instance.player, tri_count)
mesh_tbl.ntriangles = tri_count
meshgenerating = mesh_obj
mesh.Begin(mesh_obj, prim_type, prim_count)
meshdata.ntriangles = tri_count
mesh.Begin(meshdata.mesh, prim_type, prim_count)
end

meshgenerating = true
instance.canyield = false
local ok, err = pcall(func)
instance.canyield = true
Expand All @@ -1053,50 +1062,50 @@ if CLIENT then
if not ok then error(err) end
end

--- Sets the vertex color by RGBA values
--- Writes the vertex color by RGBA values to the vertex data
-- @name mesh_library.writeColor
-- @class function
-- @param number r Number, red value
-- @param number g Number, green value
-- @param number b Number, blue value
-- @param number a Number, alpha value
-- @client
function mesh_library.writeColor(r, g, b, a)
mesh.Color(r, g, b, a)
end
mesh_library.writeColor = mesh.Color

--- Sets the vertex normal
--- Writes the vertex normal to the vertex data
-- @param Vector normal Normal
-- @client
function mesh_library.writeNormal(normal)
mesh.Normal(vunwrap1(normal))
end

--- Sets the vertex position
--- Writes the vertex position to the vertex data
-- @param Vector position Position
-- @client
function mesh_library.writePosition(pos)
mesh.Position(vunwrap1(pos))
end

--- Sets the vertex texture coordinates
--- Writes the vertex texture coordinates to the vertex data
-- @name mesh_library.writeUV
-- @class function
-- @param number stage Stage of the texture coordinate
-- @param number u U coordinate
-- @param number v V coordinate
-- @client
function mesh_library.writeUV(stage, u, v)
mesh.TexCoord(stage, u, v)
end
mesh_library.writeUV = mesh.TexCoord

--- Sets the vertex tangent user data
--- Writes the vertex tangent user data to the vertex data
-- @name mesh_library.writeUserData
-- @class function
-- @param number x x
-- @param number y y
-- @param number z z
-- @param number handedness
-- @client
function mesh_library.writeUserData(x, y, z, handedness)
mesh.UserData(x, y, z, handedness)
end
mesh_library.writeUserData = mesh.UserData

--- Draws a quad using 4 vertices
--- Writes a quad using 4 vertices to the vertex data
-- @param Vector v1 Vertex1 position
-- @param Vector v2 Vertex2 position
-- @param Vector v3 Vertex3 position
Expand All @@ -1107,7 +1116,7 @@ if CLIENT then
mesh.Quad(vunwrap1(v1), vunwrap2(v2), vunwrap3(v3), vunwrap4(v4), col)
end

--- Draws a quad using a position, normal and size
--- Writes a quad using a position, normal and size to the vertex data
-- @param Vector position
-- @param Vector normal
-- @param number w
Expand All @@ -1118,30 +1127,64 @@ if CLIENT then
mesh.QuadEasy(vunwrap1(position), vunwrap2(normal), w, h, col)
end

--- Writes bone data to the vertex data
-- @name mesh_library.writeBoneData
-- @class function
-- @param number index The slot index for the vertex, either 0 or 1.
-- @param number matrixId The matrix index for the vertex, in the range of 1 -> 53.
-- @param number weight How much influence that matrix will have on this vertex, in the range of 0 -> 1
mesh_library.writeBoneData = mesh.BoneData

--- Pushes the vertex data onto the render stack
-- @name mesh_library.advanceVertex
-- @class function
-- @client
function mesh_library.advanceVertex()
mesh.AdvanceVertex()
end
mesh_library.advanceVertex = mesh.AdvanceVertex

--- Draws the mesh. Must be in a 3D rendering context.
-- @client
function mesh_methods:draw()
local mesh = unwrap(self)
local meshdata = meshData[mesh]
if not meshdata then SF.Throw("Tried to use invalid mesh.", 2) end
if not instance.data.render.isRendering then SF.Throw("Not in rendering hook.", 2) end
local meshdata = unwrap(self)
plyTriangleRenderBurst:use(instance.player, meshdata.ntriangles)
mesh:Draw()
if meshdata.matrices then
meshdata.mesh:DrawSkinned(meshdata.matrices)
else
meshdata.mesh:Draw()
end
end

--- Sets the number of matrices to be used for the skinned mesh.
-- @param number count The number of bone matrices to use in range 1 -> 53
-- @return table Table of reference VMatrix to each bone. Modifying them will modify the bone matrix
-- @client
function mesh_methods:setupBoneMatrices(count)
local meshdata = unwrap(self)
if not meshdata.matrices then SF.Throw("Unable to setup bones on non skinned mesh!", 2) end
count = math.Clamp(math.floor(count), 0, 53)
if #meshdata.matrices ~= count then
for i=#meshdata.matrices+1, count do
meshdata.matrices[i] = Matrix()
end
for i=count+1, 53 do
meshdata.matrices[i] = nil
end
end
local ret = {}
for i=1, #meshdata.matrices do
ret[i] = mwrap(meshdata.matrices[i])
end
return ret
end

--- Frees the mesh from memory
-- @client
function mesh_methods:destroy()
local mesh = unwrap(self)
if not meshData[mesh] then SF.Throw("Tried to use invalid mesh.", 2) end
if meshgenerating == mesh then SF.Throw("Cannot destroy mesh currently being generated.", 2) end
destroyMesh(instance.player, mesh)
if meshgenerating then SF.Throw("Cannot destroy mesh while generating!", 2) end
Comment thread
thegrb93 marked this conversation as resolved.
local meshdata = unwrap(self)
destroyMesh(meshdata)
mesh_meta.sf2sensitive[self] = nil
mesh_meta.sensitive2sf[meshdata] = nil
end
end

Expand Down
Loading