1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-01 00:45:34 +00:00

Merge remote-tracking branch 'gus/AI'

This commit is contained in:
Marc Zinnschlag 2013-03-06 19:05:55 +01:00
commit 7e100c36b5
6 changed files with 60 additions and 63 deletions

View file

@ -274,28 +274,31 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
if (!isPlayer && isActive)
{
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(rot.z), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * ptr.getRefData().getBaseNode()->getOrientation() : xr * yr * zr;
rot.x = newo.x;
rot.y = newo.y;
rot.z = newo.z;
Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zref(Ogre::Radian(-ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * (xref*yref*zref) : xr * yr * zr;
Ogre::Matrix3 mat;
newo.ToRotationMatrix(mat);
Ogre::Radian ax,ay,az;
mat.ToEulerAnglesXYZ(ax,ay,az);
rot.x = -ax.valueRadians();
rot.y = -ay.valueRadians();
rot.z = -az.valueRadians();
ptr.getRefData().getBaseNode()->setOrientation(newo);
}
else if(isPlayer)
{
rot.x = mPlayer->getPitch();
rot.x = -mPlayer->getPitch();
rot.z = mPlayer->getYaw();
}
else if (adjust)
{
// Stored and passed in radians
float *f = ptr.getRefData().getPosition().rot;
rot.x += f[0];
rot.y += f[1];
rot.z += f[2];
}
return force;
}

View file

@ -119,15 +119,15 @@ namespace MWScript
if (axis == "x")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees());
}
else if (axis == "y")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees());
}
else if (axis == "z")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees());
}
else
throw std::runtime_error ("invalid ration axis: " + axis);
@ -148,15 +148,15 @@ namespace MWScript
if (axis=="x")
{
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
}
else if (axis=="y")
{
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
}
else if (axis=="z")
{
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees());
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
}
else
throw std::runtime_error ("invalid ration axis: " + axis);
@ -241,15 +241,15 @@ namespace MWScript
if(axis == "x")
{
runtime.push(ptr.getCellRef().mPos.pos[0]);
runtime.push(ptr.getRefData().getPosition().pos[0]);
}
else if(axis == "y")
{
runtime.push(ptr.getCellRef().mPos.pos[1]);
runtime.push(ptr.getRefData().getPosition().pos[1]);
}
else if(axis == "z")
{
runtime.push(ptr.getCellRef().mPos.pos[2]);
runtime.push(ptr.getRefData().getPosition().pos[2]);
}
else
throw std::runtime_error ("invalid axis: " + axis);

View file

@ -99,9 +99,9 @@ namespace MWWorld
if(!physicActor || !physicActor->getCollisionMode())
{
// FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why?
return position + (Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
return position + (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
movement;
}
@ -109,14 +109,15 @@ namespace MWWorld
bool onground = false;
float remainingTime = time;
bool isInterior = !ptr.getCell()->isExterior();
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
physicActor->enableCollisions(false);
Ogre::Vector3 velocity;
if(!gravity)
{
velocity = (Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
Ogre::Quaternion(Ogre::Radian( -refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
movement / time;
}
else
@ -127,9 +128,7 @@ namespace MWWorld
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
onground = true;
}
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) *
movement / time;
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*movement / time;
velocity.z += physicActor->getVerticalForce();
}
@ -191,7 +190,7 @@ namespace MWWorld
}
physicActor->setOnGround(onground);
physicActor->setVerticalForce(!onground ? clippedVelocity.z - time*627.2f : 0.0f);
physicActor->enableCollisions(true);
return newPosition;
}
};

View file

