author Erwin Coumans Fri, 5 Aug 2005 17:00:32 +0000 (17:00 +0000) committer Erwin Coumans Fri, 5 Aug 2005 17:00:32 +0000 (17:00 +0000)
added raycast support for bullet (no triangle-mesh support, soon)
added python methods for 'getHitObject', getRayDirection, getHitPosition and getHitNormal for mouse over sensor,
which makes it easy for a shootout.blend demo :)

17 files changed:

index 1cc6226360354b38d2826f4c2f41b1fb56c9482f..98f2a3d54448a399f9e28888bd553a065db57fd9 100644 (file)
@@ -31,7 +31,7 @@ void BoxShape::GetAabb(const SimdTransform& t,SimdVector3& aabbMin,SimdVector3&

//todo: this is a quick fix, we need to enlarge the aabb dependent on several criteria
-       //extent += SimdVector3(.2f,.2f,.2f);
+       extent += SimdVector3(.2f,.2f,.2f);

aabbMin = center - extent;
aabbMax = center + extent;
index d60bacff9628e1604146565fc11d4121fa53a282..11f184db761cb0a783b342484620053aa7c7a73c 100644 (file)
@@ -27,7 +27,24 @@ public:

virtual SimdVector3     LocalGetSupportingVertexWithoutMargin(const SimdVector3& vec)const;

+       virtual SimdVector3     LocalGetSupportingVertex(const SimdVector3& vec) const
+       {

+               SimdVector3 supVertex;
+               supVertex = LocalGetSupportingVertexWithoutMargin(vec);
+
+               if ( GetMargin()!=0.f )
+               {
+                       SimdVector3 vecnorm = vec;
+                       if (vecnorm .length2() == 0.f)
+                       {
+                               vecnorm.setValue(-1.f,-1.f,-1.f);
+                       }
+                       vecnorm.normalize();
+                       supVertex+= GetMargin() * vecnorm;
+               }
+               return supVertex;
+       }

//use box inertia
index 7be5ff4d1455309e14b7b20296ebcfce8bc5733f..9450eb2e845dfb54f2fc6de2e6a75bb19209edef 100644 (file)

#include "NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.h"

+///Solid3EpaPenetrationDepth is not shipped by default, the license doesn't allow commercial, closed source. contact if you want the file
+///It improves the penetration depth handling dramatically
+#ifdef USE_EPA
+#include "NarrowPhaseCollision/Solid3EpaPenetrationDepth.h"
+#endif// USE_EPA

#ifdef WIN32
void DrawRasterizerLine(const float* from,const float* to,int color);
@@ -136,8 +141,10 @@ void       ConvexConvexAlgorithm::CheckPenetrationDepthSolver()
m_useEpa  = gUseEpa;
if (m_useEpa)
{
-                       //not distributed
-                       //m_gjkPairDetector.SetPenetrationDepthSolver(new Solid3EpaPenetrationDepth);
+                       //not distributed, see top of this file
+                       #ifdef USE_EPA
+                       m_gjkPairDetector.SetPenetrationDepthSolver(new Solid3EpaPenetrationDepth);
+                       #endif
} else
{
m_gjkPairDetector.SetPenetrationDepthSolver(new MinkowskiPenetrationDepthSolver);
index f46346682965ff42cc717918e2f03f0c8a56dbe5..f1f7ba2c1d21bc02e672355bb43a60546bab25ab 100644 (file)
@@ -18,7 +18,7 @@ SimdVector3 startVel(0,0,0);//-10000);
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
{
m_collisionDelay = 0;
-
+       m_newClientInfo = 0;

m_MotionState = ci.m_MotionState;

@@ -163,6 +163,17 @@ void               CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa
}
void           CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
{
+       printf("CcdPhysicsController::applyImpulse\n");
+
+       SimdVector3 impulse(impulseX,impulseY,impulseZ);
+       SimdVector3 pos(attachX,attachY,attachZ);
+
+       //it might be sleeping... wake up !
+       m_body->SetActivationState(1);
+       m_body->m_deactivationTime = 0.f;
+
+       m_body->applyImpulse(impulse,pos);
+
}
void           CcdPhysicsController::SetActive(bool active)
{
@@ -186,11 +197,11 @@ void              CcdPhysicsController::setRigidBody(bool rigid)
// clientinfo for raycasts for example
void*          CcdPhysicsController::getNewClientInfo()
{
-       return 0;
+       return m_newClientInfo;
}
void           CcdPhysicsController::setNewClientInfo(void* clientinfo)
{
-
+       m_newClientInfo = clientinfo;
}

index e0cba58cb534cfcb7368c7bd74519a7eea9eddee..8c87940721a9a8a5591e7cb1b833bddf11b81b58 100644 (file)
@@ -51,6 +51,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
RigidBody* m_body;
class   PHY_IMotionState*                       m_MotionState;
CollisionShape*                 m_collisionShape;
+       void*           m_newClientInfo;

public:

index aac699468d0262b3da3838699a08ca4920aa14fe..fa3253003fc0947d163a23a645edebd46aa75726 100644 (file)
@@ -16,6 +16,8 @@

#include "IDebugDraw.h"

+#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
+#include "NarrowPhaseCollision/SubsimplexConvexCast.h"

#include "CollisionDispatch/ToiContactDispatcher.h"

@@ -24,6 +26,7 @@
#include "CollisionDispatch/UnionFind.h"

#include "NarrowPhaseCollision/RaycastCallback.h"
+#include "CollisionShapes/SphereShape.h"

bool useIslands = true;

@@ -678,6 +681,7 @@ void        CcdPhysicsEnvironment::SyncMotionStates(float timeStep)
//
// synchronize the physics and graphics transformations
//
+
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
@@ -856,9 +860,56 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
{

+       int minFraction = 1.f;

-       return 0;
+       SimdTransform   rayFromTrans,rayToTrans;
+       rayFromTrans.setIdentity();
+       rayFromTrans.setOrigin(SimdVector3(fromX,fromY,fromZ));
+       rayToTrans.setIdentity();
+       rayToTrans.setOrigin(SimdVector3(toX,toY,toZ));
+
+
+       CcdPhysicsController* nearestHit = 0;
+
+       std::vector<CcdPhysicsController*>::iterator i;
+       SphereShape pointShape(0.0f);
+
+       /// brute force go over all objects. Once there is a broadphase, use that, or
+       /// add a raycast against aabb first.
+       for (i=m_controllers.begin();
+       !(i==m_controllers.end()); i++)
+       {
+               CcdPhysicsController* ctrl = (*i);
+               RigidBody* body = ctrl->GetRigidBody();
+
+               if (body->GetCollisionShape()->IsConvex())
+               {
+                       ConvexCast::CastResult rayResult;
+                       rayResult.m_fraction = 1.f;
+
+                       ConvexShape* convexShape = (ConvexShape*) body->GetCollisionShape();
+                       VoronoiSimplexSolver    simplexSolver;
+                       SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
+                       if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,body->getCenterOfMassTransform(),body->getCenterOfMassTransform(),rayResult))
+                       {
+                               rayResult.m_normal.normalize();
+                               if (rayResult.m_fraction < minFraction)
+                               {
+                                       minFraction = rayResult.m_fraction;
+                                       nearestHit = ctrl;
+                                       normalX = rayResult.m_normal.getX();
+                                       normalY = rayResult.m_normal.getY();
+                                       normalZ = rayResult.m_normal.getZ();
+                                       hitX = rayResult.m_hitTransformA.getOrigin().getX();
+                                       hitY = rayResult.m_hitTransformA.getOrigin().getY();
+                                       hitZ = rayResult.m_hitTransformA.getOrigin().getZ();
+                               }
+                       }
+               }
+       }
+
+       return nearestHit;
}

index b7b384f25e12feac347631f7275dc5599f64fd1e..e6b85e3f42ac22ce727114a7d8e7f8c5e702d27f 100644 (file)
@@ -32,6 +32,8 @@ void  KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float l

void   KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)
{
+               CcdPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]);
+
}

