1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-20 19:39:41 +00:00

Add bullet debug drawer

This commit is contained in:
scrawl 2015-05-03 00:39:01 +02:00
parent 9cf9c2876e
commit 1943110170
10 changed files with 221 additions and 99 deletions

View file

@ -22,6 +22,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation sky npcanimation vismask
creatureanimation effectmanager util renderinginterface debugging rendermode
bulletdebugdraw
# camera activatoranimation
# localmap occlusionquery water shadows
# characterpreview globalmap ripplesimulation refraction

View file

@ -0,0 +1,98 @@
#include "bulletdebugdraw.hpp"
#include <iostream>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include "vismask.hpp"
namespace
{
osg::Vec3f toOsg(const btVector3& vec)
{
return osg::Vec3f(vec.x(), vec.y(), vec.z());
}
}
namespace MWRender
{
DebugDrawer::DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btDynamicsWorld *world)
: mParentNode(parentNode),
mWorld(world),
mDebugOn(true)
{
mGeode = new osg::Geode;
mParentNode->addChild(mGeode);
mGeode->setNodeMask(Mask_Debug);
mGeometry = new osg::Geometry;
mVertices = new osg::Vec3Array;
mDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES);
mGeometry->setUseDisplayList(false);
mGeometry->setVertexArray(mVertices);
mGeometry->setDataVariance(osg::Object::DYNAMIC);
mGeometry->addPrimitiveSet(mDrawArrays);
mGeode->addDrawable(mGeometry);
mParentNode->addChild(mGeode);
}
DebugDrawer::~DebugDrawer()
{
mParentNode->removeChild(mGeode);
}
void DebugDrawer::step()
{
if (mDebugOn)
{
mVertices->clear();
mWorld->debugDrawWorld();
mDrawArrays->setCount(mVertices->size());
mVertices->dirty();
}
}
void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
{
mVertices->push_back(toOsg(from));
mVertices->push_back(toOsg(to));
}
void DebugDrawer::drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)
{
mVertices->push_back(toOsg(PointOnB));
mVertices->push_back(toOsg(PointOnB) + (toOsg(normalOnB) * distance * 20));
}
void DebugDrawer::reportErrorWarning(const char *warningString)
{
std::cerr << warningString << std::endl;
}
void DebugDrawer::setDebugMode(int isOn)
{
mDebugOn = (isOn == 0) ? false : true;
if (!mDebugOn)
{
mVertices->clear();
mVertices->releaseGLObjects(0);
mGeometry->releaseGLObjects(0);
}
}
int DebugDrawer::getDebugMode() const
{
return mDebugOn;
}
}

View file

@ -0,0 +1,58 @@
#ifndef OPENMW_MWRENDER_BULLETDEBUGDRAW_H
#define OPENMW_MWRENDER_BULLETDEBUGDRAW_H
#include "btBulletDynamicsCommon.h"
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/PrimitiveSet>
namespace osg
{
class Group;
class Geode;
class Geometry;
}
namespace MWRender
{
class DebugDrawer : public btIDebugDraw
{
protected:
osg::ref_ptr<osg::Group> mParentNode;
btDynamicsWorld *mWorld;
osg::ref_ptr<osg::Geode> mGeode;
osg::ref_ptr<osg::Geometry> mGeometry;
osg::ref_ptr<osg::Vec3Array> mVertices;
osg::ref_ptr<osg::DrawArrays> mDrawArrays;
bool mDebugOn;
public:
DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btDynamicsWorld *world);
~DebugDrawer();
void step();
void drawLine(const btVector3& from,const btVector3& to,const btVector3& color);
void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color);
void reportErrorWarning(const char* warningString);
void draw3dText(const btVector3& location,const char* textString) {}
//0 for off, anything else for on.
void setDebugMode(int isOn);
//0 for off, anything else for on.
int getDebugMode() const;
};
}
#endif

View file

