1 (edited by ksalomao 2007-04-16 14:36:31)

Topic: Sprites instead of billboard

Hi,
I am trying to make sprites similar to b3d. Since Irrlicht billboards always face the camera, we have to use another method to simulate SpriteViewMode 2 (Free), 3 and 4 (upright).  I am having some problems to emulate them.
First I tried to create a quad and texture it, but it did not work (nothing appeared on screen!!). I simply used the b3d method:

local Sprite:Mesh=ib3d_CreateMesh()
Local surf:Surface= ib3d_CreateSurface(Sprite,SF_NORMAL)
    surf.AddVertex(-1,-1,0, 0, 1)
    surf.AddVertex(-1, 1,0, 0, 0)
    surf.AddVertex( 1, 1,0, 1, 0)
    surf.AddVertex( 1,-1,0, 1, 1)
    surf.AddTriangle(0,1,2)
    surf.AddTriangle(0,2,3)
Local tex:texture = ib3d_loadtexture(tex_filename)
ib3d_EntityTexture (sprite,tex)

After I searched on Irrlich forum I tried this (which worked!, just like a quad!)

global sprite3:iscenenode
Local sp:IAnimatedMesh = _g_ib3d_engine.smgr.addHillPlaneMesh("sprite" , _dimension2df(1.0 , 1.0) , _dimension2di(1 , 1) )
    sprite3:iscenenode=_g_ib3d_engine.smgr.addmeshscenenode(sp.getmesh(0))
    sprite3.setmaterialtype(EMT_TRANSPARENT_ALPHA_CHANNEL)
    sprite3.setmaterialtexture(0,_g_ib3d_engine.driver.gettexture("sprite.png"))
    sprite3.setscale(Vector3df.createFromVals(10,10,10))
    sprite3.setposition(_vector3df(-7,7,-55))
    sprite3.setRotation(_VECTOR3DF(-90,0,0))   '

ok, my problem now is to update the sprite position. I am having problems to get it right. it behaves strangely, now and then it flips and disapears. If someone could take a look on this code, and help me out, would be great:

Function updateSprite(SpriteViewMode)
Local rot_x#,rot_y#,rot_z#
Select SpriteViewMode
    Case 1
        rot_x#=camera.Pitch(True)
        rot_y#=camera.Yaw(True)
        rot_z#=0
    Case 2
        'FREE
    Case 3
        rot_x#=camera.Pitch(True)
        rot_y#=camera.Yaw(True)
        rot_z#=camera.Roll(True)
    Case 4
        rot_x#=0
        rot_y#=camera.Yaw(True)
        rot_z#=camera.Roll(True)
End Select

sprite3.setRotation(_VECTOR3DF((rot_x+90),rot_y,rot_z))    
End Function

Re: Sprites instead of billboard

greetings smile  off hand i dont see any issues although 3D programming is not my forte.  do you have sample code for a running example to see it in action?  may help resolve the issue.

3 (edited by ksalomao 2007-04-16 14:36:57)

Re: Sprites instead of billboard

SuperStrict
Framework irrlicht.b3d

Global Dwidth:Int = 800
Global DHeight:Int = 600
ib3d_Graphics3D (DWidth,DHeight , 32,2)

'MOUSE
Global FreeLookXS#, FreeLookZS#, FreeLookRotXS#, FreeLookRotYS#, oldmx:Float,oldmy:Float

'CAMERA and LIGHT
Global cam:Camera = ib3d_CreateCamera()
cam.Position (0,0,-12)
Local light:light = ib3d_CreateLight()
ib3d_LightAmbientColor(light,255,255,255)   '<= this seems to activate ambientlight on v1.3

'CREATE b3d Quad  ,It does not appear on screen
Local Quad:MESH=ib3d_CreateMesh()
Local Surf:Surface= ib3d_CreateSurface(Quad,SF_NORMAL)
    Surf.AddVertex(-1,-1,0, 0, 1)
    Surf.AddVertex(-1, 1,0, 0, 0)
    Surf.AddVertex( 1, 1,0, 1, 0)
    Surf.AddVertex( 1,-1,0, 1, 1)
    Surf.AddTriangle(0,1,2)
    Surf.AddTriangle(0 , 2 , 3) 
