Jump to content

custom collisions in Editor and LE


Chiblue
 Share

Recommended Posts

I have built some changes into the LUA scripts for collisions becuase I wanted to have more control over the collision system... this is my new class.lua

 

require("Scripts/core")
require("Scripts/filesystem")
require("Scripts/string")
require("Scripts/math/vector")
require("Scripts/constants/properties")

--Creates a class from a model reference object
function CreateClass(modelreference)
local class={}
local super={}
class.instances={}
classtable[modelreference]=class
class.modelreference=modelreference
class.name=string.lower(StripAll(modelreference.path))
classnametable[class.name]=class
--Print("Creating class "..class.name)
super.class=class
class.super=super

--Initialize the property editor dialog
function class:InitDialog(grid)
	group=grid:AddGroup( "General" )
	group:AddProperty( "Name", PROPERTY_STRING )
	group:AddProperty( "Position", PROPERTY_VEC3 )
	group:AddProperty( "Rotation", PROPERTY_VEC3)
	group:AddProperty( "Scale", PROPERTY_VEC3, "" )
	group:AddProperty( "Active", PROPERTY_BOOL )
	group:AddProperty( "Enabled", PROPERTY_BOOL )

	group=grid:AddGroup( "Appearance" )
	group:AddProperty( "Material", PROPERTY_FILE, "Material Files (*.mat):mat" )
	group:AddProperty( "Color", PROPERTY_COLOR, "1" )
	group:AddProperty( "Intensity", PROPERTY_FLOAT, "0,4,2" )
	group:AddProperty( "Order", PROPERTY_INTEGER, "0|-16,16,0" )
	group:AddProperty( "viewdistance",PROPERTY_VEC2,"","View distance" )
	group:AddProperty( "castshadows", PROPERTY_CHOICE,"Disabled,Dynamic,Static", "Cast shadows" )
	group:AddProperty( "Hidden", PROPERTY_BOOL)
	group:AddProperty( "occlusionculling", PROPERTY_BOOL, "", "Occlusion culling")	
	group:AddProperty( "aligntoground", PROPERTY_BOOL,"", "Align to terrain" )

	group=grid:AddGroup( "Physics" )
	group:AddProperty( "Mass", PROPERTY_FLOAT )
	group:AddProperty( "Friction", PROPERTY_VEC2 )
	group:AddProperty( "collisiontype", PROPERTY_CHOICE, "None,Static,Grass,Trees,Prop,Zone,Player,Friendly,Enemy,Neuetral,Trigger,Lineofsight,FriendlyFF,EnemyFF,NeutralFF", "Collision" )
	group:AddProperty( "Buoyancy", PROPERTY_BOOL )
	group:AddProperty( "Gravity", PROPERTY_BOOL )
	group:AddProperty( "sweptcollision", PROPERTY_BOOL,"","Swept collision")
end

--Remove the class from the global tables
function class:Free()
	Print("Freeing class "..self.name)
	classtable[modelreference]=nil
	classnametable[self.name]=nil
	self.super.class=nil
	self.super=nil
	self.instances=nil
end

