diff options
17 files changed, 304 insertions, 115 deletions
diff --git a/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp index 1cc62263603..98f2a3d5444 100644 --- a/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp +++ b/extern/bullet/Bullet/CollisionShapes/BoxShape.cpp @@ -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; diff --git a/extern/bullet/Bullet/CollisionShapes/CylinderShape.h b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h index d60bacff962..11f184db761 100644 --- a/extern/bullet/Bullet/CollisionShapes/CylinderShape.h +++ b/extern/bullet/Bullet/CollisionShapes/CylinderShape.h @@ -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 diff --git a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp index 7be5ff4d145..9450eb2e845 100644 --- a/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp +++ b/extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp @@ -34,6 +34,11 @@ #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); diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp index f4634668296..f1f7ba2c1d2 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp @@ -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; } diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h index e0cba58cb53..8c87940721a 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h @@ -51,6 +51,7 @@ class CcdPhysicsController : public PHY_IPhysicsController RigidBody* m_body; class PHY_IMotionState* m_MotionState; CollisionShape* m_collisionShape; + void* m_newClientInfo; public: diff --git a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp index aac699468d0..fa3253003fc 100644 --- a/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp +++ b/extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp @@ -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; } diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index b7b384f25e1..e6b85e3f42a 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -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) diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index cf231adfd2a..e38ff77f76e 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -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 diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 6028efe86ee..53fd0db08d0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -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); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 6e2c8a3d5d7..ee12efec684 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -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; + } } } diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 7441863b7b7..af24627f8fe 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -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" diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index d92cebfb4e1..ff69c570d53 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -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. */ diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp index fa8a04c0780..7b13cb1fd7d 100644 --- a/source/gameengine/Ketsji/KX_RayCast.cpp +++ b/source/gameengine/Ketsji/KX_RayCast.cpp @@ -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(); diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index fa5f5215aa4..73eb95d606e 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -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; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index f4634668296..f1f7ba2c1d2 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index e0cba58cb53..8c87940721a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -51,6 +51,7 @@ class CcdPhysicsController : public PHY_IPhysicsController RigidBody* m_body; class PHY_IMotionState* m_MotionState; CollisionShape* m_collisionShape; + void* m_newClientInfo; public: diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index aac699468d0..fa3253003fc 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -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; } |