diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index ea013bc7a..65cc806ea 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -87,36 +87,25 @@ namespace MWWorld const ESM::Position &refpos = ptr.getRefData().getPosition(); Ogre::Vector3 position(refpos.pos); - bool hit=false; - bool isInterior = !ptr.getCell()->isExterior(); - OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle()); if (!physicActor) return position; - bool wasCollisionMode = physicActor->getCollisionMode(); - physicActor->enableCollisions(false); - - Ogre::Vector3 halfExtents = physicActor->getHalfExtents(); - halfExtents.z = 1; // we trace the feet only, so we use a very thin box + const int maxHeight = 64.f; + Ogre::Vector3 newPosition = position+Ogre::Vector3(0.0f, 0.0f, 4.0f); - Ogre::Vector3 newPosition = position; + traceResults trace; + actortrace(&trace, physicActor->getCollisionBody(), newPosition, newPosition-Ogre::Vector3(0,0,maxHeight), engine); + if(trace.fraction >= 1.0f) + return position; - traceResults trace; //no initialization needed + physicActor->setOnGround(getSlope(trace.planenormal) <= sMaxSlope); - int maxHeight = 200.f; - newtrace(&trace, Ogre::Quaternion::IDENTITY, newPosition, newPosition-Ogre::Vector3(0,0,maxHeight), halfExtents, isInterior, engine); - if(trace.fraction < 1.0f) - hit = true; newPosition = trace.endpos; + newPosition.z -= physicActor->getHalfExtents().z; + newPosition.z += 4.0f; - physicActor->setOnGround(hit && getSlope(trace.planenormal) <= sMaxSlope); - if (wasCollisionMode) - physicActor->enableCollisions(true); - - if(!hit) - return position; - return newPosition+Ogre::Vector3(0,0,4); + return newPosition; } static Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 08c42d9d0..744462a0c 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -9,39 +9,6 @@ #include "physic.hpp" -void newtrace(traceResults *results, const Ogre::Quaternion& orient, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, bool isInterior, OEngine::Physic::PhysicEngine *enginePass) //Traceobj was a Aedra Object -{ - const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z); - const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z); - const btQuaternion btorient (orient.x, orient.y, orient.z, orient.w); - - const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); - //const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2); - const btTransform from(btorient, btstart); - const btTransform to(btorient, btend); - - btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend); - newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap|OEngine::Physic::CollisionType_Actor; - - enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback); - - // Copy the hit data over to our trace results struct: - if(newTraceCallback.hasHit()) - { - const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld; - results->fraction = newTraceCallback.m_closestHitFraction; - results->planenormal = Ogre::Vector3(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z()); - results->endpos = (end-start)*results->fraction + start; - } - else - { - results->endpos = end; - results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f); - results->fraction = 1.0f; - } -} - - class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: @@ -62,7 +29,7 @@ public: else { ///need to transform normal into worldspace - hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; } // NOTE : m_hitNormalLocal is not always vertical on the ground with a capsule or a box... diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index 79c6e72ef..6353d6cfa 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -24,7 +24,6 @@ struct traceResults float fraction; }; -void newtrace(traceResults *results, const Ogre::Quaternion& orient, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); void actortrace(traceResults *results, btCollisionObject *actor, const Ogre::Vector3& start, const Ogre::Vector3& end, OEngine::Physic::PhysicEngine *enginePass); #endif