Topic: Collision

Here is my code so far:

Strict
Framework Irrlicht.Core



Local receiver:IEventReceiver=IEventReceiver.Create(MyEventReceiver.generate)

Global device:IrrlichtDevice = ..
    IrrlichtDevice.Create(EDT_DIRECT3D9, _DIMENSION2DI(640, 480), 16, ..
        False, False, False, receiver)
        Local driver:IVideoDriver = device.getVideoDriver()
Local smgr:ISceneManager = device.getSceneManager()
Local guienv:IGUIEnvironment = device.getGUIEnvironment()
Rem
We add a hello world label To the window, using the GUI environment.
EndRem

Local s:Iguistatictext=guienv.addStaticText("Hello World! This is the Irrlicht  renderer!", ..
    _RECTI(10,10,260,22),True)
device.setWindowCaption("FPS")
Local white:scolor=_scolor(255,255,255,255) 
s.setBackgroundColor(white)
Local mesh:IMesh = smgr.getMesh("ship_models/11.b3d")
's.SetoverrideColor(white)

Type ship
Field node:imeshscenenode
Global list:TList=New TList
Field selector:Itriangleselector
EndType

For Local x=1 To 50
Local s:ship=New ship
s.node=smgr.addmeshscenenode(mesh)
ship.list.addlast(s)
Next

'Global node:ImeshSceneNode = smgr.addmeshSceneNode(mesh)
'Global node2:Imeshscenenode=smgr.addmeshscenenode(mesh)
For Local s:ship=EachIn ship.list
    s.selector = smgr.createTriangleSelector(Mesh, s.node)
    s.node.setTriangleSelector(s.selector)
    s.selector.drop()
Next

Local num=0
For Local s:Ship=EachIn ship.list
s.node.setposition(_vector3df(0,num,0))
num=num+10
Local anim:ISceneNodeAnimator = smgr.createCollisionResponseAnimator( s.selector, s.node, _VECTOR3DF(1.5,1,1.5),_VECTOR3DF(0,0,0),_VECTOR3DF(0,0,0))
s.node.addAnimator(anim)
anim.drop()
Next

Global globnode:Ilightscenenode=smgr.addlightscenenode()


Local ship_tex:itexture=driver.gettexture("ship_models\blueship-low.png")
For Local s:ship=EachIn ship.list
If (s.node)
    s.node.setMaterialFlag(EMF_LIGHTING, False)
    'node.setMD2Animation ( EMAT_STAND )
    s.node.setMaterialTexture( 0,ship_tex )
EndIf
Next

Global prev_mouse_X:Int=-1
Global prev_mouse_y:Int=-1

Type MyEventReceiver Extends IEventReceiver
    Method OnEvent:Int(event:SEvent)
        Local x:Int=event.getmousex()
        Local y:Int=event.getmousey()
        
            
            If event.geteventtype()= EET_MOUSE_INPUT_EVENT
            If x<640 And y<480 
           If prev_mouse_x>-1
Local new_x=prev_mouse_x-x
Local new_y=prev_mouse_y-y
For Local S:ship=EachIn ship.list
nodeturn(s.node,new_y,-new_x,0)
Exit
Next
            EndIf
             prev_mouse_x=x
            prev_mouse_y=y
        EndIf
        EndIf
        For Local s:ship=EachIn ship.list
        If (s.node And event.getEventType()=EET_KEY_INPUT_EVENT And ..
            Not event.getKeyPressedDown())
        
            Local key:Int=event.getKeyInputKey()
                    
            Select key
                Case EKEY_KEY_W
                    Local v:Vector3df=s.node.GetRotation()
                    v.setY(v.getY()+20.0)
                    s.node.SetRotation(v)
                    Return True
                Case EKEY_KEY_S
                    Local v:Vector3df=s.node.GetRotation()
                    v.setY(v.getY()-20.0)
                    s.node.SetRotation(v)
                    Return True
                Default
                    Return False
            EndSelect
        
        Exit
        EndIf
        Next
        Return False
    EndMethod

    ' we must override the generate function in order for instantiation to work properly
    Function generate:IEventReceiver()
        Return New MyEventReceiver
    EndFunction
EndType

Global camera:Icamerascenenode=smgr.addCameraSceneNode(Null, _VECTOR3DF(0,30,-40), _VECTOR3DF(0,5,0))
'Camera.bindTargetAndRotation(True)

'For Local s:ship=EachIn ship.list
'camera.setParent(s.node)
'Exit
'Next

'--- set camera To behave as cockpit camera of ship ---
Function makeCockpit(camera:ICameraSceneNode,node:ISceneNode, offset:vector3df) '//relative position of camera To node (ship)

    Local m:matrix4=matrix4.Create()
    m.setRotationDegrees(node.GetRotation())
    Local frv:vector3df = _vector3df (0.0, 0.0, 1.0)
    m.transformVect(frv)
    Local upv:vector3df =_vector3df (0.0, 1.0, 0.0)
    m.transformVect(upv)
    m.transformVect(offset)

    camera.setPosition((node.getPosition()).plus(offset))'; //position camera in front of the ship
    camera.setUpVector(upv)'; //set up vector of camera
    camera.setTarget((node.getPosition()).plus( frv))' //set target of camera (look at point) (thx Zeuss For correcting it)

'    camera.updateAbsolutePosition()
EndFunction

Local i#
'node.SetRotation(_vector3df(0,90,0))
While(device.run())

    driver.beginScene(True, True, _SCOLOR(0,0,0,0))



