Remove bullet raycasting shapes, to be replaced with OSG ray casts

c++11
scrawl 10 years ago
parent a592c1a1c2
commit d9d84bd7b2

@ -519,58 +519,6 @@ namespace MWWorld
return mEngine;
}
std::pair<float, std::string> PhysicsSystem::getFacedHandle(float queryDistance)
{
Ray ray;// = mRender.getCamera()->getCameraToViewportRay(0.5, 0.5);
Ogre::Vector3 origin_ = ray.getOrigin();
btVector3 origin(origin_.x, origin_.y, origin_.z);
Ogre::Vector3 dir_ = ray.getDirection().normalisedCopy();
btVector3 dir(dir_.x, dir_.y, dir_.z);
btVector3 dest = origin + dir * queryDistance;
std::pair <std::string, float> result = mEngine->rayTest(origin, dest);
result.second *= queryDistance;
return std::make_pair (result.second, result.first);
}
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float queryDistance)
{
Ray ray;// = mRender.getCamera()->getCameraToViewportRay(0.5, 0.5);
Ogre::Vector3 origin_ = ray.getOrigin();
btVector3 origin(origin_.x, origin_.y, origin_.z);
Ogre::Vector3 dir_ = ray.getDirection().normalisedCopy();
btVector3 dir(dir_.x, dir_.y, dir_.z);
btVector3 dest = origin + dir * queryDistance;
std::vector < std::pair <float, std::string> > results;
/* auto */ results = mEngine->rayTest2(origin, dest);
std::vector < std::pair <float, std::string> >::iterator i;
for (/* auto */ i = results.begin (); i != results.end (); ++i)
i->first *= queryDistance;
return results;
}
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float mouseX, float mouseY, float queryDistance)
{
Ray ray;// = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
Ogre::Vector3 from = ray.getOrigin();
Ogre::Vector3 to = ray.getPoint(queryDistance);
btVector3 _from, _to;
_from = btVector3(from.x, from.y, from.z);
_to = btVector3(to.x, to.y, to.z);
std::vector < std::pair <float, std::string> > results;
/* auto */ results = mEngine->rayTest2(_from,_to);
std::vector < std::pair <float, std::string> >::iterator i;
for (/* auto */ i = results.begin (); i != results.end (); ++i)
i->first *= queryDistance;
return results;
}
std::pair<std::string,Ogre::Vector3> PhysicsSystem::getHitContact(const std::string &name,
const Ogre::Vector3 &origin,
const Ogre::Quaternion &orient,
@ -600,13 +548,13 @@ namespace MWWorld
}
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly,bool ignoreHeightMap)
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, 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, raycastingObjectOnly,ignoreHeightMap);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to,ignoreHeightMap);
return !(result.first == "");
}
@ -626,30 +574,6 @@ namespace MWWorld
return std::make_pair(true, ray.getPoint(len * test.second));
}
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal, std::string* hit)
{
Ogre::Ray ray;// = mRender.getCamera()->getCameraToViewportRay(
//mouseX,
//mouseY);
Ogre::Vector3 from = ray.getOrigin();
Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable
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, true, false, normal);
if (result.first == "")
return std::make_pair(false, Ogre::Vector3());
else
{
if (hit != NULL)
*hit = result.first;
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
}
}
std::vector<std::string> PhysicsSystem::getCollisions(const Ptr &ptr, int collisionGroup, int collisionMask)
{
return mEngine->getCollisions(ptr.getRefData().getBaseNodeOld()->getName(), collisionGroup, collisionMask);
@ -712,12 +636,6 @@ namespace MWWorld
mEngine->mDynamicsWorld->updateSingleAabb(body);
}
if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle, true))
{
body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z));
mEngine->mDynamicsWorld->updateSingleAabb(body);
}
// Actors update their AABBs every frame (DISABLE_DEACTIVATION), so no need to do it manually
if(OEngine::Physic::PhysicActor *physact = mEngine->getCharacter(handle))
physact->setPosition(position);
@ -742,14 +660,6 @@ namespace MWWorld
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
mEngine->mDynamicsWorld->updateSingleAabb(body);
}
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle, true))
{
if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL)
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
else
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
mEngine->mDynamicsWorld->updateSingleAabb(body);
}
}
void PhysicsSystem::scaleObject (const Ptr& ptr)
@ -762,9 +672,7 @@ namespace MWWorld
//model = Misc::ResourceHelpers::correctActorModelPath(model); // FIXME: scaling shouldn't require model
bool placeable = false;
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle,true))
placeable = body->mPlaceable;
else if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle,false))
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
placeable = body->mPlaceable;
removeObject(handle);
addObject(ptr, model, placeable);
@ -806,30 +714,6 @@ namespace MWWorld
throw std::logic_error ("can't find player");
}
bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)
{
// FIXME: since raycasting shapes are going away, this should use the osg ComputeBoundingBoxVisitor
std::string model = ptr.getClass().getModel(ptr);
//model = Misc::ResourceHelpers::correctActorModelPath(model);
if (model.empty()) {
return false;
}
btVector3 btMin, btMax;
float scale = ptr.getCellRef().getScale();
mEngine->getObjectAABB(model, scale, btMin, btMax);
min.x = btMin.x();
min.y = btMin.y();
min.z = btMin.z();
max.x = btMax.x();
max.y = btMax.y();
max.z = btMax.z();
return true;
}
void PhysicsSystem::queueObjectMovement(const Ptr &ptr, const Ogre::Vector3 &movement)
{
PtrVelocityList::iterator iter = mMovementQueue.begin();
@ -913,7 +797,6 @@ namespace MWWorld
void PhysicsSystem::stepSimulation(float dt)
{
animateCollisionShapes(mEngine->mAnimatedShapes, mEngine->mDynamicsWorld);
animateCollisionShapes(mEngine->mAnimatedRaycastingShapes, mEngine->mDynamicsWorld);
mEngine->stepSimulation(dt);
}

@ -60,29 +60,19 @@ namespace MWWorld
std::vector<std::string> getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask); ///< get handles this object collides with
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr, float maxHeight);
std::pair<float, std::string> getFacedHandle(float queryDistance);
std::pair<std::string,Ogre::Vector3> getHitContact(const std::string &name,
const Ogre::Vector3 &origin,
const Ogre::Quaternion &orientation,
float queryDistance);
std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance);
// 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);
// cast ray, return true if it hit something.
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to,bool ignoreHeightMap = false);
std::pair<bool, Ogre::Vector3>
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL, std::string* hit = NULL);
///< cast ray from the mouse, return true if it hit something and the first result
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
/// @param hit if non-NULL, the string handle of the hit object will be written there (if there is a hit)
OEngine::Physic::PhysicEngine* getEngine();
bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max);
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
/// be overwritten. Valid until the next call to applyQueuedMovement.
void queueObjectMovement(const Ptr &ptr, const Ogre::Vector3 &velocity);

