Jump to content

Physic Performance


Gilmer
 Share

Recommended Posts

Hi peoples. I'm having a big problem with the performace, and dont know to solve.

 

I created a model of a grid. I wanna it have reaction with the physics if the car collide with it, or bursts. So far so good, I used there rope system, and convert to Lua in the model.

 

The Problem, this is a scene to race game, have a lot models like it in the road. So when begin the scene, the FPS start extremely low.

 

Cause at the start, the physics begins working in ever models.

 

Have someway to begins with some model physics, stoped? And begins to work, just when the camera is near?

 

Or some other way, to could optmize the performance of model physics reaction?

 

Below, is the code that I'm using. Just to be clear, inside model, have some bones: "bones1","bones2"....until the 14, that is parented to physics nodes.

 

require("scripts/class")
require("Scripts/constants/collision_const")
local class=CreateClass(...)

function class:InitDialog(grid)
self.super:InitDialog(grid)
group=grid:AddGroup("Configuration")
group:AddProperty("Thikness",PROPERTY_FLOAT,"0,1,2")
group:AddProperty("Nodes",PROPERTY_FLOAT,"1,7,0.05")
group:AddProperty("Attached",PROPERTY_CHOICE,"0,1","Attached")
group:Expand(1)
end


function class:CreateObject(model)
local object=self.super:CreateObject(model)


-- Ini sets
local Nodesq
local Thikness
local Attached


-- Local variables
local FPLoop
local nxrnd
local Could
local startBody
local endBody
local lenght
local BodyNodes={2}
BodyNodes[0]={Nodesq}
BodyNodes[1]={Nodesq}
BodyNodes[2]={Nodesq}

local firstJoint={}
local lastJoint={}
local nodePos={}
local nodeJoint={}

local pivot1
local pivot2
local pivot3
local pivot4
local pivot5
local pivot6
local pivot7
local pivot8
local pivot9

local bones1
local bones2
local bones3
local bones4
local bones5
local bones6
local bones7
local bones8
local bones9
local bones10
local bones11
local bones12
local bones13
local bones14

-- Estacas
local estaca1
local estaca1pos
local estaca2
local estaca2pos
local estacaJoint={}
local estaca1Mesh
local estaca2Mesh
local startPoint={}
local endPoint={}
local Pivo1Joint={}
local Pivo2Joint={}
local lastBodyNodes={}
local PivotStart = {}
local PivotEnd = {}
local SelfPivot
local SelfPivot2

