1 (edited by ksalomao 2007-05-21 11:39:03)

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,

2 (edited by ksalomao 2007-05-21 11:38:26)

Re: Ib3d sprite system sugestion

Oh, I also did a Billboard type for Ib3d:

'*****BillBoard type ******

Type BillBoard Extends MESH
    Field BBNode:IBillboardSceneNode=Null
    Field tex:TEXTURE=Null
    
    Method New()
        If Not MeshList Then MeshList=New TList
        MeshList.AddLast(Self)
    EndMethod
    
    Method Destroy()
        'If tex Then tex.Free()            
        tex=Null
        bbnode.Destroy
        BBNode=Null
        _mesh=Null
        Super.Destroy()
        MeshList.Remove(Self)        
    EndMethod
    
    Function CreateBillBoard:BillBoard(parent_ent:ib3d_Entity=Null)
        Local BB:BillBoard=New BillBoard
        
        bb.BBNode=_g_ib3d_engine.smgr.addbillboardscenenode()
        If Not bb.BBNode Then RuntimeError "Unable to create BillBoard"
        bb.setnode(bb.BBNode)'_g_ib3d_engine.smgr.addbillboardscenenode())
                
        If parent_ent  Then bb._node.setParent(parent_ent._node)  ' set the parent if there is one
        ib3d_EntityFX(bb,EMF_LIGHTING,0)
        Return bb
    End Function
    
    Function LoadBillBoard:BillBoard(tex_file$,tex_flag%=EMT_SOLID,parent_ent:ib3d_Entity=Null)

        Local bb:BillBoard=CreateBillBoard(parent_ent)
    
        ib3d_EntityBlend(bb,tex_flag)
        bb.tex= ib3d_LoadTexture(tex_file)
        ib3d_EntityTexture(bb,bb.tex)

        Return bb        
    End Function
    
    Method ScaleBillBoard(x_scale:Float,y_scale:Float)
        BBNode.setsize(_dimension2df(x_scale,y_scale))
    End Method
    
End Type

Function ib3d_CreateBillBoard:BillBoard(parent:ib3d_Entity=Null)
    If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
    Return BillBoard.CreateBillBoard(parent)
EndFunction

Function ib3d_LoadBillBoard:BillBoard(file:String,flag:Int=EMT_SOLID,parent:ib3d_Entity=Null)
    If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
    Return BillBoard.LoadBillBoard(file,flag,parent)
EndFunction

Function ib3d_ScaleBillBoard(bb:BillBoard,x_scale:Float,y_scale:Float)
    bb.ScaleBillBoard(x_scale,y_scale)
EndFunction

Re: Ib3d sprite system sugestion

very very cool.  do you have a test prog?  if your ok with it, ill be looking at incorporating this into the mod.

4 (edited by ksalomao 2007-05-21 11:37:41)

Re: Ib3d sprite system sugestion

Of course, glad you liked it.
I did a function for copysprite but it was slower then making a new sprite. Don't know why...


here is the example:

SuperStrict
Framework irrlicht.b3d

AppTitle = "teste"
Global width:Int=800,height:Int=600
ib3d_Graphics3D (width,height , 32,2,0,0,EDT_DIRECT3D9)
SeedRnd MilliSecs()

'Devil's freelook code
Global FreeLookXS#, FreeLookZS#, FreeLookRotXS#, FreeLookRotYS#, oldmx:Float,oldmy:Float

'CAMERA And LIGHT
Global cam:Camera = ib3d_CreateCamera()
cam.Position (0,0,-20)
Local light:light = ib3d_CreateLight()
ib3d_TurnEntity( light , 45 , 45 , 0)

'flush mouse moviment
MouseXSpeed()  
MouseySpeed()

Local cont:Int=0
'create sprites code:
Local sp:SPRITE
Local bb:BillBoard 
Local num_sprites:Int=1000
Local i:Int

For i=0 To num_sprites
    sp=ib3d_createsprite()
    ib3d_PositionEntity(sp,Rand(-12,12),Rand(-10,10),Rand(-6,10))
    'ib3d_ScaleEntity(sp,rand(1-20),rand(1-20),rand(1-20))
    'ib3d_RotateEntity(sp,Rand(0,360),Rand(0,360),Rand(0,360))
    'ib3d_SpriteViewMode(sp,Rand(1,4))
    'ib3d_RotateSprite(sp,Rand(-360,360))    
Next
'bb=ib3d_loadbillboard("clark2.png",EMT_SOLID)
'ib3d_PositionEntity(bb,0,0,-10)

