diff options
Diffstat (limited to 'extern/solid/src/DT_Scene.cpp')
-rwxr-xr-x | extern/solid/src/DT_Scene.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/extern/solid/src/DT_Scene.cpp b/extern/solid/src/DT_Scene.cpp new file mode 100755 index 00000000000..56cea1633ca --- /dev/null +++ b/extern/solid/src/DT_Scene.cpp @@ -0,0 +1,183 @@ +/* + * SOLID - Software Library for Interference Detection + * + * Copyright (C) 2001-2003 Dtecta. All rights reserved. + * + * This library may be distributed under the terms of the Q Public License + * (QPL) as defined by Trolltech AS of Norway and appearing in the file + * LICENSE.QPL included in the packaging of this file. + * + * This library may be distributed and/or modified under the terms of the + * GNU General Public License (GPL) version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Commercial use or any other use of this library not covered by either + * the QPL or the GPL requires an additional license from Dtecta. + * Please contact info@dtecta.com for enquiries about the terms of commercial + * use of this library. + */ + +#include "DT_Scene.h" +#include "DT_Object.h" +#include "DT_Convex.h" + +//#define DEBUG + +static void beginOverlap(void *client_data, void *object1, void *object2) +{ + DT_Encounter e((DT_Object *)object1, (DT_Object *)object2); + DT_EncounterTable *encounterTable = static_cast<DT_EncounterTable *>(client_data); + +#ifdef DEBUG + std::cout << "Begin: " << e << std::endl; +#endif + + encounterTable->insert(e); +} + + +static void endOverlap(void *client_data, void *object1, void *object2) +{ + DT_Encounter e((DT_Object *)object1, (DT_Object *)object2); + DT_EncounterTable *encounterTable = static_cast<DT_EncounterTable *>(client_data); + +#ifdef DEBUG + std::cout << "End: " << e << std::endl; +#endif + + assert(encounterTable->find(e) != encounterTable->end()); + encounterTable->erase(e); +} + +struct DT_RayCastData { + DT_RayCastData(const void *ignore) + : m_ignore(ignore) + {} + + const void *m_ignore; + MT_Vector3 m_normal; +}; + +static bool objectRayCast(void *client_data, + void *object, + const DT_Vector3 source, + const DT_Vector3 target, + DT_Scalar *lambda) +{ + DT_RayCastData *data = static_cast<DT_RayCastData *>(client_data); + if (((DT_Object *)object)->getClientObject() != data->m_ignore) + { + MT_Scalar param = MT_Scalar(*lambda); + + if (((DT_Object *)object)->ray_cast(MT_Point3(source), MT_Point3(target), + param, data->m_normal)) + { + *lambda = param; + return true; + } + } + return false; +} + +DT_Scene::DT_Scene() + : m_broadphase(BP_CreateScene(&m_encounterTable, &beginOverlap, &endOverlap)) +{} + +DT_Scene::~DT_Scene() +{ + BP_DestroyScene(m_broadphase); +} + +void DT_Scene::addObject(DT_Object &object) +{ + const MT_BBox& bbox = object.getBBox(); + DT_Vector3 min, max; + bbox.getMin().getValue(min); + bbox.getMax().getValue(max); + BP_ProxyHandle proxy = BP_CreateProxy(m_broadphase, &object, min, max); + +#ifdef DEBUG + DT_EncounterTable::iterator it; + std::cout << "Add " << &object << ':'; + for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it) { + std::cout << ' ' << (*it); + } + std::cout << std::endl; +#endif + object.addProxy(proxy); + m_objectList.push_back(std::make_pair(&object, proxy)); +} + + + +void DT_Scene::removeObject(DT_Object& object) +{ + T_ObjectList::iterator it = m_objectList.begin(); + + while (it != m_objectList.end() && &object != (*it).first) + { + ++it; + } + + if (it != m_objectList.end()) + { + object.removeProxy((*it).second); + BP_DestroyProxy(m_broadphase, (*it).second); + m_objectList.erase(it); + +#ifdef DEBUG + std::cout << "Remove " << &object << ':'; + DT_EncounterTable::iterator it; + for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it) + { + std::cout << ' ' << (*it); + assert((*it).first() != &object && + (*it).second() != &object); + } + std::cout << std::endl; +#endif + } +} + + + +int DT_Scene::handleCollisions(const DT_RespTable *respTable) +{ + int count = 0; + + assert(respTable); + + DT_EncounterTable::iterator it; + for (it = m_encounterTable.begin(); it != m_encounterTable.end(); ++it) + { + if ((*it).exactTest(respTable, count)) + { + break; + } + + } + return count; +} + +void *DT_Scene::rayCast(const void *ignore_client, + const DT_Vector3 source, const DT_Vector3 target, + DT_Scalar& lambda, DT_Vector3 normal) const +{ + DT_RayCastData data(ignore_client); + DT_Object *object = (DT_Object *)BP_RayCast(m_broadphase, + &objectRayCast, + &data, + source, target, + &lambda); + if (object) + { + data.m_normal.getValue(normal); + return object->getClientObject(); + } + + return 0; +} |