@ -2724,13 +2724,14 @@ namespace MWWorld
origin += node->_getDerivedPosition();
}
#endif
/*
Ogre::Quaternion orient;
orient = Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
Ogre::Vector3 direction = orient.yAxis();
Ogre::Vector3 dest = origin + direction * distance;
std::vector<std::pair<float, std::string> > collisions = mPhysEngine->rayTest2(btVector3(origin.x, origin.y, origin.z), btVector3(dest.x, dest.y, dest.z));
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end(); ++cIt)
{
@ -2741,6 +2742,7 @@ namespace MWWorld
break;
}
}
*/
}
std::string selectedSpell = stats.getSpells().getSelectedSpell();

@ -52,9 +52,9 @@ add_component_dir (nifosg
nifloader controller particle userdata
)
#add_component_dir (nifbullet
# bulletnifloader
# )
add_component_dir (nifbullet
bulletnifloader
)
add_component_dir (to_utf8
to_utf8

@ -25,11 +25,9 @@ http://www.gnu.org/licenses/ .
#include <cstdio>
#include <OgreMatrix4.h>
#include <components/misc/stringops.hpp>
#include <components/nifcache/nifcache.hpp>
#include "../nif/niffile.hpp"
#include "../nif/node.hpp"
#include "../nif/data.hpp"
@ -43,11 +41,6 @@ http://www.gnu.org/licenses/ .
// For warning messages
#include <iostream>
// float infinity
#include <limits>
typedef unsigned char ubyte;
// Extract a list of keyframe-controlled nodes from a .kf file
// FIXME: this is a similar copy of OgreNifLoader::loadKf
void extractControlledNodes(Nif::NIFFilePtr kfFile, std::set<std::string>& controlled)
@ -116,14 +109,13 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
{
mShape = static_cast<OEngine::Physic::BulletShape *>(resource);
mResourceName = mShape->getName();
mShape->mCollide = false;
mBoundingBox = NULL;
mShape->mBoxTranslation = Ogre::Vector3(0,0,0);
mShape->mBoxRotation = Ogre::Quaternion::IDENTITY;
mShape->mBoxTranslation = osg::Vec3f(0,0,0);
mShape->mBoxRotation = osg::Quat();
mCompoundShape = NULL;
mStaticMesh = NULL;
Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(mResourceName.substr(0, mResourceName.length()-7)));
Nif::NIFFilePtr pnif;// (Nif::Cache::getInstance().load(mResourceName.substr(0, mResourceName.length()-7)));
Nif::NIFFile & nif = *pnif.get ();
if (nif.numRoots() < 1)
{
@ -140,7 +132,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
kfname.replace(kfname.size()-4, 4, ".kf");
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(kfname))
{
Nif::NIFFilePtr kf (Nif::Cache::getInstance().load(kfname));
Nif::NIFFilePtr kf;// (Nif::Cache::getInstance().load(kfname));
extractControlledNodes(kf, mControlledNodes);
}
@ -188,28 +180,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
else if (mStaticMesh)
mShape->mCollisionShape = new TriangleMeshShape(mStaticMesh,true);
}
//second pass which create a shape for raycasting.
mResourceName = mShape->getName();
mShape->mCollide = false;
mBoundingBox = NULL;
mStaticMesh = NULL;
mCompoundShape = NULL;
handleNode(node,0,true,true,false);
if (mCompoundShape)
{
mShape->mRaycastingShape = mCompoundShape;
if (mStaticMesh)
{
btTransform trans;
trans.setIdentity();
mCompoundShape->addChildShape(trans, new TriangleMeshShape(mStaticMesh,true));
}
}
else if (mStaticMesh)
mShape->mRaycastingShape = new TriangleMeshShape(mStaticMesh,true);
}
bool ManualBulletShapeLoader::hasAutoGeneratedCollision(Nif::Node const * rootNode)
@ -231,8 +201,7 @@ bool ManualBulletShapeLoader::hasAutoGeneratedCollision(Nif::Node const * rootNo
}
void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
bool isCollisionNode,
bool raycasting, bool isAnimated)
bool isCollisionNode, bool isAnimated)
{
// Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least.
@ -245,10 +214,7 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
if (mControlledNodes.find(node->name) != mControlledNodes.end())
isAnimated = true;
if (!raycasting)
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
else
isCollisionNode = isCollisionNode && (node->recType != Nif::RC_RootCollisionNode);
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
// Don't collide with AvoidNode shapes
if(node->recType == Nif::RC_AvoidNode)
@ -274,33 +240,26 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
// No collision. Use an internal flag setting to mark this.
flags |= 0x800;
}
else if (sd->string == "MRK" && !mShowMarkers && raycasting)
{
// Marker objects should be invisible, but still have collision.
// Except in the editor, the marker objects are visible.
return;
}
}
}
if (isCollisionNode || (mShape->mAutogenerated && !raycasting))
if (isCollisionNode || (mShape->mAutogenerated))
{
// NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
// It must be ignored completely.
// (occurs in tr_ex_imp_wall_arch_04.nif)
if(node->hasBounds)
{
if (flags & Nif::NiNode::Flag_BBoxCollision && !raycasting)
if (flags & Nif::NiNode::Flag_BBoxCollision)
{
mShape->mBoxTranslation = node->boundPos;
mShape->mBoxRotation = node->boundRot;
mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ));
//mShape->mBoxRotation = node->boundRot;
//mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ));
}
}
else if(node->recType == Nif::RC_NiTriShape)
{
mShape->mCollide = !(flags&0x800);
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, node->getWorldTransform(), raycasting, isAnimated);
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, Ogre::Matrix4()/*node->getWorldTransform()*/, isAnimated);
}
}
@ -312,13 +271,12 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
for(size_t i = 0;i < list.length();i++)
{
if(!list[i].empty())
handleNode(list[i].getPtr(), flags, isCollisionNode, raycasting, isAnimated);
handleNode(list[i].getPtr(), flags, isCollisionNode, isAnimated);
}
}
}
void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform,
bool raycasting, bool isAnimated)
void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool isAnimated)
{
assert(shape != NULL);
@ -329,12 +287,12 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
// If the object was marked "NCO" earlier, it shouldn't collide with
// anything. So don't do anything.
if ((flags & 0x800) && !raycasting)
if ((flags & 0x800))
{
return;
}
if (!collide && !bbcollide && hidden && !raycasting)
if (!collide && !bbcollide && hidden)
// This mesh apparently isn't being used for anything, so don't
// bother setting it up.
return;
@ -354,18 +312,18 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
childMesh->preallocateVertices(data->vertices.size());
childMesh->preallocateIndices(data->triangles.size());
const std::vector<Ogre::Vector3> &vertices = data->vertices;
const std::vector<short> &triangles = data->triangles;
//const std::vector<osg::Vec3f> &vertices = data->vertices;
//const std::vector<unsigned short> &triangles = data->triangles;
for(size_t i = 0;i < data->triangles.size();i+=3)
{
Ogre::Vector3 b1 = vertices[triangles[i+0]];
Ogre::Vector3 b2 = vertices[triangles[i+1]];
Ogre::Vector3 b3 = vertices[triangles[i+2]];
childMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
//Ogre::Vector3 b1 = vertices[triangles[i+0]];
//Ogre::Vector3 b2 = vertices[triangles[i+1]];
//Ogre::Vector3 b3 = vertices[triangles[i+2]];
//childMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
}
TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
//TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
float scale = shape->trafo.scale;
const Nif::Node* parent = shape;
@ -374,18 +332,15 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
parent = parent->parent;
scale *= parent->trafo.scale;
}
Ogre::Quaternion q = transform.extractQuaternion();
Ogre::Vector3 v = transform.getTrans();
childShape->setLocalScaling(btVector3(scale, scale, scale));
//Ogre::Quaternion q = transform.extractQuaternion();
//Ogre::Vector3 v = transform.getTrans();
//childShape->setLocalScaling(btVector3(scale, scale, scale));
btTransform trans(btQuaternion(q.x, q.y, q.z, q.w), btVector3(v.x, v.y, v.z));
//btTransform trans(btQuaternion(q.x, q.y, q.z, q.w), btVector3(v.x, v.y, v.z));
if (raycasting)
mShape->mAnimatedRaycastingShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
else
mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
//mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));
mCompoundShape->addChildShape(trans, childShape);
//mCompoundShape->addChildShape(trans, childShape);
}
else
{
@ -394,15 +349,17 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
// Static shape, just transform all vertices into position
const Nif::NiTriShapeData *data = shape->data.getPtr();
const std::vector<Ogre::Vector3> &vertices = data->vertices;
const std::vector<short> &triangles = data->triangles;
//const std::vector<osg::Vec3f> &vertices = data->vertices;
//const std::vector<unsigned short> &triangles = data->triangles;
for(size_t i = 0;i < data->triangles.size();i+=3)
{
Ogre::Vector3 b1 = transform*vertices[triangles[i+0]];
Ogre::Vector3 b2 = transform*vertices[triangles[i+1]];
Ogre::Vector3 b3 = transform*vertices[triangles[i+2]];
/*
osg::Vec3f b1 = transform*vertices[triangles[i+0]];
osg::Vec3f b2 = transform*vertices[triangles[i+1]];
osg::Vec3f b3 = transform*vertices[triangles[i+2]];
mStaticMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
*/
}
}
}
@ -422,9 +379,9 @@ bool findBoundingBox (const Nif::Node* node, Ogre::Vector3& halfExtents, Ogre::V
{
if (!(node->flags & Nif::NiNode::Flag_Hidden))
{
translation = node->boundPos;
orientation = node->boundRot;
halfExtents = node->boundXYZ;
//translation = node->boundPos;
//orientation = node->boundRot;
//halfExtents = node->boundXYZ;
return true;
}
}
@ -445,7 +402,7 @@ bool findBoundingBox (const Nif::Node* node, Ogre::Vector3& halfExtents, Ogre::V
bool getBoundingBox(const std::string& nifFile, Ogre::Vector3& halfExtents, Ogre::Vector3& translation, Ogre::Quaternion& orientation)
{
Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(nifFile));
Nif::NIFFilePtr pnif;// (Nif::Cache::getInstance().load(nifFile));
Nif::NIFFile & nif = *pnif.get ();
if (nif.numRoots() < 1)

@ -107,8 +107,7 @@ private:
/**
*Parse a node.
*/
void handleNode(Nif::Node const *node, int flags, bool isCollisionNode,
bool raycasting, bool isAnimated=false);
void handleNode(Nif::Node const *node, int flags, bool isCollisionNode, bool isAnimated=false);
/**
*Helper function
@ -118,7 +117,7 @@ private:
/**
*convert a NiTriShape to a bullet trishape.
*/
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool raycasting, bool isAnimated);
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool isAnimated);
std::string mResourceName;