void   KX_BulletPhysicsController::SetObject (SG_IObject* object)
@@ -33,7 +33,7 @@
#define KX_CONVERTPHYSICSOBJECTS

/* These are defined by the build system... */
-//#define USE_SUMO_SOLID
+#define USE_SUMO_SOLID
//#define USE_ODE

//on visual studio 7/8, always enable BULLET for now
@@ -917,7 +917,6 @@ void        KX_ConvertBulletObject( class   KX_GameObject* gameobj,

bm = new BoxShape(he);
bm->CalculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-                       bm->SetMargin(0.05 * halfExtents.length());
break;
};
case KX_BOUNDCYLINDER:
@@ -947,8 +946,6 @@ void        KX_ConvertBulletObject( class   KX_GameObject* gameobj,
bm->CalculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);

-
-
break;
}
case KX_BOUNDPOLYTOPE:
@@ -998,24 +995,33 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
if (!bm)
return;

+       bm->SetMargin(0.06);
+
ci.m_collisionShape = bm;
ci.m_friction = smmaterial->m_friction;
ci.m_restitution = smmaterial->m_restitution;

-
-       ci.m_linearDamping = shapeprops->m_lin_drag;
-       ci.m_angularDamping = shapeprops->m_ang_drag;
+       // drag / damping is inverted
+       ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
+       ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
+       //need a bit of damping, else system doesn't behave well
+

KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,dyna);

gameobj->SetPhysicsController(physicscontroller);
-       physicscontroller->setNewClientInfo(gameobj);
+       physicscontroller->setNewClientInfo(gameobj->getClientInfo());
+       bool isActor = objprop->m_isactor;
+       gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
+       // store materialname in auxinfo, needed for touchsensors
+       gameobj->getClientInfo()->m_auxilary_info = 0;//(matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
+
+

-       bool isActor = objprop->m_isactor;
STR_String materialname;
if (meshobj)
materialname = meshobj->GetMaterialName(0);
@@ -953,16 +953,26 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self,

PyObject* pyattach;
PyObject* pyimpulse;
+
+       printf("impulse1\n");
+

if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse))
{
MT_Point3  attach;
MT_Vector3 impulse;
+               printf("impulse2\n");

-               if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse) && m_pPhysicsController1)
+               if (m_pPhysicsController1)
{
-                       m_pPhysicsController1->applyImpulse(attach, impulse);
-                       Py_Return;
+                               printf("impulse3\n");
+
+                       if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
+                       {
+                               printf("impulse4\n");
+                               m_pPhysicsController1->applyImpulse(attach, impulse);
+                               Py_Return;
+                       }
}

}
@@ -76,6 +76,8 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
* together, so it should be safe to do it here. */
m_mouse_over_in_previous_frame = false;
m_positive_event = false;
+       m_hitObject = 0;
+
}

