Topic: Ib3d sprite system sugestion
Hi, I just wrote a type for a sprite system for Ib3d. It extends mesh type of ib3d and works with other ib3d functions. It has b3d sprite view modes. You only have to add sprite.update() in your main loop to make the sprites face the camera according to its view mode.
I did some quick stress tests and It was 5% faster than the irrlicht native billboards (with 1000 diferent sprites/billboards).
The only thing missing is a copyentity function.
To free the sprite use ib3d_FreeEntity( entity:Sprite ), like any other mesh.
'*****Sprite type ******
Type SPRITE Extends MESH
Global SpriteList:TList=Null
Global cont:Int 'addHillPlaneMesh requests a diferent name for each mesh, don't know why, yet...
Global spMesh:IAnimatedMesh=Null
Field tex:texture=Null
Field angle:Float ' rotatesprite
'Field handle_x:Float,handle_y:Float 'todo
Field view_mode:Int=1
Global rot1:Vector3df,rot3:Vector3df,rot4:Vector3df 'update vectors
Method New()
If Not MeshList Then MeshList=New TList
MeshList.AddLast(Self)
If Not SpriteList Then SpriteList=New TList
SpriteList.AddLast(Self)
EndMethod
Method Destroy()
'If tex Then tex.Free()
tex=Null
_mesh=Null
Super.Destroy()
MeshList.Remove(Self)
SpriteList.Remove(Self)
EndMethod
Function CreateSprite:Sprite(rotate_mode:Int=1,parent_ent:ib3d_Entity=Null)
Local NewSprite:SPRITE=New SPRITE
newsprite.cont:+1
If rotate_mode=1 'uses the already created spmesh, which is faster, if rotate all sprites with spmesh rotates.
If spmesh=Null
spmesh=_g_ib3d_engine.smgr.addHillPlaneMesh("sprite"+cont, _dimension2df(1.0 , 1.0) , _dimension2di(1 , 1) )
If Not spmesh Or Not spmesh.IsValid() Then RuntimeError "Unable to create sprite mesh"
NewSprite._mesh=spmesh
NewSprite.setNode(_g_ib3d_engine.smgr.addMeshSceneNode(IAnimatedMesh(newsprite._mesh).getMesh(0)))
_RotateAnimMesh(IAnimatedMesh(spmesh).handle,newsprite._node.handle,-90,0,0) 'HillPlaneMesh needs to be rotated to face the camera
Else
'NewSprite._mesh= _g_ib3d_engine.smgr.addHillPlaneMesh("sprite"+newSprite.cont, _dimension2df(1.0 , 1.0) , _dimension2di(1 , 1) )
NewSprite._mesh=spmesh
If Not NewSprite._mesh Or Not NewSprite._mesh.IsValid() Then RuntimeError "Unable to create sprite mesh"
NewSprite.setNode(_g_ib3d_engine.smgr.addMeshSceneNode(IAnimatedMesh(newsprite._mesh).getMesh(0)))
End If
Else 'create a new mesh, slower but allows rotation
NewSprite._mesh= _g_ib3d_engine.smgr.addHillPlaneMesh("sprite"+newSprite.cont, _dimension2df(1.0 , 1.0) , _dimension2di(1 , 1) )
If Not NewSprite._mesh Or Not NewSprite._mesh.IsValid() Then RuntimeError "Unable to create sprite mesh"
NewSprite.setNode(_g_ib3d_engine.smgr.addMeshSceneNode(IAnimatedMesh(newsprite._mesh).getMesh(0)))
_RotateAnimMesh(IAnimatedMesh(spmesh).handle,newsprite._node.handle,-90,0,0) 'HillPlaneMesh needs to be rotated to face the camera
End If
If parent_ent Then NewSprite._node.setParent(parent_ent._node) ' set the parent if there is one
ib3d_EntityFX(newsprite,EMF_LIGHTING,0)
Return NewSprite
End Function
Function LoadSprite:Sprite(tex_file$,tex_flag%=EMT_SOLID,rotate_mode:Int=1,parent_ent:ib3d_Entity=Null)
Local NewSprite:Sprite=CreateSprite(rotate_mode,parent_ent)
ib3d_EntityBlend(newsprite,tex_flag)
NewSprite.tex= ib3d_LoadTexture(tex_file)
ib3d_EntityTexture(newsprite,newsprite.tex)
Return NewSprite
End Function
Method ScaleMesh(x_scale:Float,y_scale:Float,z_Scale:Float=1.0) 'z_scale is not used
If Not _mesh Or Not _mesh.isValid() Then RuntimeError "Mesh is invalid"
If IAnimatedMesh(_mesh) Then Throw "Animated meshes are not editable"
Local mm:IMeshManipulator=_g_ib3d_engine.smgr.getMeshManipulator()
mm.ScaleMesh(SMesh(_mesh),Vector3df.createFromVals(x_scale,y_scale,1.0)) 'z=1.0
EndMethod
Function Update(cam:CAMERA)
Local cam_rot:Vector3df
Local temp:SPRITE
If spritelist<>Null
rot1=cam._node.GetRotation()
rot1.setZ(0)
rot3=cam._node.GetRotation()
rot4=cam._node.GetRotation()
rot4.setx(0)
For temp=EachIn SpriteList
Select temp.view_mode 'B3D Sprite view modes
Case 1
temp._node.SetRotation(rot1)'cam_rot)
Case 2
'FREE
Case 3
temp._node.SetRotation(rot3)'cam_rot)
Case 4
temp._node.SetRotation(rot4)'cam_rot)
End Select
Next
End If
End Function
End Type
Function ib3d_CreateSprite:SPRITE(rotate_mode:Int=1,parent:ib3d_Entity=Null)
If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
Return sprite.CreateSprite(rotate_mode:Int,parent)
EndFunction
Function ib3d_LoadSprite:SPRITE(file:String,flag:Int=EMT_SOLID,rotate_mode:Int=1,parent:ib3d_Entity=Null)
If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
Return sprite.LoadSprite(file,flag,rotate_mode:Int,parent)
EndFunction
Function ib3d_SpriteViewMode(sp:SPRITE,mode:Int)
If mode>0 And mode<5
sp.view_mode=mode
End If
End Function
Function ib3d_RotateSprite(sp:SPRITE,angle:Float)
sp.angle:+angle
_RotateAnimMesh(IAnimatedMesh(sp._mesh).handle,sp._node.handle,0,0,sp.angle)
End Function
Function ib3d_ScaleSprite(sp:SPRITE,x_scale:Float,y_scale:Float)
ib3d_ScaleEntity(sp,x_scale,y_scale,1)
End Function
*EDIT* small update
note: you need to put SPRITE.update() in the main loop to update the sprites.
Any suggestion will be appreciated.
thanks,