Entity/PhysicsInitMultiConvex

From Garry's Mod
(Difference between revisions)
Jump to: navigation, search
(i dont know what was up with the previous edits)
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
{{Func
 
{{Func
|Description=An advanced version of {{ClassFunction|Entity|PhysicsInitConvex}} which initializes a physics object from multiple convex meshes.
+
|Description=An advanced version of {{ClassFunction|Entity|PhysicsInitConvex}} which initializes a physics object from multiple convex meshes. This should be used for physics objects with a custom shape which cannot be represented by a single convex mesh.
  
This should be used for physics objects with a custom shape which cannot be represented by a single convex mesh.
+
If successful, the previous physics object will be removed.
 +
 
 +
{{Bug|Clientside physics objects are broken and do not move properly in some cases. Physics objects should only created on the server or you will experience incorrect physgun beam position, prediction issues, and other unexpected behavior.
 +
 
 +
You can use the following work-around for movement, though clientside collisions will still be broken.
 +
 
 +
<pre>
 +
function ENT:Think()
 +
if ( CLIENT ) then
 +
local physobj = self:GetPhysicsObject()
 +
 
 +
if ( IsValid( physobj ) ) then
 +
physobj:SetPos( self:GetPos() )
 +
physobj:SetAngles( self:GetAngles() )
 +
end
 +
end
 +
end
 +
</pre>
 +
}}
 
|Realm=Shared
 
|Realm=Shared
 
|IsClass=Yes
 
|IsClass=Yes
|Name=PhysicsInitMultiConvex
 
|Parent=Entity
 
 
}}
 
}}
 
{{Arg
 
{{Arg
Line 12: Line 28:
 
|name=vertices
 
|name=vertices
 
|desc=A table consisting of tables of {{Type|Vector}}s. Each sub-table defines a set of points to be used in the computation of one convex mesh.
 
|desc=A table consisting of tables of {{Type|Vector}}s. Each sub-table defines a set of points to be used in the computation of one convex mesh.
 +
}}
 +
{{Ret
 +
|type=boolean
 +
|desc=Returns true on success, nil otherwise
 
}}
 
}}
 
{{Example
 
{{Example
|Description=Creates a "box" physics mesh for the entity.
+
|Description=Creates a physics mesh for the entity which consists of two boxes.
|Code=function ENT:Initialize()
+
|Code=local min1 = Vector( -30, -10, 0 ) -- Box1 minimum corner
if ( CLIENT ) then return end -- We only want to run this code serverside
+
local max1 = Vector( -10, 10, 20 ) -- Box1 maximum corner
 
+
local x0 = -20 -- Define the min corner of the box
+
local y0 = -10
+
local z0 = -5
+
  
local x1 = 20 -- Define the max corner of the box
+
local min2 = Vector( 10, -5, 10 ) -- Box2 minimum corner
local y1 = 10
+
local max2 = Vector( 30, 5, 40 ) -- Box2 maximum corner
local z1 = 5
+
  
self:PhysicsInitMultiConvex( { {
+
if SERVER then
Vector( x1, y1, z1 ),
+
function ENT:Initialize()
Vector( x1, y0, z1 ),
+
self:SetModel( "models/props_c17/oildrum001.mdl" )
Vector( x0, y0, z1 ),
+
Vector( x0, y1, z1 ),
+
Vector( x1, y1, z1 ),
+
Vector( x0, y0, z1 ),
+
  
Vector( x0, y0, z0 ),
+
-- Initializing the multi-convex physics mesh
Vector( x1, y0, z0 ),
+
self:PhysicsInitMultiConvex( {
Vector( x0, y1, z0 ),
+
{ -- Each sub-table is a set of vertices of a convex piece, order doesn't matter
Vector( x1, y0, z0 ),
+
Vector( min1.x, min1.y, min1.z ), -- The first box vertices
Vector( x1, y1, z0 ),
+
Vector( min1.x, min1.y, max1.z ),
Vector( x0, y1, z0 ),
+
Vector( min1.x, max1.y, min1.z ),
 +
Vector( min1.x, max1.y, max1.z ),
 +
Vector( max1.x, min1.y, min1.z ),
 +
Vector( max1.x, min1.y, max1.z ),
 +
Vector( max1.x, max1.y, min1.z ),
 +
Vector( max1.x, max1.y, max1.z ),
 +
},
 +
{ -- All these tables together form a concave collision mesh
 +
Vector( min2.x, min2.y, min2.z ), -- The second box vertices
 +
Vector( min2.x, min2.y, max2.z ),
 +
Vector( min2.x, max2.y, min2.z ),
 +
Vector( min2.x, max2.y, max2.z ),
 +
Vector( max2.x, min2.y, min2.z ),
 +
Vector( max2.x, min2.y, max2.z ),
 +
Vector( max2.x, max2.y, min2.z ),
 +
Vector( max2.x, max2.y, max2.z ),
 +
},
 +
} )
  
Vector( x1, y1, z1 ),
+
self:SetSolid( SOLID_VPHYSICS ) -- Setting the solidity
Vector( x1, y1, z0 ),
+
self:SetMoveType( MOVETYPE_VPHYSICS ) -- Setting the movement type
Vector( x1, y0, z0 ),
+
Vector( x1, y0, z1 ),
+
Vector( x1, y1, z1 ),
+
Vector( x1, y0, z0 ),
+
  
Vector( x0, y0, z0 ),
+
self:EnableCustomCollisions( true ) -- Enabling the custom collision mesh
Vector( x0, y1, z0 ),
+
Vector( x0, y0, z1 ),
+
Vector( x0, y1, z0 ),
+
Vector( x0, y1, z1 ),
+
Vector( x0, y0, z1 ),
+
  
Vector( x1, y0, z1 ),
+
self:PhysWake() -- Enabling the physics motion
Vector( x1, y0, z0 ),
+
end
Vector( x0, y0, z0 ),
+
else
Vector( x0, y0, z1 ),
+
local col = Color( 0, 0, 255, 255 )
Vector( x1, y0, z1 ),
+
Vector( x0, y0, z0 ),
+
  
Vector( x0, y1, z0 ),
+
-- Drawing collision boxes on the client
Vector( x1, y1, z0 ),
+
function ENT:Draw()
Vector( x0, y1, z1 ),
+
self:DrawModel()
Vector( x1, y1, z0 ),
+
Vector( x1, y1, z1 ),
+
Vector( x0, y1, z1 )
+
} } )
+
  
-- Set up solidity and movetype
+
local pos, ang = self:GetPos(), self:GetAngles()
self:SetMoveType( MOVETYPE_VPHYSICS )
+
self:SetSolid( SOLID_VPHYSICS )
+
  
-- Enable custom collisions on the entity
+
render.DrawWireframeBox( pos, ang, min1, max1, col ) -- Drawing the first collision box
self:EnableCustomCollisions( true )
+
render.DrawWireframeBox( pos, ang, min2, max2, col ) -- Drawing the second collision box
 +
end
 
end
 
end
 +
|Output=[[File:PhysicsInitMultiConvexExample.gif]]
 
}}
 
}}