bool KX_MouseFocusSensor::Evaluate(CValue* event)
@@ -132,8 +134,9 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, MT_Point3& hi
* self-hits are excluded by setting the correct ignore-object.)
* Hitspots now become valid. */
KX_GameObject* thisObj = (KX_GameObject*) GetParent();
-       if (hitKXObj == thisObj)
+       if (hitKXObj != thisObj)
{
+               m_hitObject = hitKXObj;
m_hitPosition = hit_point;
m_hitNormal = hit_normal;
return true;
@@ -267,97 +270,18 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
/* Shoot! Beware that the first argument here is an
* ignore-object. We don't ignore anything... */

-       KX_IPhysicsController* physics_controller = (cam->GetPhysicsController());
+       KX_IPhysicsController* physics_controller = cam->GetPhysicsController();
PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment();

-//     MT_Vector3 todir = topoint3 - frompoint3;
-//     if (todir.dot(todir) < MT_EPSILON)
-//             return false;
-//     todir.normalize();
-
-       KX_RayCast::RayTest(physics_controller, physics_environment, frompoint3, topoint3, resultpoint, resultnormal, KX_RayCast::Callback<KX_MouseFocusSensor>(this));
-
+       bool result = false;
+
+       result = KX_RayCast::RayTest(physics_controller, physics_environment, frompoint3, topoint3, resultpoint, resultnormal, KX_RayCast::Callback<KX_MouseFocusSensor>(this));
+       if (result)
+       {
+
+       }
+       return result;

-//     while (true)
-//     {
-//             PHY__Vector3 resultpt;
-//             PHY__Vector3 resultnr;
-//
-//             PHY_IPhysicsController* hitCtrl= physEnv->rayTest(camCtrl,
-//                                                     frompoint3.x(),frompoint3.y(),frompoint3.z(),
-//                                                     topoint3.x(),topoint3.y(),topoint3.z(),
-//                                                     resultpt[0], resultpt[1],resultpt[2],
-//                                                     resultnr[0],resultnr[1],resultnr[2]);
-//
-//             if (!hitCtrl)
-//                     return false;
-//
-//             resultpoint = MT_Vector3(resultpt);
-//             resultnormal = MT_Vector3(resultnr);
-//
-//             /* all this casting makes me nervous... */
-//             KX_ClientObjectInfo* client_info
-//                     =       static_cast<KX_ClientObjectInfo*>( hitCtrl->getNewClientInfo());
-//
-//             if (!client_info)
-//             {
-//                     std::cout<< "WARNING:  MouseOver sensor " << GetName() << " cannot sense - no client info.\n" << std::endl;
-//
-//                     return false;
-//             }
-//
-//             KX_GameObject* hitKXObj = client_info->m_gameobject;
-//
-//             if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
-//             {
-//                     // false hit
-//                     // FIXME: add raytest interface to KX_IPhysicsController, remove casting
-//                     PHY_IPhysicsController* hitspc = (PHY_IPhysicsController*) (static_cast<KX_GameObject*> (hitKXObj)->GetPhysicsController());
-//                     if (hitspc)
-//                     {
-//                             /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
-//                             MT_Scalar marg = 0.01 + hitspc->GetMargin();
-//                             marg += hitspc->GetRadius(); //this is changed, check !
-//
-//                             //if (hitspc->GetSumoObject()->getShapeProps())
-//                             //{
-//                             //}
-//
-//                             /* Calculate the other side of this object */
-//                             MT_Point3 hitObjPos;
-//                             PHY__Vector3 hitpos;
-//                             hitspc->getPosition(hitpos);
-//                             hitObjPos = MT_Vector3(hitpos);
-//                             MT_Vector3 hitvector = hitObjPos - resultpoint;
-//                             if (hitvector.dot(hitvector) > MT_EPSILON)
-//                             {
-//                                     hitvector.normalize();
-//                                     marg *= 2.*todir.dot(hitvector);
-//                             }
-//                             frompoint3 = resultpoint + marg * todir;
-//                     } else {
-//                             return false;
-//                     }
-//                     continue;
-//             }
-//             /* Is this me? In the ray test, there are a lot of extra checks
-//             * for aliasing artefacts from self-hits. That doesn't happen
-//             * here, so a simple test suffices. Or does the camera also get
-//             * self-hits? (No, and the raysensor shouldn't do it either, since
-//             * self-hits are excluded by setting the correct ignore-object.)
-//             * Hitspots now become valid. */
-//             if (hitKXObj == thisObj)
-//             {
-//                     m_hitPosition = resultpoint;
-//                     m_hitNormal = resultnormal;
-//                     return true;
-//             }
-//
-//             return false;
-//     }
-
-       return false;
}

/* ------------------------------------------------------------------------- */
@@ -398,6 +322,12 @@ PyMethodDef KX_MouseFocusSensor::Methods[] = {
METH_VARARGS, GetRayTarget_doc},
{"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource,
METH_VARARGS, GetRaySource_doc},
+       {"getHitObject",(PyCFunction) KX_MouseFocusSensor::sPyGetHitObject,METH_VARARGS, GetHitObject_doc},
+       {"getHitPosition",(PyCFunction) KX_MouseFocusSensor::sPyGetHitPosition,METH_VARARGS, GetHitPosition_doc},
+       {"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_VARARGS, GetHitNormal_doc},
+       {"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_VARARGS, GetRayDirection_doc},
+
+
{NULL,NULL} //Sentinel
};

@@ -405,6 +335,84 @@ PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) {
_getattr_up(SCA_MouseSensor);
}

