From 720d4521cdd0986d9c6df97924b72eed72e5a3af Mon Sep 17 00:00:00 2001 From: Porteries Tristan Date: Wed, 7 Oct 2015 22:14:43 +0200 Subject: BGE : Collision mask support in raycast + and raycast cleanup. I have removed the m_pHitObject, m_xray and m_testPropName and replace them by a temporary struct "RayCastData" which contains these datas and a collision mask. Finally i add a collision mask argument in the python function "rayCast" : ``` rayCast(to, from, dist, prop, face, xray, poly, mask) ``` It can be useful to hit only object which are on the right colision layer. for example if you have hitbox for a charater or vehicle you don't want to hit it with raycast. test file : {F237337} left mouse click on two planes and see console messages. Somewhat more elaborate test file by @sybren: {F237779} Look around and click on the cubes. One cube lamp responds, the other doesn't, based on their collision groups. Reviewers: moguri, hg1, agoose77, campbellbarton, sybren Reviewed By: agoose77, campbellbarton, sybren Subscribers: campbellbarton, sergey, blueprintrandom, sybren Projects: #game_engine, #game_physics Differential Revision: https://developer.blender.org/D1239 --- .../rst/bge_types/bge.types.KX_GameObject.rst | 4 +- source/gameengine/Ketsji/KX_ConstraintActuator.cpp | 8 +- source/gameengine/Ketsji/KX_ConstraintActuator.h | 10 ++- source/gameengine/Ketsji/KX_GameObject.cpp | 88 ++++++++++++---------- source/gameengine/Ketsji/KX_GameObject.h | 18 +++-- source/gameengine/Ketsji/KX_MouseFocusSensor.cpp | 6 +- source/gameengine/Ketsji/KX_MouseFocusSensor.h | 8 +- source/gameengine/Ketsji/KX_RayCast.h | 27 ++++--- source/gameengine/Ketsji/KX_RaySensor.cpp | 6 +- source/gameengine/Ketsji/KX_RaySensor.h | 8 +- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 5 +- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h | 8 +- 12 files changed, 120 insertions(+), 76 deletions(-) diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst index 74df50ddb58..d8cc5e45e83 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst @@ -799,7 +799,7 @@ base class --- :class:`SCA_IObject` :return: the first object hit or None if no object or object does not match prop :rtype: :class:`KX_GameObject` - .. method:: rayCast(objto, objfrom, dist, prop, face, xray, poly) + .. method:: rayCast(objto, objfrom, dist, prop, face, xray, poly, mask) Look from a point/object to another point/object and find first object hit within dist that matches prop. if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None, None, None) if no hit. @@ -851,6 +851,8 @@ base class --- :class:`SCA_IObject` * 2: return value is a 5-tuple and the 5th element is a 2-tuple (u, v) with the UV mapping of the hit point or None if no hit, or the object doesn't use a mesh collision shape, or doesn't have a UV mapping. :type poly: integer + :arg mask: collision mask: The collision mask (16 layers mapped to a 16-bit integer) is combined with each object's collision group, to hit only a subset of the objects in the scene. Only those objects for which ``collisionGroup & mask`` is true can be hit. + :type mask: bitfield :return: (object, hitpoint, hitnormal) or (object, hitpoint, hitnormal, polygon) or (object, hitpoint, hitnormal, polygon, hituv). * object, hitpoint and hitnormal are None if no hit. diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index e07660cef72..fecd60eb212 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -117,7 +117,7 @@ KX_ConstraintActuator::~KX_ConstraintActuator() // there's nothing to be done here, really.... } /* end of destructor */ -bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) +bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data)) { m_hitObject = client->m_gameobject; @@ -153,7 +153,7 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *resu /* This function is used to pre-filter the object before casting the ray on them. * This is useful for "X-Ray" option when we want to see "through" unwanted object. */ -bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo *client) +bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)) { if (client->m_type > KX_ClientObjectInfo::ACTOR) { @@ -347,7 +347,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame) spc = parent->GetPhysicsController(); } } - KX_RayCast::Callback callback(this,dynamic_cast(spc)); + KX_RayCast::Callback callback(this,dynamic_cast(spc)); result = KX_RayCast::RayTest(pe, position, topoint, callback); if (result) { MT_Vector3 newnormal = callback.m_hitNormal; @@ -459,7 +459,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame) m_hitObject = NULL; // distance of Fh area is stored in m_minimum MT_Point3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction; - KX_RayCast::Callback callback(this, spc); + KX_RayCast::Callback callback(this, spc); result = KX_RayCast::RayTest(pe, position, topoint, callback); // we expect a hit object if (!m_hitObject) diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index edb2e5e0180..af617655d5e 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -37,6 +37,8 @@ #include "MT_Vector3.h" #include "KX_ClientObjectInfo.h" +#include "BLI_utildefines.h" + class KX_RayCast; class KX_GameObject; @@ -113,9 +115,11 @@ protected: KX_ACT_CONSTRAINT_LOCAL = 1024, KX_ACT_CONSTRAINT_DOROTFH = 2048 }; - bool IsValidMode(KX_CONSTRAINTTYPE m); - bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo*); + bool IsValidMode(KX_CONSTRAINTTYPE m); + /// \see KX_RayCast + bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data)); + /// \see KX_RayCast + bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)); KX_ConstraintActuator(SCA_IObject* gameobj, int posDamptime, diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index c3da80bc14f..d7a94f0601c 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -47,7 +47,6 @@ #include "KX_MeshProxy.h" #include "KX_PolyProxy.h" #include // printf -#include // USHRT_MAX #include "SG_Controller.h" #include "PHY_IGraphicController.h" #include "SG_Node.h" @@ -108,8 +107,6 @@ KX_GameObject::KX_GameObject( m_bOccluder(false), m_pPhysicsController(NULL), m_pGraphicController(NULL), - m_xray(false), - m_pHitObject(NULL), m_pObstacleSimulation(NULL), m_pInstanceObjects(NULL), m_pDupliGroupObject(NULL), @@ -2361,8 +2358,8 @@ int KX_GameObject::pyattr_set_collisionGroup(void *self_v, const KX_PYATTRIBUTE_ return PY_SET_ATTR_FAIL; } - if (val < 0 || val > USHRT_MAX) { - PyErr_Format(PyExc_AttributeError, "gameOb.collisionGroup = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX); + if (val == 0 || val & ~((1 << OB_MAX_COL_MASKS) - 1)) { + PyErr_Format(PyExc_AttributeError, "gameOb.collisionGroup = int: KX_GameObject, expected a int bit field, 0 < group < %i", (1 << OB_MAX_COL_MASKS)); return PY_SET_ATTR_FAIL; } @@ -2386,8 +2383,8 @@ int KX_GameObject::pyattr_set_collisionMask(void *self_v, const KX_PYATTRIBUTE_D return PY_SET_ATTR_FAIL; } - if (val < 0 || val > USHRT_MAX) { - PyErr_Format(PyExc_AttributeError, "gameOb.collisionMask = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX); + if (val == 0 || val & ~((1 << OB_MAX_COL_MASKS) - 1)) { + PyErr_Format(PyExc_AttributeError, "gameOb.collisionMask = int: KX_GameObject, expected a int bit field, 0 < mask < %i", (1 << OB_MAX_COL_MASKS)); return PY_SET_ATTR_FAIL; } @@ -3572,15 +3569,32 @@ KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo, return returnValue; } -bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) +struct KX_GameObject::RayCastData +{ + RayCastData(STR_String prop, bool xray, short mask) + :m_prop(prop), + m_xray(xray), + m_mask(mask), + m_hitObject(NULL) + { + } + + STR_String m_prop; + bool m_xray; + unsigned short m_mask; + KX_GameObject *m_hitObject; +}; + +bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, RayCastData *rayData) { KX_GameObject* hitKXObj = client->m_gameobject; - + // if X-ray option is selected, the unwnted objects were not tested, so get here only with true hit // if not, all objects were tested and the front one may not be the correct one. - if (m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL) + if ((rayData->m_xray || rayData->m_prop.Length() == 0 || hitKXObj->GetProperty(rayData->m_prop) != NULL) && + hitKXObj->GetUserCollisionGroup() & rayData->m_mask) { - m_pHitObject = hitKXObj; + rayData->m_hitObject = hitKXObj; return true; } // return true to stop RayCast::RayTest from looping, the above test was decisive @@ -3591,10 +3605,10 @@ bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void /* this function is used to pre-filter the object before casting the ray on them. * This is useful for "X-Ray" option when we want to see "through" unwanted object. */ -bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client) +bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client, RayCastData *rayData) { KX_GameObject* hitKXObj = client->m_gameobject; - + if (client->m_type > KX_ClientObjectInfo::ACTOR) { // Unknown type of object, skip it. @@ -3605,7 +3619,8 @@ bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client) // if X-Ray option is selected, skip object that don't match the criteria as we see through them // if not, test all objects because we don't know yet which one will be on front - if (!m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL) + if ((!rayData->m_xray || rayData->m_prop.Length() == 0 || hitKXObj->GetProperty(rayData->m_prop) != NULL) && + hitKXObj->GetUserCollisionGroup() & rayData->m_mask) { return true; } @@ -3652,17 +3667,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, KX_GameObject *parent = GetParent(); if (!spc && parent) spc = parent->GetPhysicsController(); - - m_pHitObject = NULL; - if (propName) - m_testPropName = propName; - else - m_testPropName.SetLength(0); - KX_RayCast::Callback callback(this,spc); - KX_RayCast::RayTest(pe, fromPoint, toPoint, callback); - if (m_pHitObject) - return m_pHitObject->GetProxy(); + RayCastData rayData(propName, false, (1 << OB_MAX_COL_MASKS) - 1); + KX_RayCast::Callback callback(this, spc, &rayData); + if (KX_RayCast::RayTest(pe, fromPoint, toPoint, callback)) + return rayData.m_hitObject->GetProxy(); Py_RETURN_NONE; } @@ -3713,7 +3722,7 @@ static PyObject *none_tuple_5() } KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, - "rayCast(to,from,dist,prop,face,xray,poly): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) or 4-tuple (object,hit,normal,polygon,hituv) of contact point with object within dist that matches prop.\n" + "rayCast(to,from,dist,prop,face,xray,poly,mask): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) or 4-tuple (object,hit,normal,polygon,hituv) of contact point with object within dist that matches prop.\n" " If no hit, return (None,None,None) or (None,None,None,None) or (None,None,None,None,None).\n" " to = 3-tuple or object reference for destination of ray (if object, use center of object)\n" " from = 3-tuple or object reference for origin of ray (if object, use center of object)\n" @@ -3727,6 +3736,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, " 2=>return value is a 5-tuple, the 4th element is the KX_PolyProxy object\n" " and the 5th element is the vector of UV coordinates at the hit point of the None if there is no UV mapping\n" " If 0 or omitted, return value is a 3-tuple\n" +" mask = collision mask: the collision mask that ray can hit, 0 < mask < 65536\n" "Note: The object on which you call this method matters: the ray will ignore it.\n" " prop and xray option interact as follow:\n" " prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray\n" @@ -3742,8 +3752,9 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, char *propName = NULL; KX_GameObject *other; int face=0, xray=0, poly=0; + int mask = (1 << OB_MAX_COL_MASKS) - 1; - if (!PyArg_ParseTuple(args,"O|Ofsiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) { + if (!PyArg_ParseTuple(args,"O|Ofsiiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly, &mask)) { return NULL; // Python sets a simple error } @@ -3773,11 +3784,16 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, fromPoint = other->NodeGetWorldPosition(); } else { - PyErr_SetString(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly): KX_GameObject, the second optional argument to rayCast must be a vector or a KX_GameObject"); + PyErr_SetString(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly,mask): KX_GameObject, the second optional argument to rayCast must be a vector or a KX_GameObject"); return NULL; } } - + + if (mask == 0 || mask & ~((1 << OB_MAX_COL_MASKS) - 1)) { + PyErr_Format(PyExc_TypeError, "gameOb.rayCast(to,from,dist,prop,face,xray,poly,mask): KX_GameObject, mask argument to rayCast must be a int bitfield, 0 < mask < %i", (1 << OB_MAX_COL_MASKS)); + return NULL; + } + if (dist != 0.0f) { MT_Vector3 toDir = toPoint-fromPoint; if (MT_fuzzyZero(toDir.length2())) { @@ -3796,22 +3812,16 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, KX_GameObject *parent = GetParent(); if (!spc && parent) spc = parent->GetPhysicsController(); - - m_pHitObject = NULL; - if (propName) - m_testPropName = propName; - else - m_testPropName.SetLength(0); - m_xray = xray; + // to get the hit results - KX_RayCast::Callback callback(this,spc,NULL,face,(poly==2)); - KX_RayCast::RayTest(pe, fromPoint, toPoint, callback); + RayCastData rayData(propName, xray, mask); + KX_RayCast::Callback callback(this, spc, &rayData, face, (poly == 2)); - if (m_pHitObject) + if (KX_RayCast::RayTest(pe, fromPoint, toPoint, callback)) { PyObject *returnValue = (poly == 2) ? PyTuple_New(5) : (poly) ? PyTuple_New(4) : PyTuple_New(3); if (returnValue) { // unlikely this would ever fail, if it does python sets an error - PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->GetProxy()); + PyTuple_SET_ITEM(returnValue, 0, rayData.m_hitObject->GetProxy()); PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(callback.m_hitPoint)); PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(callback.m_hitNormal)); if (poly) diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index c10802a83b2..abd109a5e52 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -111,9 +111,6 @@ protected: PHY_IPhysicsController* m_pPhysicsController; PHY_IGraphicController* m_pGraphicController; - STR_String m_testPropName; - bool m_xray; - KX_GameObject* m_pHitObject; SG_Node* m_pSGNode; @@ -131,9 +128,18 @@ protected: BL_ActionManager* GetActionManager(); bool m_bRecordAnimation; + public: bool m_isDeformable; + /** + * KX_GameObject custom infos for ray cast, it contains property name, + * collision mask, xray flag and hited object. + * This structure is created during ray cast and passed as argument + * "data" to functions KX_GameObject::NeedRayCast and KX_GameObject::RayHit. + */ + struct RayCastData; + /** * Helper function for modules that can't include KX_ClientObjectInfo.h */ @@ -661,8 +667,10 @@ public: return (m_pSGNode && m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsVertexParent()); } - bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo* client); + /// \see KX_RayCast + bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, RayCastData *rayData); + /// \see KX_RayCast + bool NeedRayCast(KX_ClientObjectInfo *client, RayCastData *rayData); /** diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 46f27e1a2df..db2cb1fdcfd 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -144,7 +144,7 @@ bool KX_MouseFocusSensor::Evaluate() return result; } -bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *result, void * const data) +bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *result, void *UNUSED(data)) { KX_GameObject* hitKXObj = client_info->m_gameobject; @@ -198,7 +198,7 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r /* this function is used to pre-filter the object before casting the ray on them. * This is useful for "X-Ray" option when we want to see "through" unwanted object. */ -bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo* client) +bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)) { KX_GameObject *hitKXObj = client->m_gameobject; @@ -356,7 +356,7 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam) PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment(); // get UV mapping - KX_RayCast::Callback callback(this,physics_controller,NULL,false,true); + KX_RayCast::Callback callback(this,physics_controller,NULL,false,true); KX_RayCast::RayTest(physics_environment, m_prevSourcePoint, m_prevTargetPoint, callback); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 0c7c8ab676a..dd9295b2ff4 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -35,6 +35,8 @@ #include "SCA_MouseSensor.h" +#include "BLI_utildefines.h" + class KX_RayCast; /** @@ -90,8 +92,10 @@ class KX_MouseFocusSensor : public SCA_MouseSensor return result; }; - bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo* client); + /// \see KX_RayCast + bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data)); + /// \see KX_RayCast + bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)); const MT_Point3& RaySource() const; const MT_Point3& RayTarget() const; diff --git a/source/gameengine/Ketsji/KX_RayCast.h b/source/gameengine/Ketsji/KX_RayCast.h index e47ac676eb1..c977fb8f385 100644 --- a/source/gameengine/Ketsji/KX_RayCast.h +++ b/source/gameengine/Ketsji/KX_RayCast.h @@ -44,12 +44,15 @@ struct KX_ClientObjectInfo; /** * Defines a function for doing a ray cast. * - * eg KX_RayCast::RayTest(ignore_physics_controller, physics_environment, frompoint, topoint, result_point, result_normal, KX_RayCast::Callback(this, data) + * eg KX_RayCast::RayTest(ignore_physics_controller, physics_environment, frompoint, topoint, result_point, result_normal, KX_RayCast::Callback(this, data) * - * Calls myclass->RayHit(client, hit_point, hit_normal, data) for all client + * Calls myclass->NeedRayCast(client, data) for all client in environment + * and myclass->RayHit(client, hit_point, hit_normal, data) for all client * between frompoint and topoint * - * myclass->RayHit should return true to end the raycast, false to ignore the current client. + * myclass->NeedRayCast should return true to ray test the current client. + * + * myclass->RayHit should return true to end the raycast, false to ignore the current client and to continue. * * Returns true if a client was accepted, false if nothing found. */ @@ -80,10 +83,10 @@ public: /** * Callback wrapper. * - * Construct with KX_RayCast::Callback(this, data) + * Construct with KX_RayCast::Callback(this, data) * and pass to KX_RayCast::RayTest */ - template class Callback; + template class Callback; /// Public interface. /// Implement bool RayHit in your class to receive ray callbacks. @@ -99,12 +102,18 @@ public: #endif }; -template class KX_RayCast::Callback : public KX_RayCast +template +class KX_RayCast::Callback : public KX_RayCast { T *self; - void *data; + /** + * Some user info passed as argument in constructor. + * It contains all info needed to check client in NeedRayCast + * and RayHit. + */ + dataT *data; public: - Callback(T *_self, PHY_IPhysicsController* controller=NULL, void *_data = NULL, bool faceNormal=false, bool faceUV=false) + Callback(T *_self, PHY_IPhysicsController *controller = NULL, dataT *_data = NULL, bool faceNormal = false, bool faceUV = false) : KX_RayCast(controller, faceNormal, faceUV), self(_self), data(_data) @@ -127,7 +136,7 @@ public: MT_assert(info && "Physics controller with no client object info"); return false; } - return self->NeedRayCast(info); + return self->NeedRayCast(info, data); } diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index c97d233a67b..4ffb5f332db 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -107,7 +107,7 @@ bool KX_RaySensor::IsPositiveTrigger() return result; } -bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) +bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data)) { KX_GameObject* hitKXObj = client->m_gameobject; @@ -158,7 +158,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void /* this function is used to pre-filter the object before casting the ray on them. * This is useful for "X-Ray" option when we want to see "through" unwanted object. */ -bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client) +bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)) { KX_GameObject *hitKXObj = client->m_gameobject; @@ -282,7 +282,7 @@ bool KX_RaySensor::Evaluate() PHY_IPhysicsEnvironment* physics_environment = this->m_scene->GetPhysicsEnvironment(); - KX_RayCast::Callback callback(this, spc); + KX_RayCast::Callback callback(this, spc); KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback); /* now pass this result to some controller */ diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 4604863a233..1901bb04f86 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -38,6 +38,8 @@ #include "SCA_IScene.h" /* only for scene replace */ #include "KX_Scene.h" /* only for scene replace */ +#include "BLI_utildefines.h" + struct KX_ClientObjectInfo; class KX_RayCast; @@ -74,8 +76,10 @@ public: virtual bool IsPositiveTrigger(); virtual void Init(); - bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo* client); + /// \see KX_RayCast + bool RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data)); + /// \see KX_RayCast + bool NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data)); virtual void Replace_IScene(SCA_IScene *val) { diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 1758b7abf9f..bd84c3c96b1 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -1215,10 +1215,9 @@ void RAS_OpenGLRasterizer::RemoveLight(RAS_ILightObject* lightobject) m_lights.erase(lit); } -bool RAS_OpenGLRasterizer::RayHit(struct KX_ClientObjectInfo *client, KX_RayCast *result, void * const data) +bool RAS_OpenGLRasterizer::RayHit(struct KX_ClientObjectInfo *client, KX_RayCast *result, double *oglmatrix) { if (result->m_hitMesh) { - double* const oglmatrix = (double* const) data; RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon); if (!poly->IsVisible()) @@ -1328,7 +1327,7 @@ void RAS_OpenGLRasterizer::applyTransform(double* oglmatrix,int objectdrawmode ) if (!physics_controller && parent) physics_controller = parent->GetPhysicsController(); - KX_RayCast::Callback callback(this, physics_controller, oglmatrix); + KX_RayCast::Callback callback(this, physics_controller, oglmatrix); if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback)) { // couldn't find something to cast the shadow on... diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index ad49ebe5179..67a11f64726 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -45,6 +45,8 @@ using namespace std; #include "RAS_MaterialBucket.h" #include "RAS_IPolygonMaterial.h" +#include "BLI_utildefines.h" + class RAS_IStorage; class RAS_ICanvas; class RAS_OpenGLLight; @@ -306,8 +308,10 @@ public: void PushMatrix(); void PopMatrix(); - bool RayHit(struct KX_ClientObjectInfo *client, class KX_RayCast *result, void * const data); - bool NeedRayCast(struct KX_ClientObjectInfo *) { return true; } + /// \see KX_RayCast + bool RayHit(struct KX_ClientObjectInfo *client, class KX_RayCast *result, double *oglmatrix); + /// \see KX_RayCast + bool NeedRayCast(struct KX_ClientObjectInfo *, void *UNUSED(data)) { return true; } RAS_ILightObject* CreateLight(); void AddLight(RAS_ILightObject* lightobject); -- cgit v1.2.3