Pub.ColDet is now available
BlitzMax Forums/BlitzMax Programming/Pub.ColDet is now available Erm.... what is it?
Info? Screenshots?
Info? Screenshots?
ColDet (at least the B3D version) creates collision volumes for models to use for physics and general collision checks.
gman:
<NoelCower> I need someone to do something for me, and it's very important
<NoelCower> Post on bb.com telling gman that his coldet module requires all code that uses it to be open source
<NoelCower> Due to the viral nature of the LGPL when using static linking
<NoelCower> In short, he's statically linking to LGPL'd source code when he has to make an import library that makes use of a DLL
<NoelCower> Otherwise people have to release any and all code using the module
<NoelCower> Under the LGPL no less
<NoelCower> I need someone to do something for me, and it's very important
<NoelCower> Post on bb.com telling gman that his coldet module requires all code that uses it to be open source
<NoelCower> Due to the viral nature of the LGPL when using static linking
<NoelCower> In short, he's statically linking to LGPL'd source code when he has to make an import library that makes use of a DLL
<NoelCower> Otherwise people have to release any and all code using the module
<NoelCower> Under the LGPL no less
thx tom (and Noel). ill get it into a DLL this evening.
thanks gman, MiniB3D and now this what more can we ask.
kev
kev
you are very welcome :) i will release some bindings for MiniB3D probably not tonight now that i need to build a DLL, but hopefully sunday sometime. tomorrow is one of my daughters B-Day so PC is off limits :)
UPDATE: the download is now a DLL based mod. hopefully can get my MiniB3D bindings out tonight with an example.
Excellent work gman. Looking forward to giving this a go.
this is just an initial design, but it shows some of the possibilities. this builds off the animator MiniB3D addition i posted earlier. again no modifications to MiniB3D. save this to a file called animator.bmx in the same directory as MiniB3D.bmx.
now for an implementation. again, this is based on the MiniB3D test-alpha.bmx program. save the following code into test-alpha_anim.bmx in the same directory as test-alpha.bmx
in the animator.bmx code, there are two new types, one is a interface type meant to be extended. ICollisionAdapter provides a means to store the collision data with the mesh. due to it being an actual child of the mesh, when the parents matrix is updated so is the childs. i use this to create an event. the implementation uses this event to update the model collision transformation.
the second type is the implementation of ICollisionAdapter i called TColDetCollisionAdapter. it acutally implements the creation of the collision data, the updating of the collision matrix, and the checking for a collision.
NOTE: be sure to run this in debug mode. 2 reasons, first, for some reason you will get an unhandle mem error at the first collision. im not sure why but im waiting till the next version of MiniB3D to check it out. ive manually tested outside of MiniB3D and it seems to work fine in debug or runtime. second, you will see the debug output when the collisions occur. you will see the millisecs, followed by the names of the two entities that collided.
this is very basic stuff but it does show a simple collision detection implementation.
enjoy :)
one more time, a big THANK YOU to simonh. cant wait for v0.3!
Import "MiniB3D.bmx" Import Pub.ColDet ' animator.bmx Type IEntityAnimator Extends TMesh Const ORDER_BASE:Int=999999 Method Update() Local entity:TEntity=GetParent() If entity Then AnimateEntity(entity,MilliSecs()) Else DebugLog("IEntityAnimator: No Entity") EndMethod ' called each update to animate an entity Method AnimateEntity(entity:TEntity,timeMS:Int) Abstract EndType Type TColDetCollisionAdapter Extends ICollisionAdapter Field model:TCollisionModel3D=Null Method New() model=New TCollisionModel3D EndMethod Function EntityAddAdapter(entity:TEntity,order:Int=0) Local coll:TColDetCollisionAdapter=TColDetCollisionAdapter.Create(entity) ' set the order so the animator update is called before the update to the entity EntityOrder(coll,(ORDER_BASE-order)) EndFunction Function create:TColDetCollisionAdapter(parent_ent:TEntity) If Not TMesh(parent_ent) Then RuntimeError "TColDetCollisionAdapter.create(): invalid entity passed" Local coll:TColDetCollisionAdapter=New TColDetCollisionAdapter coll.class$="TColDetCollisionAdapter" coll.AddParent(parent_ent) coll.EntityListAdd(entity_list) ' update matrix If coll.parent<>Null coll.mat.Overwrite(coll.parent.mat) coll.UpdateMat() Else coll.UpdateMat(True) EndIf ' populate the collision model with triangles coll.FillCollisionModel() Return coll EndFunction ' populates the collision model with the mesh triangles Method FillCollisionModel() Local entity:TMesh=TMesh(getParent()) ' loop through each surface For Local s:Int=1 To entity.CountSurfaces() Local surf:TSurface=entity.GetSurface(s) ' loop through each triangle of the surface For Local t:Int=1 To surf.CountTriangles() ' add each triangle to the collision model model.addTriangle( .. surf.VertexX(surf.TriangleVertex(t,0)), .. surf.VertexY(surf.TriangleVertex(t,0)), .. surf.VertexZ(surf.TriangleVertex(t,0)), .. surf.VertexX(surf.TriangleVertex(t,1)), .. surf.VertexY(surf.TriangleVertex(t,1)), .. surf.VertexZ(surf.TriangleVertex(t,1)), .. surf.VertexX(surf.TriangleVertex(t,2)), .. surf.VertexY(surf.TriangleVertex(t,2)), .. surf.VertexZ(surf.TriangleVertex(t,2))) Next Next ' finalize the model model.finalize() EndMethod Method OnUpdate(entity:TEntity) ' check for a collision For Local mesh:TEntity=EachIn TEntity.entity_list If mesh<>Self And mesh.class="TColDetCollisionAdapter" If model.Collision(TColDetCollisionAdapter(mesh).model) DebugLog(MilliSecs()+": "+entity.EntityName()+" hit "+mesh.getParent().EntityName()) EndIf EndIf Next EndMethod ' because this is a child, this gets called every time the parent is updated Method OnUpdateMat(entity:TEntity) ' update the model transformation with the parents matrix model.setTransform(entity.mat.grid) EndMethod ' Method OnFreeEntity(entity:TEntity) EndMethod EndType ' collision adapter for entity ' this is meant to store/update collision info for an entity and also to ' allow cleanup via the free entity ' needs to fire after the animators but before the entitys so ORDER_BASE is 10000 lower Type ICollisionAdapter Extends TMesh Const ORDER_BASE:Int=989999 Method Update() Local entity:TEntity=GetParent() If entity Then OnUpdate(entity) Else DebugLog("ICollisionAdapter: No Entity") EndMethod Method UpdateMat(load_identity:Int=False) Local entity:TEntity=GetParent() If entity Then OnUpdateMat(entity) Else DebugLog("ICollisionAdapter: No Entity") EndMethod Method FreeEntity() Local entity:TEntity=GetParent() If entity Then OnFreeEntity(entity) Else DebugLog("ICollisionAdapter: No Entity") EndMethod Method OnUpdate(entity:TEntity) Abstract ' this updates when the entity updates Method OnUpdateMat(entity:TEntity) Abstract Method OnFreeEntity(entity:TEntity) Abstract EndType
now for an implementation. again, this is based on the MiniB3D test-alpha.bmx program. save the following code into test-alpha_anim.bmx in the same directory as test-alpha.bmx
Import "../MiniB3D.bmx" Import BRL.PNGLoader Import "../animator.bmx" Local width=640,height=480,depth=16,mode=0 Graphics3D width,height,depth,mode Local cam=CreateCamera() Local light=CreateLight() Local ent1=CreateCube() Local tex=LoadTexture("media/test.png") EntityTexture ent1,tex Local ent2=CopyEntity(ent1) Local ent3=CopyEntity(ent1) Local ent4=CopyEntity(ent1) Local ent5=CopyEntity(ent1) Local ent6=CopyEntity(ent1) ' ----------------------------- ' add a controller to the cam. this could just as easily ' be added to one of the cubes ' ----------------------------- TCameraController.EntityAddAnimator(cam,0) ' ----------------------------- ' ----------------------------- ' create simple rotation animators and add them to ' ents 1-4 ' ----------------------------- TSimpleRotateAnimator.EntityAddAnimator(ent1,.5) TSimpleRotateAnimator.EntityAddAnimator(ent2,-.5) TSimpleRotateAnimator.EntityAddAnimator(ent3,1) TSimpleRotateAnimator.EntityAddAnimator(ent4,-1) NameEntity(ent1,"ent1") NameEntity(ent2,"ent2") NameEntity(ent3,"ent3") NameEntity(ent4,"ent4") NameEntity(ent5,"ent5") NameEntity(ent6,"ent6") ' add some collision detection to all the boxes TColDetCollisionAdapter.EntityAddAdapter(ent1) TColDetCollisionAdapter.EntityAddAdapter(ent2) TColDetCollisionAdapter.EntityAddAdapter(ent3) TColDetCollisionAdapter.EntityAddAdapter(ent4) TColDetCollisionAdapter.EntityAddAdapter(ent5) TColDetCollisionAdapter.EntityAddAdapter(ent6) ' ----------------------------- PositionEntity ent1,0,0,10 PositionEntity ent2,0,0,5 PositionEntity ent3,0,0,20 PositionEntity ent4,0,0,15 PositionEntity ent5,0,0,30 PositionEntity ent6,0,0,25 EntityAlpha ent2,0.5 EntityAlpha ent4,0.5 Local cx#=0 Local cy#=0 Local cz#=0 Local pitch#=0 Local yaw#=0 Local roll#=0 ' used by fps code Local old_ms=MilliSecs() Local renders Local fps While Not KeyDown(KEY_ESCAPE) If KeyHit(KEY_ENTER) Then DebugStop RenderWorld renders=renders+1 ' calculate fps If MilliSecs()-old_ms>=1000 old_ms=MilliSecs() fps=renders renders=0 EndIf GLDrawText "FPS: "+String(fps),0,0 PositionEntity(ent2,0,0,EntityZ(ent2)+.01) Flip ' problem with freeentity 'FreeEntity(ent6) Wend End ' ----------------------------- ' begin the animator types ' ----------------------------- ' conrols a camera (or potentially any entity) via keyboard ' arrows UP/DOWN/LEFT/RIGHT and keys W/A/S/D Type TCameraController Extends IEntityAnimator Field cx#=0 Field cy#=0 Field cz#=0 Field pitch#=0 Field yaw#=0 Field roll#=0 Method AnimateEntity(entity:TEntity,timeMS:Int) ' control camera If KeyDown(KEY_UP) Then cz#=cz#+1.0 If KeyDown(KEY_LEFT) Then cx#=cx#-1.0 If KeyDown(KEY_RIGHT) Then cx#=cx#+1.0 If KeyDown(KEY_DOWN) Then cz#=cz#-1.0 If KeyDown(KEY_W) Then pitch#=pitch#-1.0 If KeyDown(KEY_A) Then yaw#=yaw#+1.0 If KeyDown(KEY_S) Then pitch#=pitch#+1.0 If KeyDown(KEY_D) Then yaw#=yaw#-1.0 entity.MoveEntity(cx#*0.5,cy#*0.5,cz#*0.5) entity.RotateEntity(pitch#,yaw#,roll#) cx#=0 cy#=0 cz#=0 EndMethod Function EntityAddAnimator(entity:TEntity,order:Int=0) Local anim:TCameraController=TCameraController.Create(entity) ' set the order so the animator update is called before the update to the entity EntityOrder(anim,(ORDER_BASE-order)) EndFunction Function create:TCameraController(parent_ent:TEntity) Local piv:TCameraController=New TCameraController piv.class$="TCameraController" piv.AddParent(parent_ent) piv.EntityListAdd(entity_list) ' update matrix If piv.parent<>Null piv.mat.Overwrite(piv.parent.mat) piv.UpdateMat() Else piv.UpdateMat(True) EndIf Return piv EndFunction EndType Type TSimpleRotateAnimator Extends IEntityAnimator Field rate:Float Method AnimateEntity(entity:TEntity,timeMS:Int) entity.TurnEntity(0,rate,0) EndMethod Function EntityAddAnimator(entity:TEntity,rate:Float,order:Int=0) Local anim:TSimpleRotateAnimator=TSimpleRotateAnimator.Create(entity) anim.rate=rate ' set the order so the animator update is called before the update to the entity EntityOrder(anim,(ORDER_BASE-order)) EndFunction Function create:TSimpleRotateAnimator(parent_ent:TEntity) Local piv:TSimpleRotateAnimator=New TSimpleRotateAnimator piv.class$="TSimpleRotateAnimator" piv.AddParent(parent_ent) piv.EntityListAdd(entity_list) ' update matrix If piv.parent<>Null piv.mat.Overwrite(piv.parent.mat) piv.UpdateMat() Else piv.UpdateMat(True) EndIf Return piv EndFunction EndType ' ----------------------------- ' -----------------------------
in the animator.bmx code, there are two new types, one is a interface type meant to be extended. ICollisionAdapter provides a means to store the collision data with the mesh. due to it being an actual child of the mesh, when the parents matrix is updated so is the childs. i use this to create an event. the implementation uses this event to update the model collision transformation.
the second type is the implementation of ICollisionAdapter i called TColDetCollisionAdapter. it acutally implements the creation of the collision data, the updating of the collision matrix, and the checking for a collision.
NOTE: be sure to run this in debug mode. 2 reasons, first, for some reason you will get an unhandle mem error at the first collision. im not sure why but im waiting till the next version of MiniB3D to check it out. ive manually tested outside of MiniB3D and it seems to work fine in debug or runtime. second, you will see the debug output when the collisions occur. you will see the millisecs, followed by the names of the two entities that collided.
this is very basic stuff but it does show a simple collision detection implementation.
enjoy :)
one more time, a big THANK YOU to simonh. cant wait for v0.3!
Would it be possible to produce a version of your ColDet module that does not require a dll? I try to avoid using dlls whenever possible, as they always have potential for causing problems when the program is terminated, and they are a nuisance to have to include with my engine.
Would it be possible to produce a version of your ColDet module that does not require a dll?
Uh... <NoelCower> I need someone to do something for me, and it's very important
<NoelCower> Post on bb.com telling gman that his coldet module requires all code that uses it to be open source
<NoelCower> Due to the viral nature of the LGPL when using static linking
<NoelCower> In short, he's statically linking to LGPL'd source code when he has to make an import library that makes use of a DLL
<NoelCower> Otherwise people have to release any and all code using the module
<NoelCower> Under the LGPL no less
No?<NoelCower> Post on bb.com telling gman that his coldet module requires all code that uses it to be open source
<NoelCower> Due to the viral nature of the LGPL when using static linking
<NoelCower> In short, he's statically linking to LGPL'd source code when he has to make an import library that makes use of a DLL
<NoelCower> Otherwise people have to release any and all code using the module
<NoelCower> Under the LGPL no less
Unless Leadwerks Engine goes open source ;)
The author will probably give me permission to statically link it if I explain it to them.
I have the Newton version and the ColDet version implemented side by side. But ColDet doesn't work. Here I am trying to perform a raycast between point 0 and point 1. The parameters for the raycast method are very confusing. I don't know if the direction is supposed to be normalized or what:
I have the Newton version and the ColDet version implemented side by side. But ColDet doesn't work. Here I am trying to perform a raycast between point 0 and point 1. The parameters for the raycast method are very confusing. I don't know if the direction is supposed to be normalized or what:
Method ColDetRayCast:Int(p0:TVec3,p1:TVec3,position:TVec3,normal:TVec3,radius:Float=0.0,closest=True) Global direction:Float[3] If Not collisionmodel Return direction[0]=p1.x-p0.x direction[1]=p1.y-p0.y direction[2]=p1.z-p0.z Local m#=NormalizeVec3(direction,direction) If collisionmodel.rayCollision:Int(Varptr p0.x,direction,closest,0,m) collisionmodel.getCollisionPoint(Varptr position.x) Notify position.tostring() Return 1 Else Return 0 EndIf EndMethod
I got coldet working right, but it treats triangles as if they are two-sided. Is there a way to disable this?
Maybe try the coldet forums.
They are defunct.