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

Merge remote-tracking branch 'gus/AIFix'

This commit is contained in:
Marc Zinnschlag 2013-05-08 20:31:57 +02:00
commit c80ffa0a16
9 changed files with 53 additions and 27 deletions

View file

@ -245,6 +245,9 @@ namespace MWBase
virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0;
///< Run physics simulation and modify \a world accordingly.
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
///< cast a Ray and return true if there is an object in the ray path.
virtual bool toggleCollisionMode() = 0;
///< Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity.

View file

@ -1,4 +1,8 @@
#include "pathfinding.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/adjacency_list.hpp>
#include "boost/tuple/tuple.hpp"
@ -169,15 +173,20 @@ namespace MWMechanics
void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
const ESM::Pathgrid* pathGrid,float xCell,float yCell)
{
int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ);
int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ);
if(start != -1 && end != -1)
//first check if there is an obstacle
if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX,startPoint.mY,startPoint.mZ,
endPoint.mX,endPoint.mY,endPoint.mZ) )
{
PathGridGraph graph = buildGraph(pathGrid,xCell,yCell);
mPath = findPath(start,end,graph);
}
std::cout << "hit";
int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ);
int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ);
if(start != -1 && end != -1)
{
PathGridGraph graph = buildGraph(pathGrid,xCell,yCell);
mPath = findPath(start,end,graph);
}
}
mPath.push_back(endPoint);
mIsPathConstructed = true;
}

View file

@ -333,14 +333,13 @@ namespace MWWorld
return result;
}
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly,bool ignoreHeightMap)
{
btVector3 _from, _to;
_from = btVector3(from.x, from.y, from.z);
_to = btVector3(to.x, to.y, to.z);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to, raycastingObjectOnly,ignoreHeightMap);
return !(result.first == "");
}

View file

@ -62,8 +62,8 @@ namespace MWWorld
btVector3 getRayPoint(float extent, float mouseX, float mouseY);
// cast ray, return true if it hit something
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
// cast ray, return true if it hit something. if raycasringObjectOnlt is set to false, it ignores NPCs and objects with no collisions.
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
std::pair<bool, Ogre::Vector3>
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);

View file

@ -1042,6 +1042,13 @@ namespace MWWorld
mPhysEngine->stepSimulation (duration);
}
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
{
Ogre::Vector3 a(x1,y1,z1);std::cout << x1 << " " << x2;
Ogre::Vector3 b(x2,y2,z2);
return mPhysics->castRay(a,b,false,true);
}
void World::processDoors(float duration)
{
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin();

View file

@ -279,6 +279,9 @@ namespace MWWorld
virtual void doPhysics(const PtrMovementList &actors, float duration);
///< Run physics simulation and modify \a world accordingly.
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2);
///< cast a Ray and return true if there is an object in the ray path.
virtual bool toggleCollisionMode();
///< Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity.

View file

@ -28,7 +28,7 @@ namespace Physic
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true);
Ogre::Quaternion inverse = mBoxRotation.Inverse();
mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w);
mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map
mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map
}
PhysicActor::~PhysicActor()
@ -109,7 +109,7 @@ namespace Physic
//Create the newly scaled rigid body
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot);
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot, 0, 0, true);
mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map
mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map
}
Ogre::Vector3 PhysicActor::getHalfExtents() const
@ -331,8 +331,8 @@ namespace Physic
mHeightFieldMap [name] = hf;
dynamicsWorld->addRigidBody(body,CollisionType_World|CollisionType_Raycasting,
CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal|CollisionType_Raycasting);
dynamicsWorld->addRigidBody(body,CollisionType_HeightMap|CollisionType_Raycasting,
CollisionType_World|CollisionType_Actor|CollisionType_Raycasting);
}
void PhysicEngine::removeHeightField(int x, int y)
@ -422,15 +422,17 @@ namespace Physic
}
void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap, RigidBody* raycastingBody)
void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap, RigidBody* raycastingBody,bool actor)
{
if(!body && !raycastingBody)
return; // nothing to do
const std::string& name = (body ? body->mName : raycastingBody->mName);
if (body)
dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal);
if (body){
if(actor) dynamicsWorld->addRigidBody(body,CollisionType_Actor,CollisionType_World|CollisionType_HeightMap);
else dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_Actor|CollisionType_HeightMap);
}
if (raycastingBody)
dynamicsWorld->addRigidBody(raycastingBody,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_World);
@ -603,14 +605,17 @@ namespace Physic
{
}
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to)
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap)
{
std::string name = "";
float d = -1;
float d1 = 10000.;
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting;
if(raycastingObjectOnly) resultCallback1.m_collisionFilterMask = CollisionType_Raycasting;
else resultCallback1.m_collisionFilterMask = CollisionType_World;
if(!ignoreHeightMap) resultCallback1.m_collisionFilterMask = resultCallback1.m_collisionFilterMask|| CollisionType_HeightMap;
dynamicsWorld->rayTest(from, to, resultCallback1);
if (resultCallback1.hasHit())
{
@ -641,7 +646,7 @@ namespace Physic
std::pair<bool, float> PhysicEngine::sphereCast (float radius, btVector3& from, btVector3& to)
{
OurClosestConvexResultCallback callback(from, to);
callback.m_collisionFilterMask = OEngine::Physic::CollisionType_World;
callback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap;
btSphereShape shape(radius);
const btQuaternion btrot(0.0f, 0.0f, 0.0f);

View file

@ -46,8 +46,8 @@ namespace Physic
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_Actor = 1<<1, //<Collide sith actors
CollisionType_HeightMap = 1<<2, //<collide with heightmap
CollisionType_Raycasting = 1<<3 //Still used?
};
@ -226,7 +226,7 @@ namespace Physic
/**
* Add a RigidBody to the simulation
*/
void addRigidBody(RigidBody* body, bool addToMap = true, RigidBody* raycastingBody = NULL);
void addRigidBody(RigidBody* body, bool addToMap = true, RigidBody* raycastingBody = NULL,bool actor = false);
/**
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
@ -293,7 +293,7 @@ namespace Physic
/**
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
*/
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to);
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
/**
* Return all objects hit by a ray.

View file

@ -27,7 +27,7 @@ void newtrace(traceResults *results, const Ogre::Quaternion& orient, const Ogre:
const btTransform to(btorient, btend);
btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend);
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World;
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap;
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);