|
| 1 | +local shared = include("shared.lua") |
| 2 | + |
| 3 | +ENT.DefaultMaterial = Material("models/wireframe") |
| 4 | +ENT.Material = ENT.DefaultMaterial |
| 5 | + |
| 6 | +local Ent_IsValid = FindMetaTable("Entity").IsValid |
| 7 | +local Phys_IsValid = FindMetaTable("PhysObj").IsValid |
| 8 | +local Ent_GetTable = FindMetaTable("Entity").GetTable |
| 9 | + |
| 10 | +function ENT:Initialize() |
| 11 | + self.rendermesh = Mesh(self.Material) |
| 12 | + self.meshapplied = false |
| 13 | + self:DrawShadow(false) |
| 14 | + self:EnableCustomCollisions(true) |
| 15 | +end |
| 16 | + |
| 17 | +function ENT:OnRemove() |
| 18 | + if self.rendermesh then |
| 19 | + self.rendermesh:Destroy() |
| 20 | + self.rendermesh = nil |
| 21 | + end |
| 22 | +end |
| 23 | + |
| 24 | +function ENT:BuildPhysics(ent_tbl, physmesh) |
| 25 | + ent_tbl.physmesh = physmesh |
| 26 | + self:PhysicsInitMultiConvex(physmesh) |
| 27 | + self:SetMoveType(MOVETYPE_VPHYSICS) |
| 28 | + self:SetSolid(SOLID_VPHYSICS) |
| 29 | + self:EnableCustomCollisions(true) |
| 30 | + |
| 31 | + local phys = self:GetPhysicsObject() |
| 32 | + if Phys_IsValid(phys) then |
| 33 | + phys:SetMaterial(ent_tbl.GetPhysMaterial(self)) |
| 34 | + end |
| 35 | +end |
| 36 | + |
| 37 | +function ENT:BuildRenderMesh(ent_tbl) |
| 38 | + local phys = self:GetPhysicsObject() |
| 39 | + if not Phys_IsValid(phys) then return end |
| 40 | + |
| 41 | + local convexes = phys:GetMeshConvexes() |
| 42 | + local rendermesh = convexes[1] |
| 43 | + for i=2, #convexes do |
| 44 | + for k, v in ipairs(convexes[i]) do |
| 45 | + rendermesh[#rendermesh+1] = v |
| 46 | + end |
| 47 | + end |
| 48 | + |
| 49 | + -- less than 3 can crash |
| 50 | + if #rendermesh < 3 then return end |
| 51 | + |
| 52 | + ent_tbl.rendermesh:BuildFromTriangles(rendermesh) |
| 53 | +end |
| 54 | + |
| 55 | +function ENT:Think() |
| 56 | + local physobj = self:GetPhysicsObject() |
| 57 | + if Phys_IsValid(physobj) then |
| 58 | + physobj:SetPos(self:GetPos()) |
| 59 | + physobj:SetAngles(self:GetAngles()) |
| 60 | + physobj:EnableMotion(false) |
| 61 | + physobj:Sleep() |
| 62 | + end |
| 63 | +end |
| 64 | + |
| 65 | +function ENT:Draw(flags) |
| 66 | + self:DrawModel(flags) |
| 67 | +end |
| 68 | + |
| 69 | +function ENT:GetRenderMesh() |
| 70 | + local ent_tbl = Ent_GetTable(self) |
| 71 | + if ent_tbl.custom_mesh then |
| 72 | + if ent_tbl.custom_mesh_data[ent_tbl.custom_mesh] then |
| 73 | + return { Mesh = ent_tbl.custom_mesh, Material = ent_tbl.Material } |
| 74 | + else |
| 75 | + ent_tbl.custom_mesh = nil |
| 76 | + end |
| 77 | + else |
| 78 | + return { Mesh = ent_tbl.rendermesh, Material = ent_tbl.Material } |
| 79 | + end |
| 80 | +end |
| 81 | + |
| 82 | +local wire_customprops_hullsize_max = GetConVar("wire_customprops_hullsize_max") |
| 83 | +local quantMinX, quantMinY, quantMinZ = -wire_customprops_hullsize_max:GetFloat(), -wire_customprops_hullsize_max:GetFloat(), -wire_customprops_hullsize_max:GetFloat() |
| 84 | +local quantMaxX, quantMaxY, quantMaxZ = wire_customprops_hullsize_max:GetFloat(), wire_customprops_hullsize_max:GetFloat(), wire_customprops_hullsize_max:GetFloat() |
| 85 | +local function streamToMesh(meshdata) |
| 86 | + local meshConvexes, posMins, posMaxs = {}, Vector(math.huge, math.huge, math.huge), Vector(-math.huge, -math.huge, -math.huge) |
| 87 | + |
| 88 | + meshdata = util.Decompress(meshdata, 65536) |
| 89 | + |
| 90 | + local pos = 1 |
| 91 | + local nConvexes |
| 92 | + nConvexes, pos = shared.readInt16(meshdata, pos) |
| 93 | + for iConvex = 1, nConvexes do |
| 94 | + local nVertices |
| 95 | + nVertices, pos = shared.readInt16(meshdata, pos) |
| 96 | + local convex = {} |
| 97 | + for iVertex = 1, nVertices do |
| 98 | + local x, y, z |
| 99 | + x, pos = shared.readQuantizedFloat16(meshdata, pos, quantMinX, quantMaxX) |
| 100 | + y, pos = shared.readQuantizedFloat16(meshdata, pos, quantMinY, quantMaxY) |
| 101 | + z, pos = shared.readQuantizedFloat16(meshdata, pos, quantMinZ, quantMaxZ) |
| 102 | + if x > posMaxs.x then posMaxs.x = x end |
| 103 | + if y > posMaxs.y then posMaxs.y = y end |
| 104 | + if z > posMaxs.z then posMaxs.z = z end |
| 105 | + if x < posMins.x then posMins.x = x end |
| 106 | + if y < posMins.y then posMins.y = y end |
| 107 | + if z < posMins.z then posMins.z = z end |
| 108 | + convex[iVertex] = Vector(x, y, z) |
| 109 | + end |
| 110 | + meshConvexes[iConvex] = convex |
| 111 | + end |
| 112 | + |
| 113 | + return meshConvexes, posMins, posMaxs |
| 114 | +end |
| 115 | + |
| 116 | +net.Receive(shared.classname, function() |
| 117 | + local receivedEntity, receivedData |
| 118 | + |
| 119 | + local function tryApplyData() |
| 120 | + if not receivedEntity or not receivedData then return end |
| 121 | + |
| 122 | + if Ent_IsValid(receivedEntity) and receivedEntity:GetClass()~=shared.classname then return end |
| 123 | + local ent_tbl = Ent_GetTable(receivedEntity) |
| 124 | + if not (ent_tbl and ent_tbl.rendermesh:IsValid() and receivedData and not ent_tbl.meshapplied) then return end |
| 125 | + |
| 126 | + ent_tbl.meshapplied = true |
| 127 | + |
| 128 | + local physmesh, mins, maxs = streamToMesh(receivedData) |
| 129 | + ent_tbl.BuildPhysics(receivedEntity, ent_tbl, physmesh) |
| 130 | + ent_tbl.BuildRenderMesh(receivedEntity, ent_tbl) |
| 131 | + receivedEntity:SetRenderBounds(mins, maxs) |
| 132 | + receivedEntity:SetCollisionBounds(mins, maxs) |
| 133 | + end |
| 134 | + |
| 135 | + shared.readReliableEntity(function(self) |
| 136 | + receivedEntity = self |
| 137 | + tryApplyData() |
| 138 | + end) |
| 139 | + |
| 140 | + net.ReadStream(nil, function(data) |
| 141 | + receivedData = data |
| 142 | + tryApplyData() |
| 143 | + end) |
| 144 | +end) |
| 145 | + |
| 146 | +hook.Add("NetworkEntityCreated", shared.classname.."physics", function(ent) |
| 147 | + local ent_tbl = Ent_GetTable(ent) |
| 148 | + local mesh = ent_tbl.physmesh |
| 149 | + if mesh and not Phys_IsValid(ent:GetPhysicsObject()) then |
| 150 | + ent_tbl.BuildPhysics(ent, ent_tbl, mesh) |
| 151 | + end |
| 152 | +end) |
| 153 | + |
| 154 | +function ENT:OnPhysMaterialChanged(name, old, new) |
| 155 | + local phys = self:GetPhysicsObject() |
| 156 | + if Phys_IsValid(phys) then |
| 157 | + phys:SetMaterial(new) |
| 158 | + end |
| 159 | +end |
0 commit comments