From 565cbe146d02986eb34aed3c09642fd7c3a570ae Mon Sep 17 00:00:00 2001 From: gus Date: Wed, 31 Jul 2013 10:04:09 +0200 Subject: [PATCH 1/6] function declaration --- libs/openengine/bullet/physic.cpp | 6 ++++++ libs/openengine/bullet/physic.hpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 66ee077ee..05452c8a7 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -547,6 +547,12 @@ namespace Physic #endif }; + + std::string PhysicEngine::sphereTest(float radius,btVector3& pos) + { + + } + std::vector PhysicEngine::getCollisions(const std::string& name) { RigidBody* body = getRigidBody(name); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index baeb31678..ff29d635d 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -306,6 +306,8 @@ namespace Physic std::pair sphereCast (float radius, btVector3& from, btVector3& to); ///< @return (hit, relative distance) + std::string sphereTest(float radius,btVector3& pos); + std::vector getCollisions(const std::string& name); //event list of non player object From 830762722d786edb06dfe7174eaf71518ae747b1 Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 3 Aug 2013 11:26:36 +0200 Subject: [PATCH 2/6] first attempt: hit detection with a sphere (not finished) --- apps/openmw/mwworld/physicssystem.cpp | 7 +++- libs/openengine/bullet/physic.cpp | 50 ++++++++++++++++++++++++++- libs/openengine/bullet/physic.hpp | 2 +- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index a5b43b4fc..2615842e9 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -268,6 +268,7 @@ namespace MWWorld std::pair result; /*auto*/ result = mEngine->rayTest(origin, dest); result.second *= queryDistance; + return std::make_pair (result.second, result.first); } @@ -316,7 +317,11 @@ namespace MWWorld std::pair result = mEngine->rayTest(origin, dest); result.second *= queryDistance; - return result; + + std::pair result2 = mEngine->sphereTest(queryDistance,origin); + std::cout << "physic system: getFacedHandle" << result2.first << result2.second.length(); + return std::make_pair (result2.first,result2.second.length()); + //return result; } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 32883b48e..a9173e301 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -545,15 +545,63 @@ namespace Physic if (body && !(col0->getBroadphaseHandle()->m_collisionFilterGroup & CollisionType_Raycasting)) mResult.push_back(body->mName); + return 0.f; } #endif }; + struct AabbResultCallback : public btBroadphaseAabbCallback { + std::vector hits; + //AabbResultCallback(){} + virtual bool process(const btBroadphaseProxy* proxy) { + RigidBody* collisionObject = static_cast(proxy->m_clientObject); + if(proxy->m_collisionFilterGroup == CollisionType_Actor && (collisionObject->mName != "player")) + this->hits.push_back(collisionObject); + return true; + } + }; + - std::string PhysicEngine::sphereTest(float radius,btVector3& pos) + std::pair PhysicEngine::sphereTest(float radius,btVector3& pos) { + AabbResultCallback callback; + /*btDefaultMotionState* newMotionState = + new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),pos)); + btCollisionShape * shape = new btSphereShape(radius); + btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo + (0,newMotionState, shape); + RigidBody* body = new RigidBody(CI,"hitDetectionShpere__"); + btTransform tr = body->getWorldTransform(); + tr.setOrigin(pos); + body->setWorldTransform(tr); + dynamicsWorld->addRigidBody(body,CollisionType_Actor,CollisionType_World|CollisionType_World); + body->setWorldTransform(tr);*/ + btVector3 aabbMin = pos - radius*btVector3(1.0f, 1.0f, 1.0f); + btVector3 aabbMax = pos + radius*btVector3(1.0f, 1.0f, 1.0f); + + broadphase->aabbTest(aabbMin,aabbMax,callback); + for(int i=0;igetWorldTransform().getOrigin()-pos).length()mName,callback.hits[i]->getWorldTransform().getOrigin()); + } + } + //ContactTestResultCallback callback; + //dynamicsWorld->contactTest(body, callback); + //dynamicsWorld->removeRigidBody(body); + //delete body; + //delete shape; + //if(callback.mResultName.empty()) return std::make_pair(std::string(""),btVector3(0,0,0)); + /*for(int i=0;i(callback.mResultName[i],callback.mResultContact[i]); + */ + return std::make_pair(std::string(""),btVector3(0,0,0)); } std::vector PhysicEngine::getCollisions(const std::string& name) diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 2ff2009c1..32af0da4e 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -307,7 +307,7 @@ public: std::pair sphereCast (float radius, btVector3& from, btVector3& to); ///< @return (hit, relative distance) - std::string sphereTest(float radius,btVector3& pos); + std::pair sphereTest(float radius,btVector3& pos); std::vector getCollisions(const std::string& name); From 4c7dcdc8aae7b4f65f0af3798f33b3da2d8b552f Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 3 Aug 2013 11:33:34 +0200 Subject: [PATCH 3/6] check if there is an object in the way --- libs/openengine/bullet/physic.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index a9173e301..f2fa79735 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -584,9 +584,12 @@ namespace Physic broadphase->aabbTest(aabbMin,aabbMax,callback); for(int i=0;igetWorldTransform().getOrigin()-pos).length()getWorldTransform().getOrigin()-pos).length(); + if(dmName,callback.hits[i]->getWorldTransform().getOrigin()); + std::pair rayResult = this->rayTest(pos,callback.hits[i]->getWorldTransform().getOrigin()); + if(rayResult.second>d || rayResult.first == callback.hits[i]->mName) + return std::make_pair(callback.hits[i]->mName,callback.hits[i]->getWorldTransform().getOrigin()); } } //ContactTestResultCallback callback; From a25ee360dc000a5a8b42f6523794a19f19b4e31a Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 3 Aug 2013 12:16:51 +0200 Subject: [PATCH 4/6] use angles and GMST. not sure this work as it should --- apps/openmw/mwworld/physicssystem.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 2615842e9..071321223 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -15,9 +15,12 @@ #include -//#include "../mwbase/world.hpp" // FIXME +#include "../mwbase/world.hpp" // FIXME #include "../mwbase/environment.hpp" +#include +#include "../mwworld/esmstore.hpp" + #include "ptr.hpp" #include "class.hpp" @@ -319,8 +322,23 @@ namespace MWWorld result.second *= queryDistance; std::pair result2 = mEngine->sphereTest(queryDistance,origin); - std::cout << "physic system: getFacedHandle" << result2.first << result2.second.length(); - return std::make_pair (result2.first,result2.second.length()); + //std::cout << "physic system: getFacedHandle" << result2.first << result2.second.length(); + if(result2.first == "") return std::make_pair("",0); + btVector3 a = result2.second - origin; + Ogre::Vector3 a_ = Ogre::Vector3(a.x(),a.y(),a.z()); + a_ = orient_.Inverse()*a_; + Ogre::Vector2 a_xy = Ogre::Vector2(a_.x,a_.y); + Ogre::Vector2 a_yz = Ogre::Vector2(a_.y,a_.z); + float axy = a_xy.angleBetween(Ogre::Vector2::UNIT_Y).valueDegrees(); + float az = a_yz.angleBetween(Ogre::Vector2::UNIT_X).valueDegrees(); + std::cout << axy << " " << az << "\n"; + //MWBase::Environment::get().getWorld()->getStore(); + float fCombatAngleXY = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatAngleXY")->getFloat(); + float fCombatAngleZ = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatAngleZ")->getFloat(); + if(abs(axy) < fCombatAngleXY && abs(az) < fCombatAngleZ) + return std::make_pair (result2.first,result2.second.length()); + else + return std::make_pair("",0); //return result; } From c8bb32c40d3dda4b0aaab2bff00417c1a5ac42b2 Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 3 Aug 2013 12:29:18 +0200 Subject: [PATCH 5/6] small maths correction --- apps/openmw/mwworld/physicssystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 071321223..4ee10d872 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -328,7 +328,7 @@ namespace MWWorld Ogre::Vector3 a_ = Ogre::Vector3(a.x(),a.y(),a.z()); a_ = orient_.Inverse()*a_; Ogre::Vector2 a_xy = Ogre::Vector2(a_.x,a_.y); - Ogre::Vector2 a_yz = Ogre::Vector2(a_.y,a_.z); + Ogre::Vector2 a_yz = Ogre::Vector2(a_xy.length(),a_.z); float axy = a_xy.angleBetween(Ogre::Vector2::UNIT_Y).valueDegrees(); float az = a_yz.angleBetween(Ogre::Vector2::UNIT_X).valueDegrees(); std::cout << axy << " " << az << "\n"; From a23e7fac93233a34c1d58ee2e4d40cd95aba71c9 Mon Sep 17 00:00:00 2001 From: gus Date: Sat, 3 Aug 2013 13:58:16 +0200 Subject: [PATCH 6/6] clean up --- apps/openmw/mwworld/physicssystem.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 4ee10d872..e85e99983 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -316,30 +316,23 @@ namespace MWWorld Ogre::Vector3 dest_ = origin_ + orient_.yAxis()*queryDistance; btVector3 origin(origin_.x, origin_.y, origin_.z); - btVector3 dest(dest_.x, dest_.y, dest_.z); - std::pair result = mEngine->rayTest(origin, dest); - result.second *= queryDistance; - - std::pair result2 = mEngine->sphereTest(queryDistance,origin); - //std::cout << "physic system: getFacedHandle" << result2.first << result2.second.length(); - if(result2.first == "") return std::make_pair("",0); - btVector3 a = result2.second - origin; + std::pair result = mEngine->sphereTest(queryDistance,origin); + if(result.first == "") return std::make_pair("",0); + btVector3 a = result.second - origin; Ogre::Vector3 a_ = Ogre::Vector3(a.x(),a.y(),a.z()); a_ = orient_.Inverse()*a_; Ogre::Vector2 a_xy = Ogre::Vector2(a_.x,a_.y); Ogre::Vector2 a_yz = Ogre::Vector2(a_xy.length(),a_.z); float axy = a_xy.angleBetween(Ogre::Vector2::UNIT_Y).valueDegrees(); float az = a_yz.angleBetween(Ogre::Vector2::UNIT_X).valueDegrees(); - std::cout << axy << " " << az << "\n"; - //MWBase::Environment::get().getWorld()->getStore(); + float fCombatAngleXY = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatAngleXY")->getFloat(); float fCombatAngleZ = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatAngleZ")->getFloat(); if(abs(axy) < fCombatAngleXY && abs(az) < fCombatAngleZ) - return std::make_pair (result2.first,result2.second.length()); + return std::make_pair (result.first,result.second.length()); else return std::make_pair("",0); - //return result; }