I can't make any sense of the collision system. It seems entirely horrible. I could say something nice like 'I'm sure it made more sense back in Blitz3D', but I _owned_ B3D and I could never make sense of it back then either. :)
So I made a simpler one. There are only four commands:
collide (Checks for collision between two entities using sphere-to-mesh check) collide_sphere (Checks for collision between two entities using sphere-to-sphere check) latestcollision (gets data object from an entity's most recent collision) resetentities (must be called before moving anything every frame)
It uses as much of the default behaviour as possible to avoid weird side effects, so it's not as efficient as it could be. But it should still be faster than the default (fingers crossed).
Strict
Import sidesign.minib3d
'Rem
Graphics3D 640, 480
Local cube:TMesh=CreateCube()
cube.PositionEntity -5,0,0
cube.EntityRadius 1
Local sphere:TMesh=CreateSphere()
sphere.PositionEntity 0,0,0
sphere.EntityRadius 1
Local sphere2:TMesh=CreateSphere()
sphere2.PositionEntity 0,1,0
sphere2.EntityRadius 1
Local cam:TCamera=CreateCamera()
cam.PositionEntity 0,0,-5
'hardwareinfo.displayinfo
While Not AppTerminate() And Not KeyHit(KEY_ESCAPE)
ResetEntities
If KeyDown(KEY_LEFT) cube.MoveEntity -0.1,0,0
If KeyDown(KEY_RIGHT) cube.MoveEntity 0.1,0,0
If KeyDown(KEY_UP) cube.MoveEntity 0,0.1,0
If KeyDown(KEY_DOWN) cube.MoveEntity 0,-0.1,0
If collide (cube, sphere)
Print "THUMP!"
Print "You hit the lower sphere at: " + latestcollision (cube).x + ", "..
+ latestcollision (cube).y + ", " + latestcollision (cube).z
End If
If collide (cube, sphere2) Print "BUMP!"
RenderWorld
Flip
Wend
'EndRem
Function collide (ent:TEntity, ent2:TMesh)
Local old = ent.no_collisions
If TCollision.QuickCheck(ent,ent2)
ent2.TreeCheck()
TCollision.SphereToMesh(ent,ent2)
EndIf
If old < ent.no_collisions Return 1
End Function
Function collide_sphere (ent:TEntity, ent2:TEntity)
If TCollision.SphereToSphere(ent,ent2)
ent.no_collisions=ent.no_collisions+1
Local i=ent.no_collisions-1
ent.collision=ent.collision[..i+1]
ent.collision[i]=New TCollisionImpact
ent.collision[i].ent=ent2
Return 1
EndIf
End Function
Function latestcollision:TCollisionImpact (ent:TEntity)
If ent.no_collisions = 0 Return Null
Return ent.collision[ent.no_collisions-1]
End Function
Function resetentities(list:TList=Null)
If Not list list = TEntity.entity_list
For Local loop:TEntity = EachIn list
loop.ResetEntity
Next
EndFunction
If you give it a go, or especially if you give a go and find a bug, please let me know!
|