1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-13 06:13:06 +00:00

Allow to display collision points in the debug viewer

This commit is contained in:
fredzio 2020-10-25 22:33:19 +01:00
parent fa9278e25b
commit 435b2e37f8
4 changed files with 74 additions and 25 deletions

View file

@ -1,5 +1,8 @@
#include "physicssystem.hpp" #include "physicssystem.hpp"
#include <LinearMath/btIDebugDraw.h>
#include <LinearMath/btVector3.h>
#include <memory>
#include <osg/Group> #include <osg/Group>
#include <osg/Stats> #include <osg/Stats>
@ -90,6 +93,7 @@ namespace MWPhysics
} }
mTaskScheduler = std::make_unique<PhysicsTaskScheduler>(mPhysicsDt, mCollisionWorld); mTaskScheduler = std::make_unique<PhysicsTaskScheduler>(mPhysicsDt, mCollisionWorld);
mDebugDrawer = std::make_unique<MWRender::DebugDrawer>(mParentNode, mCollisionWorld.get());
} }
PhysicsSystem::~PhysicsSystem() PhysicsSystem::~PhysicsSystem()
@ -124,14 +128,8 @@ namespace MWPhysics
{ {
mDebugDrawEnabled = !mDebugDrawEnabled; mDebugDrawEnabled = !mDebugDrawEnabled;
if (mDebugDrawEnabled && !mDebugDrawer) mCollisionWorld->setDebugDrawer(mDebugDrawEnabled ? mDebugDrawer.get() : nullptr);
{ mDebugDrawer->setDebugMode(mDebugDrawEnabled);
mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mCollisionWorld.get()));
mCollisionWorld->setDebugDrawer(mDebugDrawer.get());
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
}
else if (mDebugDrawer)
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
return mDebugDrawEnabled; return mDebugDrawEnabled;
} }
@ -758,7 +756,7 @@ namespace MWPhysics
void PhysicsSystem::debugDraw() void PhysicsSystem::debugDraw()
{ {
if (mDebugDrawer) if (mDebugDrawEnabled)
mDebugDrawer->step(); mDebugDrawer->step();
} }
@ -864,6 +862,12 @@ namespace MWPhysics
stats.setAttribute(frameNumber, "Physics HeightFields", mHeightFields.size()); stats.setAttribute(frameNumber, "Physics HeightFields", mHeightFields.size());
} }
void PhysicsSystem::reportCollision(const btVector3& position, const btVector3& normal)
{
if (mDebugDrawEnabled)
mDebugDrawer->addCollision(position, normal);
}
ActorFrameData::ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, ActorFrameData::ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn,
bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel) bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel)
: mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn), : mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn),

View file