@ -146,10 +146,6 @@ Debugging::~Debugging()
bool Debugging::toggleRenderMode (int mode){
switch (mode)
{
//case Render_CollisionDebug:
//return mEngine->toggleDebugRendering();
case Render_Pathgrid:
togglePathgrid();
return mPathgridEnabled;

View file

@ -10,6 +10,8 @@
#include <OgreTextureManager.h>
#include <OgreSceneNode.h>
#include <osg/Group>
#include <openengine/bullet/trace.h>
#include <openengine/bullet/physic.hpp>
#include <openengine/bullet/BtOgreExtras.h>
@ -29,6 +31,8 @@
#include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwrender/bulletdebugdraw.hpp"
//#include "../apps/openmw/mwrender/animation.hpp"
#include "../apps/openmw/mwbase/world.hpp"
#include "../apps/openmw/mwbase/environment.hpp"
@ -498,8 +502,8 @@ namespace MWWorld
};
PhysicsSystem::PhysicsSystem() :
mEngine(0), mTimeAccum(0.0f), mWaterEnabled(false), mWaterHeight(0)
PhysicsSystem::PhysicsSystem(osg::ref_ptr<osg::Group> parentNode) :
mEngine(0), mTimeAccum(0.0f), mWaterEnabled(false), mWaterHeight(0), mDebugDrawEnabled(false), mParentNode(parentNode)
{
// Create physics. shapeLoader is deleted by the physic engine
//NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
@ -514,6 +518,21 @@ namespace MWWorld
//delete OEngine::Physic::BulletShapeManager::getSingletonPtr();
}
bool PhysicsSystem::toggleDebugRendering()
{
mDebugDrawEnabled = !mDebugDrawEnabled;
if (mDebugDrawEnabled && !mDebugDrawer.get())
{
mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mEngine->mDynamicsWorld));
mEngine->mDynamicsWorld->setDebugDrawer(mDebugDrawer.get());
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
}
else if (mDebugDrawer.get())
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
return mDebugDrawEnabled;
}
OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
{
return mEngine;
@ -799,6 +818,9 @@ namespace MWWorld
animateCollisionShapes(mEngine->mAnimatedShapes, mEngine->mDynamicsWorld);
mEngine->stepSimulation(dt);
if (mDebugDrawer.get())
mDebugDrawer->step();
}
bool PhysicsSystem::isActorStandingOn(const Ptr &actor, const Ptr &object) const

View file

@ -7,8 +7,14 @@
#include <btBulletCollisionCommon.h>
#include <osg/ref_ptr>
#include "ptr.hpp"
namespace osg
{
class Group;
}
namespace OEngine
{
@ -18,6 +24,11 @@ namespace OEngine
}
}
namespace MWRender
{
class DebugDrawer;
}
namespace MWWorld
{
class World;
@ -27,7 +38,7 @@ namespace MWWorld
class PhysicsSystem
{
public:
PhysicsSystem ();
PhysicsSystem (osg::ref_ptr<osg::Group> parentNode);
~PhysicsSystem ();
void enableWater(float height);
@ -98,10 +109,14 @@ namespace MWWorld
/// Get the handle of all actors colliding with \a object in this frame.
void getActorsCollidingWith(const MWWorld::Ptr& object, std::vector<std::string>& out) const;
bool toggleDebugRendering();
private:
void updateWater();
bool mDebugDrawEnabled;
OEngine::Physic::PhysicEngine* mEngine;
std::map<std::string, std::string> handleToMesh;
@ -123,6 +138,10 @@ namespace MWWorld
std::auto_ptr<btCollisionObject> mWaterCollisionObject;
std::auto_ptr<btCollisionShape> mWaterCollisionShape;
std::auto_ptr<MWRender::DebugDrawer> mDebugDrawer;
osg::ref_ptr<osg::Group> mParentNode;
PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&);
};

View file

@ -18,7 +18,7 @@
#include "../mwrender/renderingmanager.hpp"
//#include "physicssystem.hpp"
#include "physicssystem.hpp"
#include "player.hpp"
#include "localscripts.hpp"
#include "esmstore.hpp"
@ -26,8 +26,6 @@
#include "cellfunctors.hpp"
#include "cellstore.hpp"
#include <osg/Timer>
namespace
{
@ -194,26 +192,22 @@ namespace MWWorld
ListAndResetHandles functor;
(*iter)->forEach<ListAndResetHandles>(functor);
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
iter2!=functor.mHandles.end(); ++iter2)
{
// silence annoying g++ warning
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
iter2!=functor.mHandles.end(); ++iter2)
{
//Ogre::SceneNode* node = *iter2;
//mPhysics->removeObject (node->getName());
}
//Ogre::SceneNode* node = *iter2;
//mPhysics->removeObject (node->getName());
}
if ((*iter)->getCell()->isExterior())
{
/*ESM::Land* land =
ESM::Land* land =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Land>().search(
(*iter)->getCell()->getGridX(),
(*iter)->getCell()->getGridY()
);
if (land && land->mDataTypes&ESM::Land::DATA_VHGT)
mPhysics->removeHeightField ((*iter)->getCell()->getGridX(), (*iter)->getCell()->getGridY());
*/
}
mRendering.removeCell(*iter);
@ -234,10 +228,9 @@ namespace MWWorld
{
std::cout << "loading cell " << cell->getCell()->getDescription() << std::endl;
//float verts = ESM::Land::LAND_SIZE;
//float worldsize = ESM::Land::REAL_SIZE;
float verts = ESM::Land::LAND_SIZE;
float worldsize = ESM::Land::REAL_SIZE;
#if 0
// Load terrain physics first...
if (cell->getCell()->isExterior())
{
@ -262,7 +255,6 @@ namespace MWWorld
;
}
}
#endif
cell->respawn();
@ -316,9 +308,7 @@ namespace MWWorld
{
int newX, newY;
MWBase::Environment::get().getWorld()->positionToIndex(pos.x(), pos.y(), newX, newY);
osg::Timer timer;
changeCellGrid(newX, newY);
std::cout << "changeCellGrid took " << timer.time_m() << std::endl;
//mRendering.updateTerrain();
}
}