Local vm%=1
ib3d_SetFontColor(255,0,0)
Repeat
    FreeLook(cam,0.1,0.2)
    
    'change view mode
    If ib3d_KeyHit(KEY_ENTER)
        vm:+1 
        If vm=5 Then vm=1
        For sp =EachIn sp.spritelist
            ib3d_SpriteViewMode(sp,vm)
        Next
    End If
    
    'random rotation 
    If ib3d_KeyHit(KEY_R)
        For sp =EachIn sp.spritelist
            ib3d_RotateSprite(sp,Rand(-360,360))
        Next
    End If
    
    'random scale
    If ib3d_KeyHit(KEY_S)
        For sp =EachIn sp.spritelist
            ib3d_scalesprite(sp,Rnd(0.1,5),Rnd(0.1,5))
        Next
        For bb=EachIn bb.meshlist
            ib3d_ScaleBillBoard(bb,Rnd(0.1,5),Rnd(0.1,5))
        Next
    End If
    
    'Change to billbords
    If ib3d_KeyHit(KEY_SPACE)
        cont=1-cont
        If cont=1
            For sp =EachIn sp.spritelist
                ib3d_FreeEntity(sp)
            Next
            For i=0 To num_sprites
                bb=ib3d_createbillboard()
                ib3d_PositionEntity(bb,Rand(-12,12),Rand(-10,10),Rand(-6,10))
                ib3d_ScaleBillBoard(bb,1,1)
            Next
        Else If cont=0
            For bb =EachIn bb.Meshlist
                ib3d_FreeEntity(bb)
            Next
            For i=0 To num_sprites
                sp=ib3d_createsprite()
                ib3d_PositionEntity(sp,Rand(-12,12),Rand(-10,10),Rand(-6,10))
            Next
        End If
        GCCollect()
    End If
    
    
    
    
    
    sprite.Update(cam)
    ib3d_DrawText "KEY_SPACE TO CHANGE TO BILLBOARDS AND BACK TO SPRITE",20,30
    ib3d_DrawText "fps = "+fpscounter.counter(),20,50
    ib3d_DrawText "Sprite Viewmode = "+vm,20,70
    ib3d_DrawText "KEY_ENTER = change View Mode",20,90
    ib3d_DrawText "KEY_R = Random Rotation",20,110
    ib3d_DrawText "KEY_S = Random Scale",20,130
    ib3d_DrawText "Mem = "+GCMemAlloced()/1000+"kb",20,150
    
    ib3d_RenderWorld
    
Until ib3d_KeyHit(KEY_ESCAPE) 
ib3d_EndGraphics()
End

'****** Types *****

