mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 21:35:24 +00:00
Merge remote-tracking branch 'zini/master' into animations
This commit is contained in:
commit
d01351431c
@ -397,11 +397,24 @@ namespace MWGui
|
|||||||
|
|
||||||
void Console::setSelectedObject(const MWWorld::Ptr& object)
|
void Console::setSelectedObject(const MWWorld::Ptr& object)
|
||||||
{
|
{
|
||||||
mPtr = object;
|
if (!object.isEmpty())
|
||||||
if (!mPtr.isEmpty())
|
{
|
||||||
setTitle("#{sConsoleTitle} (" + mPtr.getCellRef().mRefID + ")");
|
if (object == mPtr)
|
||||||
else
|
{
|
||||||
setTitle("#{sConsoleTitle}");
|
setTitle("#{sConsoleTitle}");
|
||||||
|
mPtr=MWWorld::Ptr();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setTitle("#{sConsoleTitle} (" + object.getCellRef().mRefID + ")");
|
||||||
|
mPtr = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setTitle("#{sConsoleTitle}");
|
||||||
|
mPtr = MWWorld::Ptr();
|
||||||
|
}
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,11 +322,10 @@ void RenderingManager::update (float duration, bool paused)
|
|||||||
|
|
||||||
btVector3 btOrig(orig.x, orig.y, orig.z);
|
btVector3 btOrig(orig.x, orig.y, orig.z);
|
||||||
btVector3 btDest(dest.x, dest.y, dest.z);
|
btVector3 btDest(dest.x, dest.y, dest.z);
|
||||||
std::pair<std::string,float> test = mPhysicsEngine->rayTest(btOrig, btDest);
|
std::pair<bool, float> test = mPhysicsEngine->sphereCast(mRendering.getCamera()->getNearClipDistance()*2.5, btOrig, btDest);
|
||||||
if (!test.first.empty()) {
|
if (test.first)
|
||||||
mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
|
mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mOcclusionQuery->update(duration);
|
mOcclusionQuery->update(duration);
|
||||||
|
|
||||||
|
@ -33,23 +33,23 @@ namespace MWWorld
|
|||||||
class MovementSolver
|
class MovementSolver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static bool stepMove(Ogre::Vector3& position, const Ogre::Vector3 &velocity, float remainingTime,
|
static bool stepMove(Ogre::Vector3& position, const Ogre::Quaternion& orient, const Ogre::Vector3 &velocity, float remainingTime,
|
||||||
const Ogre::Vector3 &halfExtents, bool isInterior,
|
const Ogre::Vector3 &halfExtents, bool isInterior,
|
||||||
OEngine::Physic::PhysicEngine *engine)
|
OEngine::Physic::PhysicEngine *engine)
|
||||||
{
|
{
|
||||||
traceResults trace; // no initialization needed
|
traceResults trace; // no initialization needed
|
||||||
|
|
||||||
newtrace(&trace, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize),
|
newtrace(&trace, orient, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize),
|
||||||
halfExtents, isInterior, engine);
|
halfExtents, isInterior, engine);
|
||||||
if(trace.fraction == 0.0f)
|
if(trace.fraction == 0.0f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
newtrace(&trace, trace.endpos, trace.endpos + velocity*remainingTime,
|
newtrace(&trace, orient, trace.endpos, trace.endpos + velocity*remainingTime,
|
||||||
halfExtents, isInterior, engine);
|
halfExtents, isInterior, engine);
|
||||||
if(trace.fraction == 0.0f || (trace.fraction != 1.0f && getSlope(trace.planenormal) > sMaxSlope))
|
if(trace.fraction == 0.0f || (trace.fraction != 1.0f && getSlope(trace.planenormal) > sMaxSlope))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
newtrace(&trace, trace.endpos, trace.endpos-Ogre::Vector3(0.0f,0.0f,sStepSize), halfExtents, isInterior, engine);
|
newtrace(&trace, orient, trace.endpos, trace.endpos-Ogre::Vector3(0.0f,0.0f,sStepSize), halfExtents, isInterior, engine);
|
||||||
if(getSlope(trace.planenormal) <= sMaxSlope)
|
if(getSlope(trace.planenormal) <= sMaxSlope)
|
||||||
{
|
{
|
||||||
// only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
|
// only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
|
||||||
@ -105,24 +105,19 @@ namespace MWWorld
|
|||||||
physicActor->enableCollisions(false);
|
physicActor->enableCollisions(false);
|
||||||
|
|
||||||
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
|
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
|
||||||
|
halfExtents.z = 1; // we trace the feet only, so we use a very thin box
|
||||||
|
|
||||||
Ogre::Vector3 newPosition = position;
|
Ogre::Vector3 newPosition = position;
|
||||||
|
|
||||||
traceResults trace; //no initialization needed
|
traceResults trace; //no initialization needed
|
||||||
|
|
||||||
int maxHeight = 400.f;
|
int maxHeight = 200.f;
|
||||||
int steps = 100;
|
newtrace(&trace, Ogre::Quaternion::IDENTITY, newPosition, newPosition-Ogre::Vector3(0,0,maxHeight), halfExtents, isInterior, engine);
|
||||||
for (int i=0; i<steps; ++i)
|
|
||||||
{
|
|
||||||
newtrace(&trace, newPosition, newPosition-Ogre::Vector3(0,0,maxHeight / steps), halfExtents, isInterior, engine);
|
|
||||||
if(trace.fraction < 1.0f)
|
if(trace.fraction < 1.0f)
|
||||||
hit = true;
|
hit = true;
|
||||||
newPosition = trace.endpos;
|
newPosition = trace.endpos;
|
||||||
}
|
|
||||||
|
|
||||||
newPosition = trace.endpos;
|
physicActor->setOnGround(hit && getSlope(trace.planenormal) <= sMaxSlope);
|
||||||
|
|
||||||
physicActor->setOnGround(hit);
|
|
||||||
physicActor->enableCollisions(wasCollisionMode);
|
physicActor->enableCollisions(wasCollisionMode);
|
||||||
|
|
||||||
if (hit)
|
if (hit)
|
||||||
@ -154,7 +149,7 @@ namespace MWWorld
|
|||||||
bool isInterior = !ptr.getCell()->isExterior();
|
bool isInterior = !ptr.getCell()->isExterior();
|
||||||
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
|
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
|
||||||
physicActor->enableCollisions(false);
|
physicActor->enableCollisions(false);
|
||||||
|
Ogre::Quaternion orient = Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
Ogre::Vector3 velocity;
|
Ogre::Vector3 velocity;
|
||||||
if(!gravity)
|
if(!gravity)
|
||||||
{
|
{
|
||||||
@ -167,7 +162,7 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
if(!(movement.z > 0.0f))
|
if(!(movement.z > 0.0f))
|
||||||
{
|
{
|
||||||
newtrace(&trace, position, position-Ogre::Vector3(0,0,4), halfExtents, isInterior, engine);
|
newtrace(&trace, orient, position, position-Ogre::Vector3(0,0,4), halfExtents, isInterior, engine);
|
||||||
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
|
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
|
||||||
onground = true;
|
onground = true;
|
||||||
}
|
}
|
||||||
@ -188,7 +183,7 @@ namespace MWWorld
|
|||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
do {
|
do {
|
||||||
// trace to where character would go if there were no obstructions
|
// trace to where character would go if there were no obstructions
|
||||||
newtrace(&trace, newPosition, newPosition+clippedVelocity*remainingTime, halfExtents, isInterior, engine);
|
newtrace(&trace, orient, newPosition, newPosition+clippedVelocity*remainingTime, halfExtents, isInterior, engine);
|
||||||
newPosition = trace.endpos;
|
newPosition = trace.endpos;
|
||||||
remainingTime = remainingTime * (1.0f-trace.fraction);
|
remainingTime = remainingTime * (1.0f-trace.fraction);
|
||||||
|
|
||||||
@ -207,7 +202,7 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
// Can't walk on this. Try to step up onto it.
|
// Can't walk on this. Try to step up onto it.
|
||||||
if((gravity && !onground) ||
|
if((gravity && !onground) ||
|
||||||
!stepMove(newPosition, velocity, remainingTime, halfExtents, isInterior, engine))
|
!stepMove(newPosition, orient, velocity, remainingTime, halfExtents, isInterior, engine))
|
||||||
{
|
{
|
||||||
Ogre::Vector3 resultantDirection = trace.planenormal.crossProduct(up);
|
Ogre::Vector3 resultantDirection = trace.planenormal.crossProduct(up);
|
||||||
resultantDirection.normalise();
|
resultantDirection.normalise();
|
||||||
@ -225,7 +220,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
if(onground)
|
if(onground)
|
||||||
{
|
{
|
||||||
newtrace(&trace, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), halfExtents, isInterior, engine);
|
newtrace(&trace, orient, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), halfExtents, isInterior, engine);
|
||||||
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
|
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
|
||||||
newPosition.z = trace.endpos.z + 2.0f;
|
newPosition.z = trace.endpos.z + 2.0f;
|
||||||
else
|
else
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/compiler/locals.hpp>
|
#include <components/compiler/locals.hpp>
|
||||||
|
|
||||||
|
#include <boost/math/special_functions/sign.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
@ -909,7 +911,7 @@ namespace MWWorld
|
|||||||
float terrainHeight = mRendering->getTerrainHeightAt(pos);
|
float terrainHeight = mRendering->getTerrainHeightAt(pos);
|
||||||
|
|
||||||
if (pos.z < terrainHeight)
|
if (pos.z < terrainHeight)
|
||||||
pos.z = terrainHeight+400; // place slightly above. will snap down to ground with code below
|
pos.z = terrainHeight+5; // place slightly above. will snap down to ground with code below
|
||||||
|
|
||||||
ptr.getRefData().getPosition().pos[2] = pos.z;
|
ptr.getRefData().getPosition().pos[2] = pos.z;
|
||||||
|
|
||||||
@ -971,6 +973,8 @@ namespace MWWorld
|
|||||||
if(duration <= 0.0f)
|
if(duration <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
processDoors(duration);
|
||||||
|
|
||||||
PtrMovementList::const_iterator player(actors.end());
|
PtrMovementList::const_iterator player(actors.end());
|
||||||
for(PtrMovementList::const_iterator iter(actors.begin());iter != actors.end();iter++)
|
for(PtrMovementList::const_iterator iter(actors.begin());iter != actors.end();iter++)
|
||||||
{
|
{
|
||||||
@ -996,8 +1000,6 @@ namespace MWWorld
|
|||||||
moveObjectImp(player->first, vec.x, vec.y, vec.z);
|
moveObjectImp(player->first, vec.x, vec.y, vec.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
processDoors(duration);
|
|
||||||
|
|
||||||
mPhysEngine->stepSimulation (duration);
|
mPhysEngine->stepSimulation (duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1020,6 +1022,7 @@ namespace MWWorld
|
|||||||
mPhysics->getObjectAABB(it->first, min, max);
|
mPhysics->getObjectAABB(it->first, min, max);
|
||||||
Ogre::Vector3 dimensions = max-min;
|
Ogre::Vector3 dimensions = max-min;
|
||||||
|
|
||||||
|
/// \todo should use convexSweepTest here
|
||||||
std::vector<std::string> collisions = mPhysics->getCollisions(it->first);
|
std::vector<std::string> collisions = mPhysics->getCollisions(it->first);
|
||||||
for (std::vector<std::string>::iterator cit = collisions.begin(); cit != collisions.end(); ++cit)
|
for (std::vector<std::string>::iterator cit = collisions.begin(); cit != collisions.end(); ++cit)
|
||||||
{
|
{
|
||||||
@ -1032,7 +1035,11 @@ namespace MWWorld
|
|||||||
Ogre::Vector3 relativePos = it->first.getRefData().getBaseNode()->
|
Ogre::Vector3 relativePos = it->first.getRefData().getBaseNode()->
|
||||||
convertWorldToLocalPosition(ptr.getRefData().getBaseNode()->_getDerivedPosition());
|
convertWorldToLocalPosition(ptr.getRefData().getBaseNode()->_getDerivedPosition());
|
||||||
|
|
||||||
float axisToCheck = (dimensions.x > dimensions.y) ? relativePos.y : -relativePos.x;
|
float axisToCheck;
|
||||||
|
if (dimensions.x > dimensions.y)
|
||||||
|
axisToCheck = relativePos.y * boost::math::sign((min+max).y);
|
||||||
|
else
|
||||||
|
axisToCheck = relativePos.x * boost::math::sign((min+max).x);
|
||||||
if (axisToCheck >= 0)
|
if (axisToCheck >= 0)
|
||||||
targetRot = std::min(std::max(0.f, oldRot + diff*0.5f), 90.f);
|
targetRot = std::min(std::max(0.f, oldRot + diff*0.5f), 90.f);
|
||||||
else
|
else
|
||||||
|
@ -622,6 +622,41 @@ namespace Physic
|
|||||||
return std::pair<std::string,float>(name,d);
|
return std::pair<std::string,float>(name,d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// callback that ignores player in results
|
||||||
|
struct OurClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OurClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld)
|
||||||
|
: btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld) {}
|
||||||
|
|
||||||
|
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
|
||||||
|
{
|
||||||
|
if (const RigidBody* body = dynamic_cast<const RigidBody*>(convexResult.m_hitCollisionObject))
|
||||||
|
if (body->mName == "player")
|
||||||
|
return 0;
|
||||||
|
return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<bool, float> PhysicEngine::sphereCast (float radius, btVector3& from, btVector3& to)
|
||||||
|
{
|
||||||
|
OurClosestConvexResultCallback callback(from, to);
|
||||||
|
callback.m_collisionFilterMask = OEngine::Physic::CollisionType_World;
|
||||||
|
|
||||||
|
btSphereShape shape(radius);
|
||||||
|
const btQuaternion btrot(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
btTransform from_ (btrot, from);
|
||||||
|
btTransform to_ (btrot, to);
|
||||||
|
|
||||||
|
dynamicsWorld->convexSweepTest(&shape, from_, to_, callback);
|
||||||
|
|
||||||
|
if (callback.hasHit())
|
||||||
|
return std::make_pair(true, callback.m_closestHitFraction);
|
||||||
|
else
|
||||||
|
return std::make_pair(false, 1);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(btVector3& from, btVector3& to)
|
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(btVector3& from, btVector3& to)
|
||||||
{
|
{
|
||||||
MyRayResultCallback resultCallback1;
|
MyRayResultCallback resultCallback1;
|
||||||
|
@ -298,6 +298,9 @@ namespace Physic
|
|||||||
*/
|
*/
|
||||||
std::vector< std::pair<float, std::string> > rayTest2(btVector3& from, btVector3& to);
|
std::vector< std::pair<float, std::string> > rayTest2(btVector3& from, btVector3& to);
|
||||||
|
|
||||||
|
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
|
||||||
|
///< @return (hit, relative distance)
|
||||||
|
|
||||||
std::vector<std::string> getCollisions(const std::string& name);
|
std::vector<std::string> getCollisions(const std::string& name);
|
||||||
|
|
||||||
//event list of non player object
|
//event list of non player object
|
||||||
|
@ -15,16 +15,16 @@ enum traceWorldType
|
|||||||
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
||||||
};
|
};
|
||||||
|
|
||||||
void newtrace(traceResults *results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, bool isInterior, OEngine::Physic::PhysicEngine *enginePass) //Traceobj was a Aedra Object
|
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 btstart(start.x, start.y, start.z + BBHalfExtents.z);
|
||||||
const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z);
|
const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z);
|
||||||
const btQuaternion btrot(0.0f, 0.0f, 0.0f); //y, x, z
|
const btQuaternion btorient (orient.x, orient.y, orient.z, orient.w);
|
||||||
|
|
||||||
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||||
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
|
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
|
||||||
const btTransform from(btrot, btstart);
|
const btTransform from(btorient, btstart);
|
||||||
const btTransform to(btrot, btend);
|
const btTransform to(btorient, btend);
|
||||||
|
|
||||||
btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend);
|
btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend);
|
||||||
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World;
|
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World;
|
||||||
|
@ -21,6 +21,6 @@ struct traceResults
|
|||||||
float fraction;
|
float fraction;
|
||||||
};
|
};
|
||||||
|
|
||||||
void newtrace(traceResults *results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user