+
+char KX_MouseFocusSensor::GetHitObject_doc[] =
+"getHitObject()\n"
+"\tReturns the name of the object that was hit by this ray.\n";
+PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self,
+                                                                                  PyObject* args,
+                                                                                  PyObject* kwds)
+{
+       if (m_hitObject)
+       {
+               printf("hitObject!\n");
+       }
+       Py_Return;
+}
+
+
+char KX_MouseFocusSensor::GetHitPosition_doc[] =
+"getHitPosition()\n"
+"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
+PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self,
+                              PyObject* args,
+                              PyObject* kwds)
+{
+
+       MT_Point3 pos = m_hitPosition;
+
+       PyObject* resultlist = PyList_New(3);
+       int index;
+       for (index=0;index<3;index++)
+       {
+               PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+       }
+       return resultlist;
+
+}
+
+char KX_MouseFocusSensor::GetRayDirection_doc[] =
+"getRayDirection()\n"
+"\tReturns the direction from the ray (in worldcoordinates) .\n";
+PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self,
+                              PyObject* args,
+                              PyObject* kwds)
+{
+
+       MT_Vector3 dir = m_prevTargetPoint - m_prevSourcePoint;
+       dir.normalize();
+
+       PyObject* resultlist = PyList_New(3);
+       int index;
+       for (index=0;index<3;index++)
+       {
+               PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index]));
+       }
+       return resultlist;
+
+}
+
+char KX_MouseFocusSensor::GetHitNormal_doc[] =
+"getHitNormal()\n"
+"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
+PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self,
+                              PyObject* args,
+                              PyObject* kwds)
+{
+       MT_Vector3 pos = m_hitNormal;
+
+       PyObject* resultlist = PyList_New(3);
+       int index;
+       for (index=0;index<3;index++)
+       {
+               PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
+       }
+       return resultlist;
+
+}
+
+
/*  getRayTarget                                                */
char KX_MouseFocusSensor::GetRayTarget_doc[] =
"getRayTarget()\n"
index d92cebfb4e16b01fb4259ee607292a5af5f90deb..ff69c570d53b5454a7d1eaf2533d9ea980ff52fd 100644 (file)
@@ -88,6 +88,11 @@ class KX_MouseFocusSensor : public SCA_MouseSensor

KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayTarget);
KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRaySource);
+
+       KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitObject);
+       KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitPosition);
+       KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitNormal);
+       KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayDirection);

/* --------------------------------------------------------------------- */

@@ -133,6 +138,9 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
* the object was hit.  */
MT_Vector3               m_hitNormal;

+       class SCA_IObject*      m_hitObject;
+
+
/**
* Ref to the engine, for retrieving a reference to the current
* scene.  */
index fa8a04c0780b3727947c77a25f01fdb9171dafd9..7b13cb1fd7da580e3ea51bbdde9406bf6f38935f 100644 (file)
@@ -69,13 +69,15 @@ bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsE

if (!info)
{
+                       printf("no info!\n");
MT_assert(info && "Physics controller with no client object info");
return false;
}

