Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Coumans <blender@erwincoumans.com>2005-08-05 21:00:32 +0400
committerErwin Coumans <blender@erwincoumans.com>2005-08-05 21:00:32 +0400
commitb6d9fbf0dbe44efee9309f09bc1a518a2cd67813 (patch)
tree43aaf1f693bec9849914001b9cf1fd1dce185de1
parent0f044af97ef785f73e0aa2188716dcafd0c0d54e (diff)
fixed the mouse-over sensor,
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 :)
-rw-r--r--extern/bullet/Bullet/CollisionShapes/BoxShape.cpp2
-rw-r--r--extern/bullet/Bullet/CollisionShapes/CylinderShape.h17
-rw-r--r--extern/bullet/BulletDynamics/CollisionDispatch/ConvexConvexAlgorithm.cpp11
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.cpp17
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h1
-rw-r--r--extern/bullet/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp55
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp22
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp16
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp186
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_RayCast.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp3
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp17
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp55
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;
}