quad.position (2 , 0 , 0)
quad.scale(5 , 5 , 5)
'Put some texture here:
'Local tex:texture = ib3d_LoadTexture("midia/clark2.png")
'ib3d_EntityTexture (quad,tex)


'USE an Irrlicht Mesh
Local sp:IAnimatedMesh = _g_ib3d_engine.smgr.addHillPlaneMesh("sprite" , _dimension2df(1.0 , 1.0) , _dimension2di(1 , 1) )
Global sprite:iscenenode=_g_ib3d_engine.smgr.addmeshscenenode(sp.getmesh(0))
sprite.setmaterialtype(EMT_TRANSPARENT_ALPHA_CHANNEL)
'sprite.setmaterialtexture(0,_g_ib3d_engine.driver.gettexture("midia/clark2.png"))
sprite.setscale(Vector3df.createFromVals(5,5,5))
sprite.setposition(_vector3df(-4,0,0))
_RotateAnimMesh(IanimatedMesh(sp).handle,_g_ib3d_engine.smgr.getMeshManipulator().handle,-90,0,0)


'flush mouse moviment
MouseXSpeed()  
MouseySpeed()

Repeat
        
    FreeLook(cam,0.01,0.1)
    
    'Update
    
    Local rot_x#=0
    Local rot_y#=cam.Yaw(True)
    Local rot_z#=cam.Roll(True)
            
    'Quad.rotate (-rot_x,rot_y,rot_z)
    'Update Sprite
    sprite.setRotation(_VECTOR3DF( rot_x , rot_y , rot_z) )
    
    ib3d_RenderWorld
    
Until ib3d_KeyHit(KEY_ESCAPE) 

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 DWidth/ 2 , DHeight / 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

Re: Sprites instead of billboard

This is something I plan on implementing in near future myself as a part of larger terrain based project I am working on. Thanks for making a good start ksalomao. I am sure we can work this out.

5 (edited by ksalomao 2007-04-16 14:37:14)

Re: Sprites instead of billboard

Hi, jippo
there is a problem in the update code that makes the sprite flip (and thus disappear). I am trying to figure out why.

'Update code
Local rot_x#=0
Local rot_y#=cam.Yaw(True)
Local rot_z#=cam.Roll(True)
sprite.setRotation(_VECTOR3DF( rot_x , rot_y , rot_z) )

If you add "EMF_BACK_FACE_CULLING,false" for the sprite (with some image of course) you can see that it flips:

sprite.setmaterialflag(EMF_BACK_FACE_CULLING,0)

Re: Sprites instead of billboard

I gave it a look but couldn't fix the flip. sad

Have you had any success?

Re: Sprites instead of billboard

I couldn't solve it neither, something with setrotation because it works with minib3d.
I guess the solution is to use one of the axis rotation codes in the irrlich forum. I will have to figure out how to covert them. If gman could have a look would be great... smile

Re: Sprites instead of billboard

try this for the update code:

Local cam_rot:Vector3df=cam._node.getRotation()
cam_rot.setX(0)
sprite.setRotation(cam_rot)

Re: Sprites instead of billboard

Perfect!! Thanks!

Re: Sprites instead of billboard

Thanks!

Re: Sprites instead of billboard

glad i could help smile  trying to get good rotations using a turn function (which is what the camera and entity turn uses) is pretty hectic.  i think the following code may also work for you:

Local rot_x#=0
Local rot_y#=cam.Yaw()
Local rot_z#=cam.Roll()           
sprite.setRotation(_VECTOR3DF( rot_x , rot_y , rot_z) )

12 (edited by ksalomao 2007-04-19 10:54:14)

Re: Sprites instead of billboard

Ok, I think I understood the problem. thanks
Just another thought: I was testing for speed between irrlicht billboards and this manually created sprite (with the above update code in the loop)  and , to my surprise, the speed was almost the same (for 500 sprites/billboards I had a diference of +/- 1 fps!!). I thought the billboards would have some kind of optimization that would make them faster, but no...
So I think there is no problem to use this manualy created sprite instead of billboards...