if (callback.RayHit(info, result_point, result_normal))
return true;
-
+
+
// skip past the object and keep tracing
/* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
MT_Scalar marg = 0.01 + hit_controller->GetMargin();
index fa5f5215aa427d058c21238a096aaa72ae92dffa..73eb95d606ef2f3694ccf6f50df36be8d7540ecd 100644 (file)
@@ -106,10 +106,13 @@ bool KX_RaySensor::IsPositiveTrigger()

bool KX_RaySensor::RayHit(KX_ClientObjectInfo* info, MT_Point3& hit_point, MT_Vector3& hit_normal, void* const data)
{
+       printf("KX_RaySensor::RayHit\n");
+
KX_GameObject* obj = (KX_GameObject*)GetParent();
SCA_IObject *hitgameobj = info->m_gameobject;
if (hitgameobj == obj || info->m_type > KX_ClientObjectInfo::ACTOR)
{
+               printf("false hit\n");
// false hit
return false;
}
index f46346682965ff42cc717918e2f03f0c8a56dbe5..f1f7ba2c1d21bc02e672355bb43a60546bab25ab 100644 (file)
@@ -18,7 +18,7 @@ SimdVector3 startVel(0,0,0);//-10000);
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
{
m_collisionDelay = 0;
-
+       m_newClientInfo = 0;

m_MotionState = ci.m_MotionState;

@@ -163,6 +163,17 @@ void               CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa
}
void           CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
{
+       printf("CcdPhysicsController::applyImpulse\n");
+
+       SimdVector3 impulse(impulseX,impulseY,impulseZ);
+       SimdVector3 pos(attachX,attachY,attachZ);
+
+       //it might be sleeping... wake up !
+       m_body->SetActivationState(1);
+       m_body->m_deactivationTime = 0.f;
+
+       m_body->applyImpulse(impulse,pos);
+
}
void           CcdPhysicsController::SetActive(bool active)
{
@@ -186,11 +197,11 @@ void              CcdPhysicsController::setRigidBody(bool rigid)
// clientinfo for raycasts for example
void*          CcdPhysicsController::getNewClientInfo()
{
-       return 0;
+       return m_newClientInfo;
}
void           CcdPhysicsController::setNewClientInfo(void* clientinfo)
{
-
+       m_newClientInfo = clientinfo;
}

index e0cba58cb534cfcb7368c7bd74519a7eea9eddee..8c87940721a9a8a5591e7cb1b833bddf11b81b58 100644 (file)
@@ -51,6 +51,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
RigidBody* m_body;
class   PHY_IMotionState*                       m_MotionState;
CollisionShape*                 m_collisionShape;
+       void*           m_newClientInfo;

public:

index aac699468d0262b3da3838699a08ca4920aa14fe..fa3253003fc0947d163a23a645edebd46aa75726 100644 (file)
@@ -16,6 +16,8 @@

#include "IDebugDraw.h"

+#include "NarrowPhaseCollision/VoronoiSimplexSolver.h"
+#include "NarrowPhaseCollision/SubsimplexConvexCast.h"

#include "CollisionDispatch/ToiContactDispatcher.h"

@@ -24,6 +26,7 @@
#include "CollisionDispatch/UnionFind.h"

#include "NarrowPhaseCollision/RaycastCallback.h"
+#include "CollisionShapes/SphereShape.h"

bool useIslands = true;

@@ -678,6 +681,7 @@ void        CcdPhysicsEnvironment::SyncMotionStates(float timeStep)
//
// synchronize the physics and graphics transformations
//
+
for (i=m_controllers.begin();
!(i==m_controllers.end()); i++)
{
@@ -856,9 +860,56 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
{

+       int minFraction = 1.f;

-       return 0;
+       SimdTransform   rayFromTrans,rayToTrans;
+       rayFromTrans.setIdentity();
+       rayFromTrans.setOrigin(SimdVector3(fromX,fromY,fromZ));
+       rayToTrans.setIdentity();
+       rayToTrans.setOrigin(SimdVector3(toX,toY,toZ));
+
+
+       CcdPhysicsController* nearestHit = 0;
+
+       std::vector<CcdPhysicsController*>::iterator i;
+       SphereShape pointShape(0.0f);
+
+       /// brute force go over all objects. Once there is a broadphase, use that, or
+       /// add a raycast against aabb first.
+       for (i=m_controllers.begin();
+       !(i==m_controllers.end()); i++)
+       {
+               CcdPhysicsController* ctrl = (*i);
+               RigidBody* body = ctrl->GetRigidBody();
+
+               if (body->GetCollisionShape()->IsConvex())
+               {
+                       ConvexCast::CastResult rayResult;
+                       rayResult.m_fraction = 1.f;
+
+                       ConvexShape* convexShape = (ConvexShape*) body->GetCollisionShape();
+                       VoronoiSimplexSolver    simplexSolver;
+                       SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
+                       if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,body->getCenterOfMassTransform(),body->getCenterOfMassTransform(),rayResult))
+                       {
+                               rayResult.m_normal.normalize();
+                               if (rayResult.m_fraction < minFraction)
+                               {
+                                       minFraction = rayResult.m_fraction;
+                                       nearestHit = ctrl;
+                                       normalX = rayResult.m_normal.getX();
+                                       normalY = rayResult.m_normal.getY();
+                                       normalZ = rayResult.m_normal.getZ();
+                                       hitX = rayResult.m_hitTransformA.getOrigin().getX();
+                                       hitY = rayResult.m_hitTransformA.getOrigin().getY();
+                                       hitZ = rayResult.m_hitTransformA.getOrigin().getZ();
+                               }
+                       }
+               }
+       }
+
+       return nearestHit;
}