@ -13,18 +13,9 @@
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#define BIT(x) (1<<(x))
namespace OEngine {
namespace Physic
{
enum collisiontypes {
COL_NOTHING = 0, //<Collide with nothing
COL_WORLD = BIT(0), //<Collide with world objects
COL_ACTOR_INTERNAL = BIT(1), //<Collide internal capsule
COL_ACTOR_EXTERNAL = BIT(2), //<collide with external capsule
COL_RAYCASTING = BIT(3)
};
PhysicActor::PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale)
: mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0)
@ -37,6 +28,8 @@ namespace Physic
Ogre::Quaternion inverse = mBoxRotation.Inverse();
mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w);
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
//mBody->setCollisionFlags(COL_NOTHING);
//mBody->setMas
}
PhysicActor::~PhysicActor()
@ -50,6 +43,8 @@ namespace Physic
void PhysicActor::enableCollisions(bool collision)
{
if(collision && !collisionMode) mBody->translate(btVector3(0,0,-1000));
if(!collision && collisionMode) mBody->translate(btVector3(0,0,1000));
collisionMode = collision;
}
@ -310,7 +305,7 @@ namespace Physic
mHeightFieldMap [name] = hf;
dynamicsWorld->addRigidBody(body,COL_WORLD,COL_WORLD|COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL);
dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal);
}
void PhysicEngine::removeHeightField(int x, int y)
@ -397,11 +392,11 @@ namespace Physic
return;
if(body->mCollide)
{
dynamicsWorld->addRigidBody(body,COL_WORLD,COL_WORLD|COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL);
dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal);
}
else
{
dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD);
dynamicsWorld->addRigidBody(body,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_World);
}
body->setActivationState(DISABLE_DEACTIVATION);
if(addToMap){
@ -535,7 +530,7 @@ namespace Physic
float d1 = 10000.;
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
resultCallback1.m_collisionFilterMask = COL_WORLD|COL_RAYCASTING;
resultCallback1.m_collisionFilterMask = CollisionType_World|CollisionType_Raycasting;
dynamicsWorld->rayTest(from, to, resultCallback1);
if (resultCallback1.hasHit())
{
@ -545,7 +540,7 @@ namespace Physic
}
btCollisionWorld::ClosestRayResultCallback resultCallback2(from, to);
resultCallback2.m_collisionFilterMask = COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL;
resultCallback2.m_collisionFilterMask = CollisionType_ActorInternal|CollisionType_ActorExternal;
dynamicsWorld->rayTest(from, to, resultCallback2);
float d2 = 10000.;
if (resultCallback2.hasHit())
@ -564,12 +559,12 @@ namespace Physic
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(btVector3& from, btVector3& to)
{
MyRayResultCallback resultCallback1;
resultCallback1.m_collisionFilterMask = COL_WORLD|COL_RAYCASTING;
resultCallback1.m_collisionFilterMask = CollisionType_World|CollisionType_Raycasting;
dynamicsWorld->rayTest(from, to, resultCallback1);
std::vector< std::pair<float, const btCollisionObject*> > results = resultCallback1.results;
MyRayResultCallback resultCallback2;
resultCallback2.m_collisionFilterMask = COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL;
resultCallback2.m_collisionFilterMask = CollisionType_ActorInternal|CollisionType_ActorExternal;
dynamicsWorld->rayTest(from, to, resultCallback2);
std::vector< std::pair<float, const btCollisionObject*> > actorResults = resultCallback2.results;

View file

@ -43,6 +43,14 @@ namespace Physic
class PhysicEngine;
class RigidBody;
enum CollisionType {
CollisionType_Nothing = 0, //<Collide with nothing
CollisionType_World = 1<<0, //<Collide with world objects
CollisionType_ActorInternal = 1<<1, //<Collide internal capsule Still Used?
CollisionType_ActorExternal = 1<<2, //<collide with external capsule Still used?
CollisionType_Raycasting = 1<<3 //Still used?
};
/**
*This is just used to be able to name objects.
*/
@ -129,8 +137,9 @@ namespace Physic
void operator delete (void * Data) { _aligned_free (Data); }
#endif
private:
OEngine::Physic::RigidBody* mBody;
Ogre::Vector3 mBoxScaledTranslation;
btQuaternion mBoxRotationInverse;

View file

@ -8,7 +8,6 @@
#include "physic.hpp"
enum traceWorldType
{
collisionWorldTrace = 1,
@ -16,14 +15,6 @@ enum traceWorldType
bothWorldTrace = collisionWorldTrace | pickWorldTrace
};
enum collaborativePhysicsType
{
No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass)
Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics)
Only_Pickup = 2, // This object only has pickup physics but no collision physics (example: items dropped on the ground)
Both_Physics = 3 // This object has both kinds of physics (example: activators)
};
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
{
const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z);
@ -36,7 +27,7 @@ void newtrace(traceResults *results, const Ogre::Vector3& start, const Ogre::Vec
const btTransform to(btrot, btend);
btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend);
newTraceCallback.m_collisionFilterMask = Only_Collision;
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_Raycasting;
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);