irrlicht camerascenenode problem

BlitzMax Forums/BlitzMax Programming/irrlicht camerascenenode problem

AntonyWells(Posted 2005) [#1]
I've wrote a wrapper for Irrlict to make it more user friendly, but in emulating b3d's move function it appears to not work on a camerascene node. it works perfectly on a regular mesh(Try it on the cube in the example code at the bottom)
When I translate the camera scene node, it works for a bit then warps as if the matrix is being screwed up.

Any idea why? Gman?

Strict
Const d_opengl=1,d_directx9=2,d_best=3
Type Gfx
	Function Graphics3D:gfx(Width,height,driver=d_opengl)
		Local out:gfx = New gfx
		Local drivertype
		Select driver
			Case d_opengl
				drivertype =EDT_OPENGL
			Case d_directx9
				?mac
				drivertype = EDT_OPENGL
				?win
				drivertype = EDT_DIRECTX9
				?
		End Select
		gfx.device:T_irrIrrlichtDevice=t_irrIrrlichtDevice.create(drivertype,T_irrDimension2d_s32.create(width,height))
		gfx.video =gfx.device.getVideoDriver()
		gfx.scene = gfx.device.getSceneManager()
		gfx.gui = gfx.device.getGuiEnvironment()
		If gfx.video = Null
			Throw "Video Driver not found."
		End If
		If gfx.scene = Null
			Throw "Scene Manager not found."
		End If 
		If gfx.gui = Null
			Throw "Gui driver not found."
		End If
		
		Return out
		
	End Function
	Function Cls()
		gfx.video.beginscene(True,True, T_irrSColor.createFromVals(255,0,0,0) )
	End Function
	Function Flip()
		gfx.video.endScene()
	End Function
	Function RenderWorld()
		gfx.scene.drawall()
	End Function
	
	Global device:T_irrIrrlichtDevice
	Global video:T_irrIVideoDriver
	Global Scene:t_irrISceneManager
	Global gui:t_irrIGuiEnvironment
	
End Type

Type Entity
	Field node:T_irrISceneNode
	Field tmp:Matrix
	Function CreateFromNode:Entity(node:T_irrISceneNode)
		Local out:Entity = New entity
		out.node = node
		Return out
	End Function
	Method New()
		tmp=matrix.create()
	End Method
	
	Method Position(x#,y#,z#,globalspace=False)
		node.setposition( t_irrVector3df.createFromVals(x,y,z) )
	End Method
	Method Move(x#,y#,z#)
		maths.tformpoint(x,y,z,Self)
		node.setposition( T_IrrVector3df.createfromVals( maths.tformx,maths.tformy,maths.tformz ) )
	End Method
	
	Method WorldMatrix:Matrix()
		Local mat:Matrix = New matrix
		mat.mat = node.getabsoluteTransformation()
		Return mat		
	End Method
	
	Method Rotate(pitch#,yaw#,roll#,globalspace=False)
		node.setrotation( t_irrVector3df.createFromVals(pitch,yaw,roll) )
	End Method
	Method SetTexture(index,tex:texture)
		node.setmaterialtexture(index,tex.tex)
	End Method
	
End Type


Type Camera Extends Entity
	Field cnode:T_irrICameraSceneNode
	Function Create:camera(parent:Entity=Null)
		Local out:Camera = New camera
		Local pnode:t_irrISceneNode
		If parent<>Null
			pnode = parent.node
		End If
		If pnode<>Null
			out.cnode = gfx.scene.AddcameraSceneNode(pnode)
		Else
			out.cnode =gfx.scene.addCameraSceneNode()
		End If
		out.node = T_IrrISceneNode(out.cnode)
		Return out
	End Function
End Type

Type Matrix
	Field mat:t_irrMatrix4
	Field rot:t_irrVector3df
	Field pos:T_irrVector3df
	Function Create:Matrix()
		Local out:matrix = New matrix
		out.mat = t_irrMatrix4.create()
		Return out
	End Function
	Method Identity()
		mat.makeidentity()
	End Method
	Method Rotate(pitch#,yaw#,roll#)
		mat.setRotationDegrees( T_irrVector3df.createfromvals(pitch,yaw,roll) )
	End Method
	Method GetRotate()
		mat.getrotationDegrees()
	End Method
	Method Pitch#()
		Return rot.getX()
	End Method
	Method Yaw#()
		Return rot.getY()
	End Method
	Method Roll#()
		Return rot.getZ()
	End Method
	Method Position(x#,y#,z#)
		mat.settranslation( t_irrVector3df.createfromvals( x,y,z) )
	End Method
	Method GetPosition()
		pos=mat.gettranslation()
	End Method
	Method X#()	
		Return pos.getX()
	End Method
	Method Y#()
		Return pos.GetY()
	End Method
	Method Z#()
		Return pos.getZ()
	End Method
	Method MultiplyNew:Matrix(with:Matrix)
		Local out:Matrix = New matrix
		out.mat = mat.Mult(with.mat)
		Return out
	End Method
	Method Multiply(with:matrix)
		mat.multeq(with.mat)
	End Method
	Method LookAt(fx#,fy#,fz#,x#,y#,z#)
		mat.buildcameralookatMatrixLH( T_irrVector3df.createfromvals(fx,fy,fz),t_irrVector3df.createfromvals(x,y,z),t_irrvector3df.createfromvals(0,-1,0) )
	End Method
	Method TformPoint(x#,y#,z#)
		Local vec:T_IrrVector3df = t_irrvector3df.createfromvals(x,y,z)
		mat.transformvect( vec )
		tformx = vec.getx()
		tformy = vec.gety()
		tformz = vec.getz()
	End Method
	
	Method TFormVector(x#,y#,z#)
		Local vec:T_IrrVector3df = t_irrvector3df.createfromvals(x,y,z)
		mat.rotatevect( vec )
		tformx = vec.getx()
		tformy = vec.gety()
		tformz = vec.getz()
	End Method
	
	Field tformx#,tformy#,tformz#
				
End Type

Type Maths
	Function TFormPoint( x#,y#,z#,ent:Entity )
		Local mt:Matrix = ent.WorldMatrix()
		mt.TformPoint( x,y,z )
		tformx=mt.tformx
		tformy=mt.tformy
		tformz=mt.tformz
	End Function
	Function TFormVector( x#,y#,z#,ent:Entity )
		Local mt:Matrix = ent.worldMatrix()
		mt.tformVector( x,y,z )
		tformx = mt.tformx
		tformy = mt.tformy
		tformz = mt.tformz
	End Function
	Function TFormedX#()
		Return tformx
	End Function
	Function TFormedY#()
		Return tformy
	End Function
	Function TFormedZ#()
		Return tformz
	End Function
	Global TformX#,tformy#,tformz#
End Type




Type Prefab
	Function Cube:Entity(size:Float,parent:Entity = Null)
		Local node:T_IrrISceneNode
		Local pnode:T_IrrISceneNode
		If parent<>Null
			pnode = parent.node
		End If
		If pnode<>Null
		node = gfx.scene.addtestSceneNode(size,pnode)
		Else
		node = gfx.scene.addTestSceneNode(Size)
		End If
		Local out:Entity = entity.createfromnode(node)
			
		Return out
	End Function
	
End Type

Type Texture
	Field tex:t_irrITexture
	Function Load:Texture(file:String)
		Local out:texture = New texture
		out.tex = gfx.video.gettexture(file)
		Return out
	End Function
End Type




Local g:gfx = gfx.graphics3d(640,480)

Local cube:Entity = prefab.cube(10)
Local cam:Camera = camera.create()
cam.position(0,0,-20)
Local tex:Texture = texture.load("media/wall.bmp")
cube.settexture(0,tex)


Repeat
	If KeyDown(KEY_A)
		cam.move(-1,0,0)
	End If
	If KeyDown(KEY_D)
		cam.move(1,0,0)
	End If 
	If KeyDown(KEY_W)
		cam.move(0,0,-1)
		End If
		If KeyDown(KEY_S)
		cam.move(0,0,1)
	End If
	gfx.cls()
	gfx.renderWorld()
	gfx.flip()
Until KeyDown(KEY_ESCAPE)





Haramanai(Posted 2005) [#2]
http://www.blitzmax.com/Community/posts.php?topic=51767


AntonyWells(Posted 2005) [#3]
Thanks, found that and it worked.

Another problem now though. I created a version of b3d's turn, which works fine, but when I go to zero the roll by getting the rotation after the turn and passing zero to roll, it locks when turning on the yaw axis.

tmp.EntityRotation( Self ) ; set matrix to match entity rotation
		Local mt:Matrix = matrix.create()
		Local vt:Matrix = matrix.create()
		vt.identity()
		tmp.multiply(vt)
		mt.rotate(pitch Mod 360.0,yaw Mod 360.0,roll Mod 360.0) 'set matrix to match turn pars
		mt = mt.multiplynew( tmp ) 'multiply current and turn pars together
		mt.Getrotate()
		mt.rotate( mt.pitch(),mt.yaw(),0 ) 'Zero roll <-Causes lock
		mt.getRotate()
		rotate( mt.pitch() Mod 360.0,mt.yaw() Mod 360.0,mt.roll() Mod 360.0 )




Haramanai(Posted 2005) [#4]
Maybe Gimbal Lock.
I cannot help you with your code. But when I need something like turn I am writing something like this:

Function Turn(LNode:T_irrISceneNode , TurnX# , TurnY# , TurnZ#)
	Local Turn:T_irrVector3df = T_irrVector3df.createFromVals(TurnX , TurnY , TurnZ)
	LNode.setRotation(LNode.getRotation().Plus(Turn) )
End Function



edit:
or with out the local

Function Turn(LNode:T_irrISceneNode , TurnX# , TurnY# , TurnZ#)
	LNode.setRotation(LNode.getRotation().Plus(T_irrVector3df.createFromVals(TurnX , TurnY , TurnZ)) )
End Function



AntonyWells(Posted 2005) [#5]
Thanks again, worked great.


Amon(Posted 2005) [#6]
Hey Ant, How far along have you come with this? Can I begin any sort of game with it?


AntonyWells(Posted 2005) [#7]
Not quite but it's not bad to get things started.

Strict
Const d_opengl=1,d_directx9=2,d_best=3
Type Gfx
	Function Graphics3D:gfx(Width,height,driver=d_opengl)
		Local out:gfx = New gfx
		Local drivertype
		Select driver
			Case d_opengl
				drivertype =EDT_OPENGL
			Case d_directx9
				?mac
				drivertype = EDT_OPENGL
				?win
				drivertype = EDT_DIRECTX9
				?
		End Select
		gfx.device:T_irrIrrlichtDevice=t_irrIrrlichtDevice.create(drivertype,T_irrDimension2d_s32.create(width,height))
		gfx.video =gfx.device.getVideoDriver()
		gfx.scene = gfx.device.getSceneManager()
		gfx.gui = gfx.device.getGuiEnvironment()
		If gfx.video = Null
			Throw "Video Driver not found."
		End If
		If gfx.scene = Null
			Throw "Scene Manager not found."
		End If 
		If gfx.gui = Null
			Throw "Gui driver not found."
		End If
		
		Return out
		
	End Function
	Function Cls()
		gfx.video.beginscene(True,True, T_irrSColor.createFromVals(255,0,0,0) )
	End Function
	Function Flip()
		gfx.video.endScene()
	End Function
	Function RenderWorld()
		gfx.scene.drawall()
	End Function
	
	Global device:T_irrIrrlichtDevice
	Global video:T_irrIVideoDriver
	Global Scene:t_irrISceneManager
	Global gui:t_irrIGuiEnvironment
	
End Type

Type Entity
	Field node:T_irrISceneNode
	Field tmp:Matrix
	Function CreateFromNode:Entity(node:T_irrISceneNode)
		Local out:Entity = New entity
		out.node = node
		Return out
	End Function
	Method New()
		tmp=matrix.create()
	End Method
	
	Method Position(x#,y#,z#,globalspace=False)
		node.setposition( t_irrVector3df.createFromVals(x,y,z) )
	End Method
	Method Move(x#,y#,z#)
		maths.tformpoint(x,y,z,Self)
		node.setposition( T_IrrVector3df.createfromVals( maths.tformx,maths.tformy,maths.tformz ) )
	End Method
	Method Turn(pitch#,yaw#,roll#)
		Node.setRotation(Node.getRotation().Plus(T_irrVector3df.createFromVals(pitch,yaw,roll)) )
		Return 
	End Method
	
	Method Point( at:Entity )
		Local pos:T_IrrVector3df = at.node.getposition()
		Local fpos:t_irrVector3df = node.getposition()
		tmp.lookat( fpos.getx(),fpos.gety(),fpos.getz(),pos.getx(),pos.gety(),pos.getz() )
		tmp.setentityRotation( Self )
	End Method
	

	
	Method Pitch#()
		Local rv:T_irrvector3df = node.getrotation()
		Return rv.getx()
	End Method
	
	Method Yaw#()
		Local rv:T_irrvector3df = node.getrotation()
		Return rv.gety()
	End Method

	Method roll#()
		Local rv:T_irrvector3df = node.getrotation()
		Return rv.getz()
	End Method
	
	Method WorldMatrix:Matrix()
		Local mat:Matrix = New matrix
		mat.mat = node.getabsoluteTransformation()
		Return mat		
	End Method
	
	Method Rotate(pitch#,yaw#,roll#,globalspace=False)
		node.setrotation( t_irrVector3df.createFromVals(pitch,yaw,roll) )
	End Method
	Method SetTexture(index,tex:texture)
		node.setmaterialtexture(index,tex.tex)
	End Method
	
End Type


Type Camera Extends Entity
	Field cnode:T_irrICameraSceneNode
	Function Create:camera(parent:Entity=Null)
		Local out:Camera = New camera
		Local pnode:t_irrISceneNode
		If parent<>Null
			pnode = parent.node
		End If
		If pnode<>Null
			out.cnode = gfx.scene.AddcameraSceneNode(pnode)
		Else
			out.cnode =gfx.scene.addCameraSceneNode()
		End If
		out.node = T_IrrISceneNode(out.cnode)
		Return out
	End Function
	Method move(x#,y#,z#)
		super.move(x,y,z)
		updateCam()
	End Method
	Method Position(x#,y#,z#,globalspace=False)
		super.position(x,y,z)
		updateCam()
	End Method
	Method Turn(pitch#,yaw#,roll#)
		super.turn(pitch,yaw,roll)
		updatecam()
	End Method 
	Method Rotate(pitch#,yaw#,roll#,globalspace=False)
		super.rotate(pitch,yaw,roll,globalspace)
		updateCam()
	End Method
	
	Method Point(at:Entity)
		super.point(at)
		updateCam()
	End Method
	
	
	Method updateCam()
		Local cam:T_irrICameraSceneNode = cnode
		Local m:T_irrMatrix4=T_irrMatrix4.create()
		m.setRotationDegrees(cam.getRotation())
		Local u:T_irrVector3df=T_irrVector3df.createFromVals(0,1,0)
		m.transformVect(u)
		cam.setUpVector(u)
		Local v:T_irrVector3df=T_irrVector3df.createFromVals(0,0,100)
   		m.transformVect(v)
		v.PlusEq(cam.getPosition())
		cam.setTarget(v)
	End Method
	
	

End Type

Type Matrix
	Field mat:t_irrMatrix4
	Field rot:t_irrVector3df
	Field pos:T_irrVector3df
	Function Create:Matrix()
		Local out:matrix = New matrix
		out.mat = t_irrMatrix4.create()
		Return out
	End Function
	Method Identity()
		mat.makeidentity()
	End Method
	Method EntityRotation( in:Entity )
		Local rv:T_irrVector3df = in.node.getrotation()
		rotate( rv.getx(),rv.gety(),360)
	End Method
	Method SetEntityRotation( in:Entity )
		Local rv:T_IrrVector3df = mat.getrotationdegrees()
		in.node.setrotation( rv )
	End Method

	
	Method Rotate(pitch#,yaw#,roll#)
		mat.setRotationDegrees( T_irrVector3df.createfromvals(pitch,yaw,roll) )
	End Method
	Method GetRotate()
		rot = mat.getrotationDegrees()
	End Method
	Method Pitch#()
		Return rot.getX()
	End Method
	Method Yaw#()
		Return rot.getY()
	End Method
	Method Roll#()
		Return rot.getZ()
	End Method
	Method Position(x#,y#,z#)
		mat.settranslation( t_irrVector3df.createfromvals( x,y,z) )
	End Method
	Method GetPosition()
		pos=mat.gettranslation()
	End Method
	Method X#()	
		Return pos.getX()
	End Method
	Method Y#()
		Return pos.GetY()
	End Method
	Method Z#()
		Return pos.getZ()
	End Method
	Method MultiplyNew:Matrix(with:Matrix)
		Local out:Matrix = New matrix
		out.mat = mat.Mult(with.mat)
		Return out
	End Method
	Method Multiply(with:matrix)
		mat.multeq(with.mat)
	End Method
	Method LookAt(fx#,fy#,fz#,x#,y#,z#)
		mat.buildcameralookatMatrixLH( T_irrVector3df.createfromvals(fx,fy,fz),t_irrVector3df.createfromvals(x,y,z),t_irrvector3df.createfromvals(0,-1,0) )
	End Method
	Method TformPoint(x#,y#,z#)
		Local vec:T_IrrVector3df = t_irrvector3df.createfromvals(x,y,z)
		mat.transformvect( vec )
		tformx = vec.getx()
		tformy = vec.gety()
		tformz = vec.getz()
	End Method
	
	Method TFormVector(x#,y#,z#)
		Local vec:T_IrrVector3df = t_irrvector3df.createfromvals(x,y,z)
		mat.rotatevect( vec )
		tformx = vec.getx()
		tformy = vec.gety()
		tformz = vec.getz()
	End Method
	
	Field tformx#,tformy#,tformz#
				
End Type

Type Maths
	Function TFormPoint( x#,y#,z#,ent:Entity )
		Local mt:Matrix = ent.WorldMatrix()
		mt.TformPoint( x,y,z )
		tformx=mt.tformx
		tformy=mt.tformy
		tformz=mt.tformz
	End Function
	Function TFormVector( x#,y#,z#,ent:Entity )
		Local mt:Matrix = ent.worldMatrix()
		mt.tformVector( x,y,z )
		tformx = mt.tformx
		tformy = mt.tformy
		tformz = mt.tformz
	End Function
	Function TFormedX#()
		Return tformx
	End Function
	Function TFormedY#()
		Return tformy
	End Function
	Function TFormedZ#()
		Return tformz
	End Function
	Global TformX#,tformy#,tformz#
End Type




Type Prefab
	Function Cube:Entity(size:Float,parent:Entity = Null)
		Local node:T_IrrISceneNode
		Local pnode:T_IrrISceneNode
		If parent<>Null
			pnode = parent.node
		End If
		If pnode<>Null
		node = gfx.scene.addtestSceneNode(size,pnode)
		Else
		node = gfx.scene.addTestSceneNode(Size)
		End If
		Local out:Entity = entity.createfromnode(node)
			
		Return out
	End Function
	
End Type

Type Texture
	Field tex:t_irrITexture
	Function Load:Texture(file:String)
		Local out:texture = New texture
		out.tex = gfx.video.gettexture(file)
		Return out
	End Function
End Type




Local g:gfx = gfx.graphics3d(640,480)

Local cube:Entity = prefab.cube(10)
Local cam:Camera = camera.create()
cam.position(0,0,-20)
Local tex:Texture = texture.load("media/wall.bmp")
cube.settexture(0,tex)

Local x#
Repeat

	If KeyDown(KEY_A)
		cam.move(-1,0,0)
	End If
	If KeyDown(KEY_D)
		cam.move(1,0,0)
	End If 
	If KeyDown(KEY_W)
		cam.move(0,0,-1)
		End If
		If KeyDown(KEY_S)
		cam.move(0,0,1)
	End If
	Local mxi# = MouseX()-320
	Local myi# = MouseY()-240
	MoveMouse 320,240
	'cam.turn(myi,mxi,0)
	cam.point(cube)
	If MouseDown(1)
		Print "Pitch:"+cam.pitch()+" Yaw:"+cam.yaw()+" roll:"+cam.roll()
	End If
	
	

	gfx.cls()
	gfx.renderWorld()
	gfx.flip()
	Delay 10
Until KeyDown(KEY_ESCAPE)