--Create a new instance of this class
function class:CreateObject(model)
	local object={}
	local super={}
	object.model=model
	object.class=self
	objecttable[model]=object
	self.instances[model]=object
	super.object=object
	object.super=super
	object.keyslocked=0
	object.active=1
	object.enabled=1

	-------------------------------------------
	--Base object functions
	-------------------------------------------		
	function object:SetKey(key,value)
		local intensity,r,g,b,a,color,v
		if key=="color" then
			intensity=tonumber(self.model:GetKey("intensity","1.0"))
			if intensity==nil then intensity=1.0 end
			color=string.Explode(value,",")
			r=tonumber(color[1])
			g=tonumber(color[2])
			b=tonumber(color[3])
			a=tonumber(color[4])
			if r==nil then r=255 end
			if g==nil then g=255 end
			if b==nil then b=255 end
			if a==nil then a=255 end
			self.model:SetColor(Vec4(r/255.0*intensity,g/255.0*intensity,b/255.0*intensity,a/255.0),1)
		elseif key=="enabled" then
			self.enabled=tonumber(value)
		elseif key=="gravity" then
			model.usegravity=value
		elseif key=="active" then
			self.active=tonumber(value)
		elseif key=="viewdistance" then
			local t=StringToVec2(value)
			self.model:SetViewDistance(t.x,t.y,1)
		elseif key=="friction" then
			v=string.Explode(value,",")
			x=tonumber(v[1])
			y=tonumber(v[2])
			if x==nil then x=0 end
			if y==nil then y=0 end		
			self.model:SetFriction(x,y)
		elseif key=="buoyancy" then
			self.model.buoyant=tonumber(value)
		elseif key=="sweptcollision" then
			self.model:SetSweptCollisionMode(value)
		elseif key=="collisiontype" then
			if(value == 0) then newvalue = 0
			elseif(value == 1) then newvalue = 2
			elseif(value == 2) then newvalue = 3
			elseif(value == 3) then newvalue = 4
			elseif(value == 4) then newvalue = 5
			elseif(value == 5) then newvalue = 10
			elseif(value == 6) then newvalue = 20
			elseif(value == 7) then newvalue = 30
			elseif(value == 8) then newvalue = 40
			elseif(value == 9) then newvalue = 50
			elseif(value == 10) then newvalue = 6
			elseif(value == 11) then newvalue = 7
			elseif(value == 12) then newvalue = 11
			elseif(value == 13) then newvalue = 12
			else newvalue = 1;
			end
			self.model:SetCollisionType(newvalue,1)
		elseif key=="mass" then
			self.model:SetMass(tonumber(value),0)
		elseif key=="intensity" then
			intensity = tonumber(value)
			if intensity==nil then intensity=0 end
			value=self.model:GetKey("color","255,255,255,255")
			color=string.Explode(value,",")
			r=tonumber(color[1])
			g=tonumber(color[2])
			b=tonumber(color[3])
			a=tonumber(color[4])
			if r==nil then r=255 end
			if g==nil then g=255 end
			if b==nil then b=255 end
			if a==nil then a=255 end
			self.model:SetColorf(r/255.0*intensity,g/255.0*intensity,b/255.0*intensity,a/255.0,1)
		elseif key=="position" then
			v=string.Explode(value,",")
			x=tonumber(v[1])
			y=tonumber(v[2])
			z=tonumber(v[3])
			if x==nil then x=0 end
			if y==nil then y=0 end
			if z==nil then z=0 end
			self.model:Fix()
			self.model:SetPositionf( x,y,z, 0 )
			return 0
		elseif key=="occlusionculling" then
			EntityOcclusionMode(model,value,1)
		elseif key=="rotation" then
			v=string.Explode(value,",")
			x=tonumber(v[1])
			y=tonumber(v[2])
			z=tonumber(v[3])
			if x==nil then x=0 end
			if y==nil then y=0 end
			if z==nil then z=0 end
			self.model:SetRotationf( x,y,z, 0 )
			self.model:Fix()
			return 0
		elseif key=="hidden" then
			if value=="0" then
				model:Show()
			else
				model:Hide()
			end
		elseif key=="scale" then
			v=string.Explode(value,",")
			x=tonumber(v[1])
			y=tonumber(v[2])
			z=tonumber(v[3])
			if x==nil then x=1 end
			if y==nil then y=1 end
			if z==nil then z=1 end
			self.model:SetScalef( x,y,z )
			return 0
		elseif key=="material" then
			if value~="" then
				local material=LoadMaterial( "abstract::"..value )
				self.model:Paint(material,1)
			end
		elseif key=="castshadows" then
			self.model:SetShadowMode(tonumber(value),1)
		end
		return 1			
	end

	function object:GetKey(key,value)
		local intensity,r,g,b,a
		if key=="position" then
			return self.model.position.x..","..self.model.position.y..","..self.model.position.z
		elseif key=="mass" then		
			return self.model.mass
		elseif key=="sweptcollision" then
			return self.model:GetSweptCollisionMode()
		elseif key=="rotation" then
			return self.model.rotation.x..","..self.model.rotation.y..","..self.model.rotation.z 
		elseif key=="buoyancy" then
			return self.model.buoyant
		elseif key=="scale" then
			return self.model.scale.x..","..self.model.scale.y..","..self.model.scale.z 
		elseif key=="collisiontype" then
			if(value == 0) then newvalue = 0
			elseif(self.model.value == 1) then newvalue = 2
			elseif(self.model.value == 2) then newvalue = 3
			elseif(self.model.value == 3) then newvalue = 4
			elseif(self.model.value == 4) then newvalue = 5
			elseif(self.model.value == 5) then newvalue = 10
			elseif(self.model.value == 6) then newvalue = 20
			elseif(self.model.value == 7) then newvalue = 30
			elseif(self.model.value == 8) then newvalue = 40
			elseif(self.model.value == 9) then newvalue = 50
			elseif(self.model.value == 10) then newvalue = 6
			elseif(self.model.value == 11) then newvalue = 7
			elseif(self.model.value == 12) then newvalue = 11
			elseif(self.model.value == 13) then newvalue = 12
			else newvalue = 1;
			end
			return newvalue
		elseif key=="gravity" then
			return model.usegravity
		elseif key=="friction" then
			return model.staticfriction..","..model.kineticfriction
		elseif key=="color" then
			intensity=tonumber(self.model:GetKey("intensity","1"))
			return (self.model.color.x*255.0/intensity)..","..(self.model.color.y*255.0/intensity)..","..(self.model.color.z*255.0/intensity)..","..(self.model.color.w*255.0)
		elseif key=="castshadows" then
			return self.model:GetShadowMode()
		elseif key=="material" then
			if self.model.material~=nil then
				return self.model.material:GetName()
			end
		elseif key=="active" then
			if self.active==0 then return 0 else return 1 end
		elseif key=="enabled" then
			if self.enabled==0 then return 0 else return 1 end
		else
			return value
		end			
	end

	function object:LockKeys()
		self.keyslocked=1
	end

	function object:UnlockKeys()
		self.keyslocked=0
	end

	function object:ReceiveMessage(message,extra)
		if message=="hide" then
			self.model:Hide()
		elseif message=="show" then
			self.model:Show()
		elseif message=="activate" then
			self.active=1
			self.model:Show()
		elseif message=="deactivate" then
			self.active=0
		end
	end

	function object:Free()
		self.class.instances[self.model]=nil
		self.class=nil
		objecttable[self.model]=nil
		self.super.object=nil
		self.super=nil
		self.model=nil
	end

	-------------------------------------------		
	--Hack so we can call self.super:function()
	-------------------------------------------
	object.SetKey_=object.SetKey
	object.GetKey_=object.GetKey
	object.LockKeys_=object.LockKeys
	object.UnlockKeys_=object.UnlockKeys
	object.ReceiveMessage_=object.ReceiveMessage
	object.Free_=object.Free

	function super:SetKey(key,value)
		return self.object:SetKey_(key,value)
	end

	function super:GetKey(key,value)
		return self.object:GetKey_(key,value)
	end

	function super:LockKeys()
		self.object:LockKeys_()
	end

	function super:UnlockKeys()
		self.object:UnlockKeys_()
	end

	function super:ReceiveMessage()
		self.object:ReceiveMessage_()
	end

	function super:Free()
		self.object:Free_()
	end
	-------------------------------------------

	--Set any default keys here.
	--You want to set them after the SetKey function is declared.
	object.model:SetKey("intensity","1.0")

	return object