@ -18,16 +18,13 @@ Ogre::Resource(creator, name, handle, group, isManual, loader)
we have none as such. Full details can be set through scripts.
*/
mCollisionShape = NULL;
mRaycastingShape = NULL;
mAutogenerated = true;
mCollide = true;
createParamDictionary("BulletShape");
}
BulletShape::~BulletShape()
{
deleteShape(mCollisionShape);
deleteShape(mRaycastingShape);
}
// farm out to BulletShapeLoader
@ -56,9 +53,7 @@ void BulletShape::deleteShape(btCollisionShape* shape)
void BulletShape::unloadImpl()
{
deleteShape(mCollisionShape);
deleteShape(mRaycastingShape);
mCollisionShape = NULL;
mRaycastingShape = NULL;
}
//TODO:change this?

@ -6,6 +6,9 @@
#include <btBulletCollisionCommon.h>
#include <OgreVector3.h>
#include <osg/Vec3f>
#include <osg/Quat>
namespace OEngine {
namespace Physic
{
@ -36,18 +39,13 @@ public:
// we store the node's record index mapped to the child index of the shape in the btCompoundShape.
std::map<int, int> mAnimatedShapes;
std::map<int, int> mAnimatedRaycastingShapes;
btCollisionShape* mCollisionShape;
btCollisionShape* mRaycastingShape;
// Does this .nif have an autogenerated collision mesh?
bool mAutogenerated;
Ogre::Vector3 mBoxTranslation;
Ogre::Quaternion mBoxRotation;
//this flag indicate if the shape is used for collision or if it's for raycasting only.
bool mCollide;
osg::Vec3f mBoxTranslation;
osg::Quat mBoxRotation;
};
/**

@ -266,7 +266,6 @@ namespace Physic
{
new BulletShapeManager();
}
//TODO:singleton?
mShapeLoader = shapeLoader;
isDebugCreated = false;
@ -310,8 +309,6 @@ namespace Physic
{
for (std::map<RigidBody*, AnimatedShapeInstance>::iterator it = mAnimatedShapes.begin(); it != mAnimatedShapes.end(); ++it)
deleteShape(it->second.mCompound);
for (std::map<RigidBody*, AnimatedShapeInstance>::iterator it = mAnimatedRaycastingShapes.begin(); it != mAnimatedRaycastingShapes.end(); ++it)
deleteShape(it->second.mCompound);
HeightFieldContainer::iterator hf_it = mHeightFieldMap.begin();
for (; hf_it != mHeightFieldMap.end(); ++hf_it)
@ -332,17 +329,6 @@ namespace Physic
rb_it->second = NULL;
}
}
rb_it = mRaycastingObjectMap.begin();
for (; rb_it != mRaycastingObjectMap.end(); ++rb_it)
{
if (rb_it->second != NULL)
{
mDynamicsWorld->removeRigidBody(rb_it->second);
delete rb_it->second;
rb_it->second = NULL;
}
}
PhysicActorContainer::iterator pa_it = mActorMap.begin();
for (; pa_it != mActorMap.end(); ++pa_it)
@ -362,9 +348,6 @@ namespace Physic
delete dispatcher;
delete broadphase;
delete mShapeLoader;
// Moved the cleanup to mwworld/physicssystem
//delete BulletShapeManager::getSingletonPtr();
}
void PhysicEngine::addHeightField(float* heights,
@ -407,7 +390,7 @@ namespace Physic
mHeightFieldMap [name] = hf;
mDynamicsWorld->addRigidBody(body,CollisionType_HeightMap,
CollisionType_Actor|CollisionType_Raycasting|CollisionType_Projectile);
CollisionType_Actor|CollisionType_Projectile);
}
void PhysicEngine::removeHeightField(int x, int y)
@ -452,12 +435,12 @@ namespace Physic
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
adjustRigidBody(body, position, rotation, shape->mBoxTranslation * scale, shape->mBoxRotation);
//adjustRigidBody(body, position, rotation, shape->mBoxTranslation * scale, shape->mBoxRotation);
}
RigidBody* PhysicEngine::createAndAdjustRigidBody(const std::string &mesh, const std::string &name,
float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation, bool raycasting, bool placeable)
Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation, bool placeable)
{
std::string sid = (boost::format("%07.3f") % scale).str();
std::string outputstring = mesh + sid;
@ -469,21 +452,17 @@ namespace Physic
// TODO: add option somewhere to enable collision for placeable meshes
if (placeable && !raycasting && shape->mCollisionShape)
if (placeable && shape->mCollisionShape)
return NULL;
if (!shape->mCollisionShape && !raycasting)
return NULL;
if (!shape->mRaycastingShape && raycasting)
if (!shape->mCollisionShape)
return NULL;
btCollisionShape* collisionShape = raycasting ? shape->mRaycastingShape : shape->mCollisionShape;
btCollisionShape* collisionShape = shape->mCollisionShape;
// If this is an animated compound shape, we must duplicate it so we can animate
// multiple instances independently.
if (!raycasting && !shape->mAnimatedShapes.empty())
collisionShape = duplicateCollisionShape(collisionShape);
if (raycasting && !shape->mAnimatedRaycastingShapes.empty())
if (!shape->mAnimatedShapes.empty())
collisionShape = duplicateCollisionShape(collisionShape);
collisionShape->setLocalScaling( btVector3(scale,scale,scale));
@ -494,41 +473,24 @@ namespace Physic
RigidBody* body = new RigidBody(CI,name);
body->mPlaceable = placeable;
if (!raycasting && !shape->mAnimatedShapes.empty())
if (!shape->mAnimatedShapes.empty())
{
AnimatedShapeInstance instance;
instance.mAnimatedShapes = shape->mAnimatedShapes;
instance.mCompound = collisionShape;
mAnimatedShapes[body] = instance;
}
if (raycasting && !shape->mAnimatedRaycastingShapes.empty())
{
AnimatedShapeInstance instance;
instance.mAnimatedShapes = shape->mAnimatedRaycastingShapes;
instance.mCompound = collisionShape;
mAnimatedRaycastingShapes[body] = instance;
}
if(scaledBoxTranslation != 0)
*scaledBoxTranslation = shape->mBoxTranslation * scale;
if(boxRotation != 0)
*boxRotation = shape->mBoxRotation;
//if(scaledBoxTranslation != 0)
// *scaledBoxTranslation = shape->mBoxTranslation * scale;
//if(boxRotation != 0)
// *boxRotation = shape->mBoxRotation;
adjustRigidBody(body, position, rotation, shape->mBoxTranslation * scale, shape->mBoxRotation);
//adjustRigidBody(body, position, rotation, shape->mBoxTranslation * scale, shape->mBoxRotation);
if (!raycasting)
{
assert (mCollisionObjectMap.find(name) == mCollisionObjectMap.end());
mCollisionObjectMap[name] = body;
mDynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_Actor|CollisionType_HeightMap);
}
else
{
assert (mRaycastingObjectMap.find(name) == mRaycastingObjectMap.end());
mRaycastingObjectMap[name] = body;
mDynamicsWorld->addRigidBody(body,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_Projectile);
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT);
}
assert (mCollisionObjectMap.find(name) == mCollisionObjectMap.end());
mCollisionObjectMap[name] = body;
mDynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_Actor|CollisionType_HeightMap);
return body;
}
@ -544,15 +506,6 @@ namespace Physic
mDynamicsWorld->removeRigidBody(body);
}
}
it = mRaycastingObjectMap.find(name);
if (it != mRaycastingObjectMap.end() )
{
RigidBody* body = it->second;
if(body != NULL)
{
mDynamicsWorld->removeRigidBody(body);
}
}
}
void PhysicEngine::deleteRigidBody(const std::string &name)
@ -572,30 +525,14 @@ namespace Physic
}
mCollisionObjectMap.erase(it);
}
it = mRaycastingObjectMap.find(name);
if (it != mRaycastingObjectMap.end() )
{
RigidBody* body = it->second;
if(body != NULL)
{
if (mAnimatedRaycastingShapes.find(body) != mAnimatedRaycastingShapes.end())
deleteShape(mAnimatedRaycastingShapes[body].mCompound);
mAnimatedRaycastingShapes.erase(body);
delete body;
}
mRaycastingObjectMap.erase(it);
}
}
RigidBody* PhysicEngine::getRigidBody(const std::string &name, bool raycasting)
RigidBody* PhysicEngine::getRigidBody(const std::string &name)
{
RigidBodyContainer* map = raycasting ? &mRaycastingObjectMap : &mCollisionObjectMap;
RigidBodyContainer::iterator it = map->find(name);
if (it != map->end() )
RigidBodyContainer::iterator it = mCollisionObjectMap.find(name);
if (it != mCollisionObjectMap.end() )
{
RigidBody* body = (*map)[name];
RigidBody* body = mCollisionObjectMap[name];
return body;
}
else
@ -617,8 +554,7 @@ namespace Physic
const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
const RigidBody* body = dynamic_cast<const RigidBody*>(colObj0Wrap->m_collisionObject);
if (body && !(colObj0Wrap->m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup
& CollisionType_Raycasting))
if (body)
mResult.push_back(body->mName);
return 0.f;
@ -628,8 +564,7 @@ namespace Physic
const btCollisionObject* col1, int partId1, int index1)
{
const RigidBody* body = dynamic_cast<const RigidBody*>(col0);
if (body && !(col0->getBroadphaseHandle()->m_collisionFilterGroup
& CollisionType_Raycasting))
if (body)
mResult.push_back(body->mName);
return 0.f;
@ -698,8 +633,6 @@ namespace Physic
std::vector<std::string> PhysicEngine::getCollisions(const std::string& name, int collisionGroup, int collisionMask)
{
RigidBody* body = getRigidBody(name);
if (!body) // fall back to raycasting body if there is no collision body
body = getRigidBody(name, true);
ContactTestResultCallback callback;
callback.m_collisionFilterGroup = collisionGroup;
callback.m_collisionFilterMask = collisionMask;
@ -769,17 +702,14 @@ namespace Physic
}
}
std::pair<std::string,float> PhysicEngine::rayTest(const btVector3 &from, const btVector3 &to, bool raycastingObjectOnly, bool ignoreHeightMap, Ogre::Vector3* normal)
std::pair<std::string,float> PhysicEngine::rayTest(const btVector3 &from, const btVector3 &to, bool ignoreHeightMap, Ogre::Vector3* normal)
{
std::string name = "";
float d = -1;
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
resultCallback1.m_collisionFilterGroup = 0xff;
if(raycastingObjectOnly)
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting|CollisionType_Actor;
else
resultCallback1.m_collisionFilterMask = CollisionType_World;
resultCallback1.m_collisionFilterMask = CollisionType_World;
if(!ignoreHeightMap)
resultCallback1.m_collisionFilterMask = resultCallback1.m_collisionFilterMask | CollisionType_HeightMap;
@ -833,51 +763,6 @@ namespace Physic
return std::make_pair(false, 1.0f);
}
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(const btVector3& from, const btVector3& to, int filterGroup)
{
MyRayResultCallback resultCallback1;
resultCallback1.m_collisionFilterGroup = filterGroup;
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting|CollisionType_Actor|CollisionType_HeightMap;
mDynamicsWorld->rayTest(from, to, resultCallback1);
std::vector< std::pair<float, const btCollisionObject*> > results = resultCallback1.results;
std::vector< std::pair<float, std::string> > results2;
for (std::vector< std::pair<float, const btCollisionObject*> >::iterator it=results.begin();
it != results.end(); ++it)
{
results2.push_back( std::make_pair( (*it).first, static_cast<const RigidBody&>(*(*it).second).mName ) );
}
std::sort(results2.begin(), results2.end(), MyRayResultCallback::cmp);
return results2;
}
void PhysicEngine::getObjectAABB(const std::string &mesh, float scale, btVector3 &min, btVector3 &max)
{
std::string sid = (boost::format("%07.3f") % scale).str();
std::string outputstring = mesh + sid;
mShapeLoader->load(outputstring, "General");
BulletShapeManager::getSingletonPtr()->load(outputstring, "General");
BulletShapePtr shape =
BulletShapeManager::getSingleton().getByName(outputstring, "General");
btTransform trans;
trans.setIdentity();
if (shape->mRaycastingShape)
shape->mRaycastingShape->getAabb(trans, min, max);
else if (shape->mCollisionShape)
shape->mCollisionShape->getAabb(trans, min, max);
else
{
min = btVector3(0,0,0);
max = btVector3(0,0,0);
}
}
int PhysicEngine::toggleDebugRendering(Ogre::SceneManager *sceneMgr)
{
if(!sceneMgr)

@ -46,9 +46,8 @@ namespace Physic
CollisionType_World = 1<<0, //<Collide with world objects
CollisionType_Actor = 1<<1, //<Collide sith actors
CollisionType_HeightMap = 1<<2, //<collide with heightmap
CollisionType_Raycasting = 1<<3,
CollisionType_Projectile = 1<<4,
CollisionType_Water = 1<<5
CollisionType_Projectile = 1<<3,
CollisionType_Water = 1<<4
};
/**
@ -211,7 +210,7 @@ namespace Physic
*/
RigidBody* createAndAdjustRigidBody(const std::string &mesh, const std::string &name,
float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0, bool raycasting=false, bool placeable=false);
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0, bool placeable=false);
/**
* Adjusts a rigid body to the right position and rotation
@ -249,7 +248,7 @@ namespace Physic
/**
* Return a pointer to a given rigid body.
*/
RigidBody* getRigidBody(const std::string &name, bool raycasting=false);
RigidBody* getRigidBody(const std::string &name);
/**
* Create and add a character to the scene, and add it to the ActorMap.
@ -286,22 +285,15 @@ namespace Physic
bool toggleDebugRendering();
void getObjectAABB(const std::string &mesh, float scale, btVector3 &min, btVector3 &max);
void setSceneManager(Ogre::SceneManager* sceneMgr);
/**
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
* If \a normal is non-NULL, the hit normal will be written there (if there is a hit)
*/
std::pair<std::string,float> rayTest(const btVector3& from,const btVector3& to,bool raycastingObjectOnly = true,
std::pair<std::string,float> rayTest(const btVector3& from,const btVector3& to,
bool ignoreHeightMap = false, Ogre::Vector3* normal = NULL);
/**
* Return all objects hit by a ray.
*/
std::vector< std::pair<float, std::string> > rayTest2(const btVector3 &from, const btVector3 &to, int filterGroup=0xff);
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
///< @return (hit, relative distance)
@ -333,10 +325,6 @@ namespace Physic
// the index refers to an element in mCollisionObjectMap
std::map<RigidBody*, AnimatedShapeInstance > mAnimatedShapes;
RigidBodyContainer mRaycastingObjectMap;
std::map<RigidBody*, AnimatedShapeInstance > mAnimatedRaycastingShapes;
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
PhysicActorContainer mActorMap;

Loading…
Cancel
Save