Latest revision as of 19:26, 29 July 2019

 Entity:PhysicsInitMultiConvex( )

Contents

Description

An advanced version of Entity:PhysicsInitConvex which initializes a physics object from multiple convex meshes. This should be used for physics objects with a custom shape which cannot be represented by a single convex mesh.

If successful, the previous physics object will be removed.

BUG

Clientside physics objects are broken and do not move properly in some cases. Physics objects should only created on the server or you will experience incorrect physgun beam position, prediction issues, and other unexpected behavior.

You can use the following work-around for movement, though clientside collisions will still be broken.

function ENT:Think()
	if ( CLIENT ) then
		local physobj = self:GetPhysicsObject()

		if ( IsValid( physobj ) ) then
			physobj:SetPos( self:GetPos() )
			physobj:SetAngles( self:GetAngles() )
		end
	end
end

Arguments

table vertices

A table consisting of tables of Vectors. Each sub-table defines a set of points to be used in the computation of one convex mesh.

Returns

boolean

Returns true on success, nil otherwise

Examples

Example

Creates a physics mesh for the entity which consists of two boxes.

local min1 = Vector( -30, -10, 0 ) -- Box1 minimum corner
local max1 = Vector( -10, 10, 20 ) -- Box1 maximum corner

local min2 = Vector( 10, -5, 10 ) -- Box2 minimum corner
local max2 = Vector( 30, 5, 40 ) -- Box2 maximum corner

if SERVER then
	function ENT:Initialize()
		self:SetModel( "models/props_c17/oildrum001.mdl" )

		-- Initializing the multi-convex physics mesh
		self:PhysicsInitMultiConvex( {
			{ -- Each sub-table is a set of vertices of a convex piece, order doesn't matter
				Vector( min1.x, min1.y, min1.z ), -- The first box vertices
				Vector( min1.x, min1.y, max1.z ),
				Vector( min1.x, max1.y, min1.z ),
				Vector( min1.x, max1.y, max1.z ),
				Vector( max1.x, min1.y, min1.z ),
				Vector( max1.x, min1.y, max1.z ),
				Vector( max1.x, max1.y, min1.z ),
				Vector( max1.x, max1.y, max1.z ),
			},
			{ -- All these tables together form a concave collision mesh
				Vector( min2.x, min2.y, min2.z ), -- The second box vertices
				Vector( min2.x, min2.y, max2.z ),
				Vector( min2.x, max2.y, min2.z ),
				Vector( min2.x, max2.y, max2.z ),
				Vector( max2.x, min2.y, min2.z ),
				Vector( max2.x, min2.y, max2.z ),
				Vector( max2.x, max2.y, min2.z ),
				Vector( max2.x, max2.y, max2.z ),
			},
		} )

		self:SetSolid( SOLID_VPHYSICS ) -- Setting the solidity
		self:SetMoveType( MOVETYPE_VPHYSICS ) -- Setting the movement type

		self:EnableCustomCollisions( true ) -- Enabling the custom collision mesh

		self:PhysWake() -- Enabling the physics motion
	end
else
	local col = Color( 0, 0, 255, 255 )

	-- Drawing collision boxes on the client
	function ENT:Draw()
		self:DrawModel()

		local pos, ang = self:GetPos(), self:GetAngles()

		render.DrawWireframeBox( pos, ang, min1, max1, col ) -- Drawing the first collision box
		render.DrawWireframeBox( pos, ang, min2, max2, col ) -- Drawing the second collision box
	end
end

Output:

PhysicsInitMultiConvexExample.gif
Personal tools
Navigation