@ -45,6 +45,7 @@ class btDefaultCollisionConfiguration;
class btCollisionDispatcher; class btCollisionDispatcher;
class btCollisionObject; class btCollisionObject;
class btCollisionShape; class btCollisionShape;
class btVector3;
namespace MWPhysics namespace MWPhysics
{ {
@ -232,6 +233,7 @@ namespace MWPhysics
bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const; bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const;
void reportStats(unsigned int frameNumber, osg::Stats& stats) const; void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
void reportCollision(const btVector3& position, const btVector3& normal);
private: private:

View file

@ -1,4 +1,4 @@
#include "bulletdebugdraw.hpp" #include <algorithm>
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h> #include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
@ -6,17 +6,11 @@
#include <osg/Group> #include <osg/Group>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/misc/convert.hpp>
#include "bulletdebugdraw.hpp"
#include "vismask.hpp" #include "vismask.hpp"
namespace
{
osg::Vec3f toOsg(const btVector3& vec)
{
return osg::Vec3f(vec.x(), vec.y(), vec.z());
}
}
namespace MWRender namespace MWRender
{ {
@ -37,11 +31,14 @@ void DebugDrawer::createGeometry()
mGeometry->setNodeMask(Mask_Debug); mGeometry->setNodeMask(Mask_Debug);
mVertices = new osg::Vec3Array; mVertices = new osg::Vec3Array;
mColors = new osg::Vec4Array;
mDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); mDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES);
mGeometry->setUseDisplayList(false); mGeometry->setUseDisplayList(false);
mGeometry->setVertexArray(mVertices); mGeometry->setVertexArray(mVertices);
mGeometry->setColorArray(mColors);
mGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
mGeometry->setDataVariance(osg::Object::DYNAMIC); mGeometry->setDataVariance(osg::Object::DYNAMIC);
mGeometry->addPrimitiveSet(mDrawArrays); mGeometry->addPrimitiveSet(mDrawArrays);
@ -70,23 +67,53 @@ void DebugDrawer::step()
if (mDebugOn) if (mDebugOn)
{ {
mVertices->clear(); mVertices->clear();
mColors->clear();
mWorld->debugDrawWorld(); mWorld->debugDrawWorld();
showCollisions();
mDrawArrays->setCount(mVertices->size()); mDrawArrays->setCount(mVertices->size());
mVertices->dirty(); mVertices->dirty();
mColors->dirty();
mGeometry->dirtyBound(); mGeometry->dirtyBound();
} }
} }
void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
{ {
mVertices->push_back(toOsg(from)); mVertices->push_back(Misc::Convert::toOsg(from));
mVertices->push_back(toOsg(to)); mVertices->push_back(Misc::Convert::toOsg(to));
mColors->push_back({1,1,1,1});
mColors->push_back({1,1,1,1});
}
void DebugDrawer::addCollision(const btVector3& orig, const btVector3& normal)
{
mCollisionViews.emplace_back(orig, normal);
}
void DebugDrawer::showCollisions()
{
const auto now = std::chrono::steady_clock::now();
for (auto& [from, to , created] : mCollisionViews)
{
if (now - created < std::chrono::seconds(2))
{
mVertices->push_back(Misc::Convert::toOsg(from));
mVertices->push_back(Misc::Convert::toOsg(to));
mColors->push_back({1,0,0,1});
mColors->push_back({1,0,0,1});
}
}
mCollisionViews.erase(std::remove_if(mCollisionViews.begin(), mCollisionViews.end(),
[&now](const CollisionView& view) { return now - view.mCreated >= std::chrono::seconds(2); }),
mCollisionViews.end());
} }
void DebugDrawer::drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color) void DebugDrawer::drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)
{ {
mVertices->push_back(toOsg(PointOnB)); mVertices->push_back(Misc::Convert::toOsg(PointOnB));
mVertices->push_back(toOsg(PointOnB) + (toOsg(normalOnB) * distance * 20)); mVertices->push_back(Misc::Convert::toOsg(PointOnB) + (Misc::Convert::toOsg(normalOnB) * distance * 20));
mColors->push_back({1,1,1,1});
mColors->push_back({1,1,1,1});
} }
void DebugDrawer::reportErrorWarning(const char *warningString) void DebugDrawer::reportErrorWarning(const char *warningString)
@ -96,7 +123,7 @@ void DebugDrawer::reportErrorWarning(const char *warningString)
void DebugDrawer::setDebugMode(int isOn) void DebugDrawer::setDebugMode(int isOn)
{ {
mDebugOn = (isOn == 0) ? false : true; mDebugOn = (isOn != 0);
if (!mDebugOn) if (!mDebugOn)
destroyGeometry(); destroyGeometry();
@ -109,6 +136,4 @@ int DebugDrawer::getDebugMode() const
return mDebugOn; return mDebugOn;
} }
} }

View file

@ -1,6 +1,9 @@
#ifndef OPENMW_MWRENDER_BULLETDEBUGDRAW_H #ifndef OPENMW_MWRENDER_BULLETDEBUGDRAW_H
#define OPENMW_MWRENDER_BULLETDEBUGDRAW_H #define OPENMW_MWRENDER_BULLETDEBUGDRAW_H
#include <chrono>
#include <vector>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Array> #include <osg/Array>
#include <osg/PrimitiveSet> #include <osg/PrimitiveSet>
@ -20,11 +23,22 @@ namespace MWRender
class DebugDrawer : public btIDebugDraw class DebugDrawer : public btIDebugDraw
{ {
private:
struct CollisionView
{
btVector3 mOrig;
btVector3 mEnd;
std::chrono::time_point<std::chrono::steady_clock> mCreated;
CollisionView(btVector3 orig, btVector3 normal) : mOrig(orig), mEnd(orig + normal * 20), mCreated(std::chrono::steady_clock::now()) {};
};
std::vector<CollisionView> mCollisionViews;
protected: protected:
osg::ref_ptr<osg::Group> mParentNode; osg::ref_ptr<osg::Group> mParentNode;
btCollisionWorld *mWorld; btCollisionWorld *mWorld;
osg::ref_ptr<osg::Geometry> mGeometry; osg::ref_ptr<osg::Geometry> mGeometry;
osg::ref_ptr<osg::Vec3Array> mVertices; osg::ref_ptr<osg::Vec3Array> mVertices;
osg::ref_ptr<osg::Vec4Array> mColors;
osg::ref_ptr<osg::DrawArrays> mDrawArrays; osg::ref_ptr<osg::DrawArrays> mDrawArrays;
bool mDebugOn; bool mDebugOn;
@ -41,6 +55,10 @@ public:
void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) override; void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) override;
void addCollision(const btVector3& orig, const btVector3& normal);
void showCollisions();
void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) override; void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) override;
void reportErrorWarning(const char* warningString) override; void reportErrorWarning(const char* warningString) override;