BGE: Fix T35288 Touch/Ray/Mouse sensor and Constraint actuator with material check...
authorPorteries Tristan <republicthunderbolt9@gmail.com>
Fri, 24 Jul 2015 18:28:39 +0000 (20:28 +0200)
committerPorteries Tristan <republicthunderbolt9@gmail.com>
Sat, 25 Jul 2015 07:43:06 +0000 (09:43 +0200)
Now we look at all materials instead of the first. So m_auxilary_info is useless and removed.

source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_ClientObjectInfo.h
source/gameengine/Ketsji/KX_ConstraintActuator.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
source/gameengine/Ketsji/KX_RaySensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.cpp

index 49eb2256b4700e7eab2d670e48adb9612f4de9b7..33c4ffd9a0c97328132ad9645fb29f8fa6c9ab40 100644 (file)
@@ -1391,16 +1391,6 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
        if ((blenderobject->gameflag & OB_RECORD_ANIMATION) != 0)
                gameobj->SetRecordAnimation(true);
 
-       // store materialname in auxinfo, needed for touchsensors
-       if (meshobj)
-       {
-               const STR_String& matname=meshobj->GetMaterialName(0);
-               gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
-       } else
-       {
-               gameobj->getClientInfo()->m_auxilary_info = 0;
-       }
-
        delete shapeprops;
        delete smmaterial;
        if (dm) {
index e947eb4be6d29cf8debffaabf75a7f8587d05c61..81ae5b58009ebfc53a2c51f3ee8225bbf20ec349 100644 (file)
@@ -52,19 +52,16 @@ struct KX_ClientObjectInfo
                OBACTORSENSOR
        }               m_type;
        KX_GameObject*  m_gameobject;
-       void*           m_auxilary_info;
        std::list<SCA_ISensor*> m_sensors;
 public:
-       KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) :
+       KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC) :
                m_type(type),
-               m_gameobject(gameobject),
-               m_auxilary_info(auxilary_info)
+               m_gameobject(gameobject)
        {}
        
        KX_ClientObjectInfo(const KX_ClientObjectInfo &copy) :
                  m_type(copy.m_type),
-                 m_gameobject(copy.m_gameobject),
-                 m_auxilary_info(copy.m_auxilary_info)
+                 m_gameobject(copy.m_gameobject)
        {
        }
        
index e5662b54b83638212f2d14e59e6eaaa1434eca98..e07660cef723947313495bfe0019fc495ac52590 100644 (file)
@@ -41,6 +41,7 @@
 #include "KX_GameObject.h"
 #include "KX_RayCast.h"
 #include "KX_PythonInit.h" // KX_GetActiveScene
+#include "RAS_MeshObject.h"
 
 #include <stdio.h>
 