View file

@ -161,7 +161,7 @@ namespace MWWorld
mStartCell (startCell), mStartupScript(startupScript),
mScriptsEnabled(true)
{
mPhysics = new PhysicsSystem();
mPhysics = new PhysicsSystem(rootNode);
//mPhysEngine = mPhysics->getEngine();
#if 0
mProjectileManager.reset(new ProjectileManager(renderer.getScene(), *mPhysEngine));
@ -1409,9 +1409,8 @@ namespace MWWorld
void World::doPhysics(float duration)
{
mPhysics->stepSimulation(duration);
#if 0
//mPhysics->stepSimulation(duration);
processDoors(duration);
mProjectileManager->update(duration);
@ -1503,7 +1502,13 @@ namespace MWWorld
bool World::toggleRenderMode (MWRender::RenderMode mode)
{
return mRendering->toggleRenderMode (mode);
switch (mode)
{
case MWRender::Render_CollisionDebug:
return mPhysics->toggleDebugRendering();
default:
return mRendering->toggleRenderMode(mode);
}
}
const ESM::Potion *World::createRecord (const ESM::Potion& record)
@ -1601,8 +1606,8 @@ namespace MWWorld
updateWeather(duration, paused);
//if (!paused)
// doPhysics (duration);
if (!paused)
doPhysics (duration);
mWorldScene->update (duration, paused);

View file

@ -240,9 +240,7 @@ namespace Physic
PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) :
mDebugActive(0)
, mSceneMgr(NULL)
PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader)
{
// Set up the collision configuration and dispatcher
collisionConfiguration = new btDefaultCollisionConfiguration();
@ -263,42 +261,6 @@ namespace Physic
mDynamicsWorld->setGravity(btVector3(0,0,-10));
mShapeLoader = shapeLoader;
isDebugCreated = false;
mDebugDrawer = NULL;
}
void PhysicEngine::createDebugRendering()
{
if(!isDebugCreated)
{
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mDebugDrawer = new BtOgre::DebugDrawer(node, mDynamicsWorld);
mDynamicsWorld->setDebugDrawer(mDebugDrawer);
isDebugCreated = true;
mDynamicsWorld->debugDrawWorld();
}
}
void PhysicEngine::setDebugRenderingMode(bool isDebug)
{
if(!isDebugCreated)
{
createDebugRendering();
}
mDebugDrawer->setDebugMode(isDebug);
mDebugActive = isDebug;
}
bool PhysicEngine::toggleDebugRendering()
{
setDebugRenderingMode(!mDebugActive);
return mDebugActive;
}
void PhysicEngine::setSceneManager(Ogre::SceneManager* sceneMgr)
{
mSceneMgr = sceneMgr;
}
PhysicEngine::~PhysicEngine()
@ -336,8 +298,6 @@ namespace Physic
}
}
delete mDebugDrawer;
delete mDynamicsWorld;
delete solver;
delete collisionConfiguration;
@ -652,10 +612,6 @@ namespace Physic
{
// This seems to be needed for character controller objects
mDynamicsWorld->stepSimulation(static_cast<btScalar>(deltaT), 10, 1 / 60.0f);
if(isDebugCreated)
{
mDebugDrawer->step();
}
}
void PhysicEngine::addCharacter(const std::string &name, const std::string &mesh,

View file

@ -271,22 +271,6 @@ namespace Physic
*/
void stepSimulation(double deltaT);
/**
* Create a debug rendering. It is called by setDebgRenderingMode if it's not created yet.
* Important Note: this will crash if the Render is not yet initialise!
*/
void createDebugRendering();
/**
* Set the debug rendering mode. 0 to turn it off.
* Important Note: this will crash if the Render is not yet initialise!
*/
void setDebugRenderingMode(bool isDebug);
bool toggleDebugRendering();
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)
@ -328,13 +312,6 @@ namespace Physic
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
PhysicActorContainer mActorMap;
Ogre::SceneManager* mSceneMgr;
//debug rendering
BtOgre::DebugDrawer* mDebugDrawer;
bool isDebugCreated;
bool mDebugActive;
private:
PhysicEngine(const PhysicEngine&);
PhysicEngine& operator=(const PhysicEngine&);