function object:UpdateModel()
	-- Ini sets
	object.model:SetKey("Thikness","0.05")
	object.model:SetKey("Nodes","7")
	object.model:SetKey("Attached","1")
	Nodesq = tonumber(object.model:GetKey("Nodes"))

	--self:Clear()

	Nodesq = tonumber(object.model:GetKey("Nodes"))
	Thikness = tonumber(object.model:GetKey("Thikness"))
	Attached = tonumber(object.model:GetKey("Attached"))


	-- Local variables
	FPLoop = 0
	nxrnd = 3-- math.random(5)
	Could = 0
	startBody = {}
	endBody = {}
	BodyNodes={2}
	BodyNodes[0]={Nodesq}
	BodyNodes[1]={Nodesq}
	BodyNodes[2]={Nodesq}

	firstJoint={}
	lastJoint={}
	nodePos={}
	nodeJoint={}

	pivot1 = FindChild(object.model,"pivot01")
	pivot2 = FindChild(object.model,"pivot02")
	pivot3 = FindChild(object.model,"pivot03")
	pivot4 = FindChild(object.model,"pivot04")
	pivot5 = FindChild(object.model,"pivot05")
	pivot6 = FindChild(object.model,"pivot06")
	pivot7 = FindChild(object.model,"pivot07")
	pivot8 = FindChild(object.model,"pivot08")
	pivot9 = FindChild(object.model,"pivot09")


	bones1 = FindChild(object.model,"Bone01")
	bones2 = FindChild(object.model,"Bone02")
	bones3 = FindChild(object.model,"Bone03")
	bones4 = FindChild(object.model,"Bone04")
	bones5 = FindChild(object.model,"Bone05")
	bones6 = FindChild(object.model,"Bone06")
	bones7 = FindChild(object.model,"Bone07")
	bones8 = FindChild(object.model,"Bone08")
	bones9 = FindChild(object.model,"Bone09")
	bones10 = FindChild(object.model,"Bone10")
	bones11 = FindChild(object.model,"Bone11")
	bones12 = FindChild(object.model,"Bone12")
	bones13 = FindChild(object.model,"Bone13")
	bones14 = FindChild(object.model,"Bone14")

	estacaJoint={}


	estaca1 = CreateBodyCylinder(0.1,(pivot3:GetPosition(1).y)-(pivot1:GetPosition(1).y))
	estaca1:SetPosition(pivot1:GetPosition(1))
	estaca1pos = (pivot1:GetPosition(1).y)-(pivot3:GetPosition(1).y)
	estaca1:Move(Vec3(0,(-estaca1pos*.5),0))
	estaca1:SetMass(0.01)

	estaca2 = CreateBodyCylinder(0.1,(pivot4:GetPosition(1).y)-(pivot2:GetPosition(1).y))
	estaca2:SetPosition(pivot2:GetPosition(1))
	estaca2pos = (pivot2:GetPosition(1).y)-(pivot4:GetPosition(1).y)
	estaca2:Move(Vec3(0,(-estaca2pos*.5),0))
	estaca2:SetMass(0.01)

	estaca1:SetDamping(0,0)
	estaca2:SetDamping(0,0)

	estaca1Mesh = LoadModel("abstract::Tales_Rede_taco.gmf")
	estaca2Mesh = LoadModel("abstract::Tales_Rede_taco.gmf")

	EntityParent(estaca1Mesh,estaca1)
	EntityParent(estaca2Mesh,estaca2)

	estaca1Mesh:SetPosition(estaca1:GetPosition(),1)
	estaca2Mesh:SetPosition(estaca2:GetPosition(),1)


	startPoint={}
	startPoint[0] = pivot1:GetPosition(1)
	startPoint[1] = pivot3:GetPosition(1)
	startPoint[2] = pivot5:GetPosition(1)
	endPoint={}
	endPoint[0] = pivot2:GetPosition(1)
	endPoint[1] = pivot4:GetPosition(1)
	endPoint[2] = pivot6:GetPosition(1)

	Pivo1Joint={}
	Pivo2Joint={}

	lastBodyNodes={}


	-- Temp, Mudar depois para os pivos do modelo


	PivotStart = {}
	PivotEnd = {}
	PivotStart[0] = CreateBodyBox(0.1,0.1,0.1)
	PivotEnd[0]  = CreateBodyBox(0.1,0.1,0.1)

	PivotStart[1] = CreateBodyBox(0.1,0.1,0.1)
	PivotEnd[1]  = CreateBodyBox(0.1,0.1,0.1)

	PivotStart[2] = CreateBodyBox(0.1,0.1,0.1)
	PivotEnd[2]  = CreateBodyBox(0.1,0.1,0.1)


	PivotStart[0]:SetPosition(startPoint[0])
	PivotEnd[0]:SetPosition(endPoint[0])
	PivotStart[1]:SetPosition(startPoint[1])
	PivotEnd[1]:SetPosition(endPoint[1])
	PivotStart[2]:SetPosition(startPoint[2])
	PivotEnd[2]:SetPosition(endPoint[2])


	for ii=0,2 do

		startBody[ii] = CreateBodyBox(0.1,0.1,0.1)
		endBody[ii]   = CreateBodyBox(0.1,0.1,0.1)
		startBody[ii]:SetPosition(startPoint[ii])
		endBody[ii]:SetPosition(endPoint[ii])

		startBody[ii]:SetMass(0.05)
		endBody[ii]:SetMass(0.05)

		lenght = (EntityDistance(startBody[ii],endBody[ii])/Nodesq)

		BodyNodes[ii][0] = CreateBodyBox(Thikness,lenght,Thikness)
		BodyNodes[ii][0]:SetMass(0.05)
		BodyNodes[ii][0]:SetPosition(startPoint[ii],1)
		BodyNodes[ii][0]:Point(endBody[ii],1)
		BodyNodes[ii][0]:Point(endBody[ii],2)
		BodyNodes[ii][0]:Point(endBody[ii],3)
		BodyNodes[ii][0]:Turn(Vec3(90,283,90))
		BodyNodes[ii][0]:Move(Vec3(0,lenght/2,0))
		BodyNodes[ii][0]:SetCollisionType(1,1)

		Collisions(1,1,1)

		Pivo1Joint[ii] = CreateJointBall(startBody[ii],PivotStart[ii],startPoint[ii],Vec3(0,0,0))
		Pivo2Joint[ii] = CreateJointBall(endBody[ii],PivotEnd[ii],endPoint[ii],Vec3(s0,0,0))


		for i=1,(Nodesq-1) do
			BodyNodes[ii][i] = CopyEntity(BodyNodes[ii][0])

			lastBodyNodes[ii] = BodyNodes[ii][i-1]:GetPosition()

			BodyNodes[ii][i]:SetPosition(lastBodyNodes[ii],1)
			BodyNodes[ii][i]:Point(endBody[ii],1)
			BodyNodes[ii][i]:Point(endBody[ii],2)
			BodyNodes[ii][i]:Point(endBody[ii],3)
			BodyNodes[ii][i]:Turn(Vec3(0,0,0))
			BodyNodes[ii][i]:Move(Vec3(0,lenght,0))
			BodyNodes[ii][i]:SetCollisionType(1,1)
			BodyNodes[ii][i]:SetDamping(0,0)

			nodePos[ii] = BodyNodes[ii][i]:GetPosition()

			nodeJoint[ii] = CreateJointBall(BodyNodes[ii][i-1],BodyNodes[ii][i],Vec3(nodePos[ii].x,nodePos[ii].y,nodePos[ii].z+(lenght/2)),Vec3(0,0,0))
			nodeJoint[ii]:SetLimits(Vec3(0,1,0),90)

		end

	end

	-- Joint das estacas
	EntityParent(bones1,BodyNodes[0][0],1)
	EntityParent(bones7,BodyNodes[0][6],1)
	EntityParent(bones8,BodyNodes[1][0],1)
	EntityParent(bones14,BodyNodes[1][6],1)



	firstJoint[0] = CreateJointBall(startBody[0], estaca1, startPoint[0],Vec3(0,0,0))
	firstJoint[1] = CreateJointBall(startBody[1], estaca1, startPoint[1],Vec3(0,0,0))
	firstJoint[2] = CreateJointBall(startBody[2], estaca1, startPoint[2],Vec3(0,0,0))

	if Attached==1 then
		lastJoint[0] = CreateJointBall(endBody[0],estaca2, endPoint[0],Vec3(0,0,0))
		lastJoint[1] = CreateJointBall(endBody[1],estaca2, endPoint[1],Vec3(0,0,0))
		lastJoint[2] = CreateJointBall(endBody[2],estaca2, endPoint[2],Vec3(0,0,0))
	end


	estacaJoint[0] = CreateJointBall(estaca1,BodyNodes[0][0], startPoint[0])
	estacaJoint[0]:SetLimits(Vec3(0,1,0),90)
	estacaJoint[1] = CreateJointBall(estaca1,BodyNodes[1][0], startPoint[1])
	estacaJoint[1]:SetLimits(Vec3(0,1,0),90)

	estacaJoint[2] = CreateJointBall(estaca2,BodyNodes[0][Nodesq-1], endPoint[0])
	estacaJoint[2]:SetLimits(Vec3(0,1,0),90)
	estacaJoint[3] = CreateJointBall(estaca2,BodyNodes[1][Nodesq-1], endPoint[1])
	estacaJoint[3]:SetLimits(Vec3(0,1,0),90)

	estacaJoint[4] = CreateJointBall(estaca1,BodyNodes[2][0], startPoint[2])
	estacaJoint[4]:SetLimits(Vec3(0,1,0),90)
	estacaJoint[5] = CreateJointBall(estaca2,BodyNodes[2][Nodesq-1], endPoint[2])
	estacaJoint[5]:SetLimits(Vec3(0,1,0),90)


