diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 60fa8d82b4..9cfeb854fd 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" @@ -268,6 +271,7 @@ namespace MWWorld std::pair result; /*auto*/ result = mEngine->rayTest(origin, dest); result.second *= queryDistance; + return std::make_pair (result.second, result.first); } @@ -312,11 +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; - return result; + 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(); + + 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 (result.first,result.second.length()); + else + return std::make_pair("",0); } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 968d2fbe7d..da459ac523 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -546,11 +546,68 @@ 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::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(); + if(d 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; + //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) { RigidBody* body = getRigidBody(name); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index a1d4816d3b..32af0da4e3 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -307,6 +307,8 @@ public: std::pair sphereCast (float radius, btVector3& from, btVector3& to); ///< @return (hit, relative distance) + std::pair sphereTest(float radius,btVector3& pos); + std::vector getCollisions(const std::string& name); //event list of non player object