fixed the mouse-over sensor,
authorErwin Coumans <blender@erwincoumans.com>
Fri, 5 Aug 2005 17:00:32 +0000 (17:00 +0000)
committerErwin Coumans <blender@erwincoumans.com>
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:
extern/bullet/Bullet/CollisionShapes/BoxShape.cpp
extern/bullet/Bullet/CollisionShapes/CylinderShape.h
extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h
extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_RayCast.cpp
source/gameengine/Ketsji/KX_RaySensor.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

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;
 
-//     m_broadphase->cast(
-       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))
+                       {
+                               //add hit
+                               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)
index cf231adfd2a4eec3b536de7ee1f1d601b7072ad1..e38ff77f76e88ac8e66634ced82d96bc357a662a 100644 (file)
@@ -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 
index 6028efe86ee926cb7ab76a97ada95fc3a932d174..53fd0db08d0168ef8d15b930ab20f9d93cf869a5 100644 (file)
@@ -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 = new ConeShape(objprop->m_boundobject.c.m_radius,objprop->m_boundobject.c.m_height);
                                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_broadphaseHandle = 0;
        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);
        env->addCcdPhysicsController( physicscontroller);
 
        
        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);
+
+
        gameobj->GetSGNode()->AddSGController(physicscontroller);
 
-       bool isActor = objprop->m_isactor;
        STR_String materialname;
        if (meshobj)
                materialname = meshobj->GetMaterialName(0);
index 6e2c8a3d5d773a7c051ad5eaa883c21dc9b44b4b..ee12efec684f1da83db47e5459811ce206d48864 100644 (file)
@@ -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;
+                       }
                }
 
        }
index 7441863b7b7b9fb6f58d3bb60cd03667c5851ebd..af24627f8fec63cadf95ad7741821e6693c9cc8f 100644 (file)
@@ -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())
-//                             //{
-//                             //      marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius;
-//                             //}
-//                             
-//                             /* 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");
+               return m_hitObject->AddRef();
+       }
+       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;
 
-//     m_broadphase->cast(
-       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))
+                       {
+                               //add hit
+                               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;
 }