end


function object:Free()
	self:Clear()
	self.super:Free()
end


function object:Update()

	bones2:SetPosition(BodyNodes[0][1]:GetPosition(1),1)
	bones3:SetPosition(BodyNodes[0][2]:GetPosition(1),1)
	bones4:SetPosition(BodyNodes[0][3]:GetPosition(1),1)		
	bones5:SetPosition(BodyNodes[0][4]:GetPosition(1),1)
	bones6:SetPosition(BodyNodes[0][5]:GetPosition(1),1)
	bones9:SetPosition(BodyNodes[1][1]:GetPosition(1),1)
	bones10:SetPosition(BodyNodes[1][2]:GetPosition(1),1)
	bones11:SetPosition(BodyNodes[1][3]:GetPosition(1),1)
	bones12:SetPosition(BodyNodes[1][4]:GetPosition(1),1)
	bones13:SetPosition(BodyNodes[1][5]:GetPosition(1),1)



	-- Distancia Nodes Centrais X
	local nx = EntityDistance(BodyNodes[2][3],BodyNodes[2][0])

	-- Distancia Nodes Centrais Y1
	local ny1 = 0
	local ny1b = 0

	if(Nodesq==nil) then
		Nodesq = tonumber(object.model:GetKey("Nodes"))
	end

	for i=0, (Nodesq-1) do
		ny1 = EntityDistance(BodyNodes[1][i],BodyNodes[0][i])
		if(ny1>2) then ny1b = 1 end
	end

	-- Distancia Nodes Centrais Y2
	local ny2 = 0
	local ny2b = 0
	for i=0, (Nodesq-1) do
		ny2 = EntityDistance(BodyNodes[2][i],BodyNodes[1][i])
		if(ny2>2) then ny2b = 1 end
	end



	if(nx>=3 or ny1b==1 or ny2b==1) then

		if(nxrnd==1) then
			FreeJoint(firstJoint[0])
			FreeJoint(firstJoint[1])
			FreeJoint(firstJoint[2])
		end

		if(nxrnd==2) then
			if Attached==1 then
				FreeJoint(lastJoint[0])
				FreeJoint(lastJoint[1])
				FreeJoint(lastJoint[2])
			end
		end

		if(nxrnd~=1 and nxrnd~=2) then
			FreeJoint(firstJoint[0])
			FreeJoint(firstJoint[1])
			FreeJoint(firstJoint[2])
			if Attached==1 then
				FreeJoint(lastJoint[0])
				FreeJoint(lastJoint[1])
				FreeJoint(lastJoint[2])
			end

		end

		object.model:SetPosition(BodyNodes[1][3]:GetPosition(1))


		FPLoop = FPLoop + 1

		if(FPLoop>300 and Could==0) then

			Could = 1

			for i=0,(Nodesq-1) do
				BodyNodes[0][i]:Free()
				BodyNodes[1][i]:Free()
				BodyNodes[2][i]:Free()
			end

			estaca1:SetCollisionType(0,0)
			estaca1:SetMass(0)
			estaca2:SetCollisionType(0,0)
			estaca2:SetMass(0)

			startBody[0]:SetCollisionType(0,0)
			startBody[0]:SetMass(0)
			startBody[1]:SetCollisionType(0,0)
			startBody[1]:SetMass(0)
			startBody[2]:SetCollisionType(0,0)
			startBody[2]:SetMass(0)
			endBody[0]:SetCollisionType(0,0)
			endBody[0]:SetMass(0)
			endBody[1]:SetCollisionType(0,0)
			endBody[1]:SetMass(0)
			endBody[2]:SetCollisionType(0,0)
			endBody[2]:SetMass(0)

			PivotStart[0]:SetCollisionType(0,0)
			PivotStart[0]:SetMass(0)
			PivotStart[1]:SetCollisionType(0,0)
			PivotStart[1]:SetMass(0)
			PivotStart[2]:SetCollisionType(0,0)
			PivotStart[2]:SetMass(0)
			PivotEnd[0]:SetCollisionType(0,0)
			PivotEnd[0]:SetMass(0)
			PivotEnd[1]:SetCollisionType(0,0)
			PivotEnd[1]:SetMass(0)
			PivotEnd[2]:SetCollisionType(0,0)
			PivotEnd[2]:SetMass(0)

			startBody[0]:Free()
			startBody[1]:Free()
			startBody[2]:Free()
			endBody[0]:Free()
			endBody[1]:Free()
			endBody[2]:Free()
			PivotStart[0]:Free()
			PivotStart[1]:Free()
			PivotStart[2]:Free()
			PivotEnd[0]:Free()
			PivotEnd[1]:Free()
			PivotEnd[2]:Free()

			pivot1:Free()
			pivot2:Free()
			pivot3:Free()
			pivot4:Free()
			pivot5:Free()
			pivot6:Free()

		end

	end