@@ -129,15 +130,17 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *resu
        }
        else
        {
-               if (m_option & KX_ACT_CONSTRAINT_MATERIAL)
-               {
-                       if (client->m_auxilary_info)
-                       {
-                               bFound = !strcmp(m_property.Ptr(), ((char*)client->m_auxilary_info));
+               if (m_option & KX_ACT_CONSTRAINT_MATERIAL) {
+                       for (unsigned int i = 0; i < m_hitObject->GetMeshCount(); ++i) {
+                               RAS_MeshObject *meshObj = m_hitObject->GetMesh(i);
+                               for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                       bFound = strcmp(m_property.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                       if (bFound)
+                                               break;
+                               }
                        }
                }
-               else
-               {
+               else {
                        bFound = m_hitObject->GetProperty(m_property) != NULL;
                }
        }
index c3c693ed55fbd36585ce165aa7cffe6c27b836a7..46f27e1a2df7a72b7b069770f2cee840db801ad7 100644 (file)
@@ -42,6 +42,7 @@
 #include "RAS_FramingManager.h"
 #include "RAS_ICanvas.h"
 #include "RAS_IRasterizer.h"
+#include "RAS_MeshObject.h"
 #include "SCA_IScene.h"
 #include "KX_Scene.h"
 #include "KX_Camera.h"
@@ -165,15 +166,17 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r
                }
                else
                {
-                       if (m_bFindMaterial)
-                       {
-                               if (client_info->m_auxilary_info)
-                               {
-                                       bFound = (m_propertyname== ((char*)client_info->m_auxilary_info));
+                       if (m_bFindMaterial) {
+                               for (unsigned int i = 0; i < hitKXObj->GetMeshCount(); ++i) {
+                                       RAS_MeshObject *meshObj = hitKXObj->GetMesh(i);
+                                       for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                               bFound = strcmp(m_propertyname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                               if (bFound)
+                                                       break;
+                                       }
                                }
                        }
-                       else
-                       {
+                       else {
                                bFound = hitKXObj->GetProperty(m_propertyname) != NULL;
                        }
                }
@@ -197,6 +200,8 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r
  */
 bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo* client)
 {
+       KX_GameObject *hitKXObj = client->m_gameobject;
+
        if (client->m_type > KX_ClientObjectInfo::ACTOR)
        {
                // Unknown type of object, skip it.
@@ -208,14 +213,21 @@ bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo* client)
        {
                if (m_bFindMaterial)
                {
-                       // not quite correct: an object may have multiple material
-                       // should check all the material and not only the first one
-                       if (!client->m_auxilary_info || (m_propertyname != ((char*)client->m_auxilary_info)))
+                       bool found = false;
+                       for (unsigned int i = 0; i < hitKXObj->GetMeshCount(); ++i) {
+                               RAS_MeshObject *meshObj = hitKXObj->GetMesh(i);
+                               for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                       found = strcmp(m_propertyname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                       if (found)
+                                               break;
+                               }
+                       }
+                       if (!found)
                                return false;
                }
                else
                {
-                       if (client->m_gameobject->GetProperty(m_propertyname) == NULL)
+                       if (hitKXObj->GetProperty(m_propertyname) == NULL)
                                return false;
                }
        }
index 0f47dfd922beb1267c02ca5656af865cb9639420..c97d233a67bfe3d6628f1f8b03b9d28df4a41653 100644 (file)
@@ -46,6 +46,7 @@
 #include "PHY_IPhysicsEnvironment.h"
 #include "PHY_IPhysicsController.h"
 #include "DNA_sensor_types.h"
+#include "RAS_MeshObject.h"
 
 #include <stdio.h>
 
@@ -111,6 +112,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
 
        KX_GameObject* hitKXObj = client->m_gameobject;
        bool bFound = false;
+       bool hitMaterial = false;
 
        if (m_propertyname.Length() == 0)
        {
@@ -118,15 +120,19 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
        }
        else
        {
-               if (m_bFindMaterial)
-               {
-                       if (client->m_auxilary_info)
-                       {
-                               bFound = (m_propertyname== ((char*)client->m_auxilary_info));
+               if (m_bFindMaterial) {
+                       for (unsigned int i = 0; i < hitKXObj->GetMeshCount(); ++i) {
+                               RAS_MeshObject *meshObj = hitKXObj->GetMesh(i);
+                               for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                       bFound = strcmp(m_propertyname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                       if (bFound) {
+                                               hitMaterial = true;
+                                               break;
+                                       }
+                               }
                        }
                }
-               else
-               {
+               else {
                        bFound = hitKXObj->GetProperty(m_propertyname) != NULL;
                }
        }
@@ -143,7 +149,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
                m_hitNormal[1] = result->m_hitNormal[1];
                m_hitNormal[2] = result->m_hitNormal[2];
                        
-               m_hitMaterial = (client->m_auxilary_info ? (char*)client->m_auxilary_info : "");
+               m_hitMaterial = hitMaterial;
        }
        // no multi-hit search yet
        return true;
@@ -154,6 +160,8 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void
  */
 bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client)
 {
+       KX_GameObject *hitKXObj = client->m_gameobject;
+
        if (client->m_type > KX_ClientObjectInfo::ACTOR)
        {
                // Unknown type of object, skip it.
@@ -163,16 +171,21 @@ bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client)
        }
        if (m_bXRay && m_propertyname.Length() != 0)
        {
-               if (m_bFindMaterial)
-               {
-                       // not quite correct: an object may have multiple material
-                       // should check all the material and not only the first one
-                       if (!client->m_auxilary_info || (m_propertyname != ((char*)client->m_auxilary_info)))
+               if (m_bFindMaterial) {
+                       bool found = false;
+                       for (unsigned int i = 0; i < hitKXObj->GetMeshCount(); ++i) {
+                               RAS_MeshObject *meshObj = hitKXObj->GetMesh(i);
+                               for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                       found = strcmp(m_propertyname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                       if (found)
+                                               break;
+                               }
+                       }
+                       if (!found)
                                return false;
                }
-               else
-               {
-                       if (client->m_gameobject->GetProperty(m_propertyname) == NULL)
+               else {
+                       if (hitKXObj->GetProperty(m_propertyname) == NULL)
                                return false;
                }
        }
index 5cb1d5f3620c3b09fc9de08d2245e3cbc6666553..593d3e844e8c6fb3054a336ecaa87fe7a3cc4604 100644 (file)
@@ -41,6 +41,8 @@
 
 #include "PHY_IPhysicsController.h"
 
+#include "RAS_MeshObject.h"
+
 #include <iostream>
 #include "PHY_IPhysicsEnvironment.h"
 
@@ -219,14 +221,17 @@ bool      KX_TouchSensor::BroadPhaseSensorFilterCollision(void*obj1,void*obj2)
        bool found = m_touchedpropname.IsEmpty();
        if (!found)
        {
-               if (m_bFindMaterial)
-               {
-                       if (client_info->m_auxilary_info)
-                       {
-                               found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info));
+               if (m_bFindMaterial) {
+                       for (unsigned int i = 0; i < otherobj->GetMeshCount(); ++i) {
+                               RAS_MeshObject *meshObj = otherobj->GetMesh(i);
+                               for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                       found = strcmp(m_touchedpropname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                       if (found)
+                                               break;
+                               }
                        }
-               } else
-               {
+               }
+               else {
                        found = (otherobj->GetProperty(m_touchedpropname) != NULL);
                }
        }
@@ -255,16 +260,22 @@ bool      KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
        {
                
                bool found = m_touchedpropname.IsEmpty();
+               bool hitMaterial = false;
                if (!found)
                {
-                       if (m_bFindMaterial)
-                       {
-                               if (client_info->m_auxilary_info)
-                               {
-                                       found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info));
+                       if (m_bFindMaterial) {
+                               for (unsigned int i = 0; i < gameobj->GetMeshCount(); ++i) {
+                                       RAS_MeshObject *meshObj = gameobj->GetMesh(i);
+                                       for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
+                                               found = strcmp(m_touchedpropname.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
+                                               if (found) {
+                                                       hitMaterial = true;
+                                                       break;
+                                               }
+                                       }
                                }
-                       } else
-                       {
+                       }
+                       else {
                                found = (gameobj->GetProperty(m_touchedpropname) != NULL);
                        }
                }
@@ -278,7 +289,7 @@ bool        KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
                        }
                        m_bTriggered = true;
                        m_hitObject = gameobj;
-                       m_hitMaterial = (client_info->m_auxilary_info ? (char*)client_info->m_auxilary_info : "");
+                       m_hitMaterial = hitMaterial;
                        //printf("KX_TouchSensor::HandleCollision\n");
                }