For Local S:ship=EachIn ship.list
s.node.setposition(TFormPoint(0,0,.1,s.node,globnode))
makecockpit(camera,s.node,_vector3df(0,2,-5))
'Local nodepos:vector3df=TFormPoint(0,0,10,s.node,globnode)
'Local noderot:vector3df=s.node.GetRotation()
'camera.setposition(_vector3df(0,3,-4))
'camera.SetRotation(noderot)
Exit
Next


device.setWindowCaption("FPS: "+driver.getfps())
    smgr.drawAll()
    guienv.drawAll()

    driver.endScene()
Wend


device.drop()


Function TFormPoint:Vector3df(x:Float,y:Float,z:Float,source:ISceneNode,dest:ISceneNode)
    Local lastTForm:Vector3df=_VECTOR3DF(x,y,z)

    ' first convert to world from the source
    If source Then source.getAbsoluteTransformation().transformVect(lastTForm)

    ' now from world to local
    If dest Then dest.getRelativeTransformation().transformVect(lastTForm)
    
    Return lastTForm
EndFunction


Function NodeMove(node:ISceneNode,x:Float,y:Float,z:Float)    
    ' from: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=4680            
    Local dest:Vector3df=Vector3df.createFromVals(x,y,z)
    node.getRelativeTransformation().transformVect(dest)
    node.setPosition(dest)
EndFunction

Function NodeTurn(node:ISceneNode,pitch:Float,yaw:Float,roll:Float)
    ' from: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=4680
    Local m:Matrix4=Matrix4.Create()
    Local n:Matrix4=Matrix4.Create()
    Local t:Matrix4=Matrix4.Create()
    
    m.setRotationDegrees(node.GetRotation())
    n.setRotationDegrees(_VECTOR3DF(0,0,roll))
    t.setRotationDegrees(_VECTOR3DF(pitch,0,0))
    
    n.MultEq(t)
    t.setRotationDegrees(_VECTOR3DF(0,yaw,0))
    n.MultEq(t)
        
    m.MultEq(n)
    node.SetRotation(m.getRotationDegrees())
EndFunction

Function NodePointTo:Vector3df(node:ISceneNode, x:Float, y:Float, z:Float)
    Local direction:Vector3df = _VECTOR3DF(x,y,z).Minus(node.getPosition())
    node.SetRotation(direction.getHorizontalAngle())
EndFunction

collision doesnt work as expected, it seems ok on the quake level demo that comes with irrlicht, but here there is weird behaviour such as being able to go throw a mesh if you wiggle the mouse and sometimes the collisions are made no-where near the ships.

Re: Collision

greetings smile  one thing i see is that in the call to createCollisionResponseAnimator() you are passing the current nodes selector.  this should actually be a selector to what you want to collide with, not the current node.  so for example, if you had 2 ships and you want them to collide, you need to set ships 1 collisionresponseanimator to the selector for ship 2, and ship 2s collisionresponseanimator to the selector for ship 1.  if you want to have your camera collide against all ships, you need to use an IMetaTriangleSelector of all ships selectors and then pass in the meta selector to the cameras collision animator.  so a couple of changes will set you up for this in your code (this is untested):

' something to hold all ships
Global all_ships_selector:IMetaTriangleSelector = IMetaTriangleSelector.create()
For Local s:ship=EachIn ship.list
    s.selector = smgr.createTriangleSelector(Mesh, s.node)
    s.node.setTriangleSelector(s.selector)
    all_ships_selector.addTriangleSelector(s.selector)
    s.selector.drop()
Next

For Local s:Ship=EachIn ship.list
s.node.setposition(_vector3df(0,num,0))
num=num+10
Local all_ships_but_me:IMetaTriangleSelector = smgr.createMetaTriangleSelector()
For Local ship_collision:Ship = EachIn ship.list
    ' if not the current ship, then add it into the meta selector
    If Not ship_collision.Compare(s) Then all_ships_but_me.addTriangleSelector(ship_collison.selector)
Next
Local anim:ISceneNodeAnimator = smgr.createCollisionResponseAnimator( all_ships_but_me, s.node, _VECTOR3DF(1.5,1,1.5),_VECTOR3DF(0,0,0),_VECTOR3DF(0,0,0))
s.node.addAnimator(anim)
anim.drop()
Next

Hope this helps smile

3 (edited by Slenkar 2009-04-06 08:04:15)

Re: Collision

thanks for the help

Imetatriangle selector doesnt have a create function
just a createfromhandle function, im not sure what to use for a phandle argument.

also, allshipsbutme doesnt have a .selector

it compiled when I changed allshipsbutme.selector to allshipsbutme but no collisions happened (probably because i was using NEW imetatriangleselector)

Re: Collision

greetings smile  i fixed the above code.  keep in mind you will also need to add a collisionresponseanimator to the camera as well if you want it to collide with the ships.

5 (edited by Slenkar 2009-04-07 07:49:22)

Re: Collision

thanks,

the behaviour is still very wierd
check it out:
http://www.mediafire.com/download.php?zywg0iyydtz

I read somewhere in the irrlicht forums that sliding collision was buggy.

Re: Collision

unfortunately i dont have my BMAX with me right now (i ran the demo though).  it may be something with the size of your ellipsoid on the response animator.  try this to calculate it from your bounding box:

Local ellipsoid:Vector3df = s.node.getBoundingBox().getMaxEdge().Minus(s.node.getBoundingBox().getCenter())               
Local anim:ISceneNodeAnimator = smgr.createCollisionResponseAnimator( all_ships_but_me, s.node, ellipsoid,_VECTOR3DF(0,0,0),_VECTOR3DF(0,0,0))

again untested.  it may be .MinusVect() instead of .Minus() im not sure.  other things that can affect this are if your model is not based at 0,0,0.  you will need to either reposition it to 0,0,0 or use the offset parameter of the collisionresponseanimator.