end

function object:Clear()

	Thikness	= nil
	Attached	= nil
	lenght 		= nil
	pivot1 		= nil
	pivot2 		= nil
	pivot3 		= nil
	pivot4 		= nil
	pivot5 		= nil
	pivot6 		= nil
	bones1 	= nil
	bones2 	= nil
	bones3 	= nil
	bones4 	= nil
	bones5 	= nil
	bones6 	= nil
	bones7 	= nil
	bones8 	= nil
	bones9 	= nil
	bones10 	= nil
	bones11 	= nil
	bones12 	= nil
	bones13 	= nil
	bones14 	= nil
	if(estaca1~=nil) then estaca1:Free() end
	estaca1pos 	= nil
	if(estaca2~=nil) then estaca2:Free() end
	estaca2pos 	= nil
	estaca1Mesh 	= nil
	estaca2Mesh 	= nil
	startPoint[0] 	= nil
	startPoint[1] 	= nil
	startPoint[2] 	= nil
	endPoint[0] 	= nil
	endPoint[1] 	= nil
	endPoint[2] 	= nil
	if(PivotStart[0]~=nil) then PivotStart[0]:Free() end
	if(PivotStart[1]~=nil) then PivotStart[1]:Free() end
	if(PivotStart[2]~=nil) then PivotStart[2]:Free() end
	if(PivotEnd[0]~=nil) then PivotEnd[0]:Free() end
	if(PivotEnd[1]~=nil) then PivotEnd[1]:Free() end
	if(PivotEnd[2]~=nil) then PivotEnd[2]:Free() end

	for i=0,(Nodesq-1) do
		if(BodyNodes[0][i]~=nil) then BodyNodes[0][i]:Free() end
		if(BodyNodes[1][i]~=nil) then BodyNodes[1][i]:Free() end
		if(BodyNodes[2][i]~=nil) then BodyNodes[2][i]:Free() end
	end

	Nodesq 		= nil
end



object:UpdateModel()



end

 

 

And a video in action:

Link to comment
Share on other sites

Have a loading screen which checks the FPS and when FPS is over 30, then close the loading screen.

 

A more advanced way, which needs no loading screen, would be to set first the mass of all physics object to 0, and then set the mass to 1 in regular time intervals, like every 10 second activate one gate. Since the player is not near the other gates, he wouldn't notice it either, so make sure you start to activate the gates from nearest to the player.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

The headlight parts on that car look pretty high-detail. That could be reduced a lot.

 

I guess the physics are bouncing around a bit at first until they settle. Maybe set the mass of these things to zero until a collision occurs? That way they would just be static until something actually hits them.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...