BGE: Fix T35288 Touch/Ray/Mouse sensor and Constraint actuator with material check doesn't work.

Now we look at all materials instead of the first. So m_auxilary_info is useless and removed.
This commit is contained in:
Porteries Tristan 2015-07-24 20:28:39 +02:00
parent e301cf3ec2
commit 9939c18900
Notes: blender-bot 2023-02-21 17:59:30 +01:00
Referenced by issue #35288, Collision and Touch Sensors don't work properly
6 changed files with 91 additions and 65 deletions

View 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) {

View 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)
{
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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");
}