end

-------------------------------------------	
--Hack so we can call self.super:function()
-------------------------------------------
class.InitDialog_=class.InitDialog
class.Free_=class.Free
class.CreateObject_=class.CreateObject

function super:CreateObject(model)
	return self.class:CreateObject_(model)
end

function super:InitDialog(grid)
	self.class:InitDialog_(grid)
end

function super:Free()
	self.class:Free_()
end
-------------------------------------------

return class
end

 

These are my collision constants...

 

COLLISION_NONE=0
COLLISION_TERRAIN=1
COLLISION_STATIC=2
COLLISION_GRASS=3
COLLISION_TREES=4
COLLISION_PROP=5
COLLISION_ZONE=10
COLLISION_FRIENDFIELD=11
COLLISION_ENEMYFIELD=12
COLLISION_NEUTRALFIELD=13
COLLISION_PLAYERBODY=20
COLLISION_PLAYERMESH=21
COLLISION_FRIENDBODY=30
COLLISION_FRIENDMESH=31
COLLISION_ENEMYBODY=40
COLLISION_ENEMYMESH=41
COLLISION_NEUTRALBODY=50
COLLISION_NEUTRALMESH=51
COLLISION_TRIGGER=6
COLLISION_AILINEOFSIGHT=7

 

The problem is when I use any collisions in my C++ program they always have an entity type of 5555 or 55555, terrain was 55555 and my props are 5555 even though I set the collisiontype in the class script. Obviously I have done something wrong and this is my first time with LUA so I it's all trial and error... sorry in advance if the reason is really stupid... oh and I am using gamelib to load the scene...

 

thanks and sorry again if i am being stupid...

If it's not Tactical realism then you are just playing..

Link to comment
Share on other sites

A CHOICE_EDIT selection for the collisiontype returns the index number selection of the pulldown list. So your collision constants should be numerically from 0 to 19. The numbering should match the order that the collisiontypes are listed inside the Choice_Edit, with 0 = None and NeutralFF = 19. (Well, depends... you only have 15 items listed in the InitDialog() but have 19 listed in your collision constant file...)

 

Also, I see no reason at all why the standard SetKey() that comes with the normal class.lua should have been changed at all. These lines should still work:

elseif key=="collisiontype" then
self.model:SetCollisionType(value,1)

 

but you will probably need to set the Collisions() relationships up inside C++ to get these new ones to react the way you want them to react. Note that the collision_const.lua file is for just relating the naming of the collisiontypes (like COLLISION_CHARACTER) to a number that a game script's SetCollisionType() would recognize. And for a lua gamescript, you would need to also edit the start/collisions.lua file for these new collision relationships.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

I understand the relationship of collision type with index in the pull down, that is why I built the if so that when I select a collision type I translate the index to the collision type I want. I have a setup the lua collision script to assign te apprioriate collisions because if I constants in my program for the entity type it al works, if I use the collision types from the scene it does not. I believe you are correct that the set and get for the value is my problem but I do not have 19 types but I have grouped them into divisions of 10 for each "class" ie. Player entities are 20-29, enemy are 30-39 although I currently only use 20 and 21.

 

Due to the index I have to translate this index to my true collision type.

If it's not Tactical realism then you are just playing..

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...