Function FreeLook(camera:camera, sp# = .1, sp2#=0.2)
    Local pitch#,yaw#
    If sp# > 0 Then
        FreeLookXS# = (FreeLookXS# + ((ib3d_KeyDown(KEY_D) Or ib3d_KeyDown(KEY_RIGHT)) - (ib3d_KeyDown(KEY_A) Or ib3d_KeyDown(KEY_LEFT))) * sp#) * .75
        FreeLookZS# = (FreeLookZS# + ((ib3d_KeyDown(KEY_W) Or ib3d_KeyDown(KEY_UP)) - (ib3d_KeyDown(KEY_S) Or ib3d_KeyDown(KEY_DOWN))) * sp#) * .75
        ib3d_MoveEntity camera, FreeLookXS#, 0, FreeLookZS#
    EndIf
    FreeLookRotXS# = ((-MouseXSpeed() - FreeLookRotXS#) * sp2 + FreeLookRotXS#) * .5
    FreeLookRotYS# = ((MouseYSpeed() - FreeLookRotYS#) * sp2 + FreeLookRotYS#) * .5
    If ib3d_EntityPitch(camera) + FreeLookRotYS# < -89 pitch# = -89 ElseIf ib3d_EntityPitch(camera) + FreeLookRotYS# > 89 pitch# = 89 Else pitch# = ib3d_EntityPitch(camera) + FreeLookRotYS#
        yaw# = -FreeLookRotXS# + ib3d_EntityYaw(camera)
        ib3d_RotateEntity camera, pitch#, yaw#, 0
        MoveMouse Width/ 2 , Height / 2
        MouseXSpeed()  
        MouseySpeed()
End Function

Function MouseXSpeed:Float()
    Local mxs:Float
    mxs=ib3d_MouseX()-oldmx
    oldmx=ib3d_MouseX()
    Return mxs
End Function

Function MouseYSpeed:Float()
    Local mys:Float
    mys=ib3d_MouseY()-oldmy
    oldmy=ib3d_MouseY()
    Return mys
End Function


Type FPScounter
    Global FPS_Counter:Int=0,old_ms:Int,FPS:Int
    Function counter:Int()
    FPS_Counter:+ 1
    If MilliSecs()-old_ms>=1000
        old_ms=MilliSecs()
        FPS=FPS_Counter
        FPS_Counter = 0
        'Print fps
    EndIf
    Return fps
    End Function
        
End Type


'*****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


'*****BillBoard type ******

Type BillBoard Extends MESH
    Field BBNode:IBillboardSceneNode=Null
    Field tex:TEXTURE=Null
    
    Method New()
        If Not MeshList Then MeshList=New TList
        MeshList.AddLast(Self)
    EndMethod
    
    Method Destroy()
        'If tex Then tex.Free()            
        tex=Null
        bbnode.Destroy
        BBNode=Null
        _mesh=Null
        Super.Destroy()
        MeshList.Remove(Self)        
    EndMethod
    
    Function CreateBillBoard:BillBoard(parent_ent:ib3d_Entity=Null)
        Local BB:BillBoard=New BillBoard
        
        bb.BBNode=_g_ib3d_engine.smgr.addbillboardscenenode()
        If Not bb.BBNode Then RuntimeError "Unable to create BillBoard"
        bb.setnode(bb.BBNode)'_g_ib3d_engine.smgr.addbillboardscenenode())
                
        If parent_ent  Then bb._node.setParent(parent_ent._node)  ' set the parent if there is one
        ib3d_EntityFX(bb,EMF_LIGHTING,0)
        Return bb
    End Function
    
    Function LoadBillBoard:BillBoard(tex_file$,tex_flag%=EMT_SOLID,parent_ent:ib3d_Entity=Null)

        Local bb:BillBoard=CreateBillBoard(parent_ent)
    
        ib3d_EntityBlend(bb,tex_flag)
        bb.tex= ib3d_LoadTexture(tex_file)
        ib3d_EntityTexture(bb,bb.tex)

        Return bb        
    End Function
    
    Method ScaleBillBoard(x_scale:Float,y_scale:Float)
        BBNode.setsize(_dimension2df(x_scale,y_scale))
    End Method
    
End Type

Function ib3d_CreateBillBoard:BillBoard(parent:ib3d_Entity=Null)
    If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
    Return BillBoard.CreateBillBoard(parent)
EndFunction

Function ib3d_LoadBillBoard:BillBoard(file:String,flag:Int=EMT_SOLID,parent:ib3d_Entity=Null)
    If Not _g_ib3d_engine Then RuntimeError "iB3D engine has not been initialized"
    Return BillBoard.LoadBillBoard(file,flag,parent)
EndFunction

Function ib3d_ScaleBillBoard(bb:BillBoard,x_scale:Float,y_scale:Float)
    bb.ScaleBillBoard(x_scale,y_scale)
EndFunction

5 (edited by ksalomao 2007-05-21 12:11:32)

Re: Ib3d sprite system sugestion

There was some flaws in the code, it is better now and slightly faster.
use ib3d_LoadSprite or ib3d_CreateSprite to create new sprites. To speed things up by default it creates only one mesh to all sprites. The problem is that if you rotate the mesh (ib3d_RotateSprite) all sprites will rotate together. I put an option to create sprites with diferent meshes which allows mesh rotation normally, but is slightly slower. The parameter rotation_mode is there for that option, 1 = single mesh and 2 = individual meshes.

*EDIT* only ib3d_RotateSprite needs independent meshes to work as expected.
You can use ib3d_RotateEntity normally with the default sprites (rotate_mode=1), but it will only have any effect if you use SpriteViewMode =2 (free), because the update function will rotate the sprite to face the camera.

I updated the example code above and the sprite type and billboard type.

The Sprite type supports normal ib3d entities/mesh commands as it is a normal mesh. To update the sprites you must put Sprite.Update in the main loop. (else if you use only spriteview mode 2 (free) there is no need to update).

If you don't need to rotate the mesh or to use a sprite as a decal, I guess it is better to use BillBoards as they are faster.

To scale the billboard use ib3d_ScaleBillBoard. I think other commands (except rotate) function normally, like ib3d_PositionEntity or ib3d_EntityTexture.

gman, could you please check my destroy method: If use "If tex Then tex.Free() " and there is another sprite using the same texture (not the same texture, but the same texture file loaded with ib3d_loadtexture for each sprite), I get an error. But if I don't free the texture it remains loaded in the memory.

Re: Ib3d sprite system sugestion

i started implementing this into the ib3d framework.  working very slick thanks again.  there are a few things.  v1.3 of irrlicht provides a way to rotate meshes via a matrix.  its much faster than my custom routine so i will replace that.  also, i havent investigated yet but when i scale in the demo it crashes on me.  i hope to have this in and released sometime tonight.

as for the texture thing.  i will take a look and see what may be up.  i may not have the translation of Free() correct and its killing resources that shouldnt be killed.

Re: Ib3d sprite system sugestion

i see the problem with the free() method so hopefully i can get it whipped into shape.  i havent had a chance to look into the scale issue im having yet.

Re: Ib3d sprite system sugestion

Strange, here I got no crash with scale. It hapens with sprite or with billboards or both?
with sprite I simply used: ib3d_ScaleEntity(sprite,x_scale,y_scale,1) . Maybe the last parameter (z axis) should be 1.0 because its a float. Please, try that.

This new rotate method may speed thing up. Thanks.

( I just noticed that I am not using the scalemesh method and I forgot to delete it)