- added debug line drawing in gameengine (handy for debugging physics problems)

- added #ifdef for a visual studio 8 crashing problems
- added scaling and tolerances to triangle meshes
This commit is contained in:
Erwin Coumans 2005-07-27 09:30:53 +00:00
parent b8142515ce
commit 411123b250
23 changed files with 183 additions and 24 deletions

@ -69,6 +69,8 @@ public:
const char * m_tempDebug;
//endif debugging support
virtual void SetMargin(float margin) = 0;
virtual float GetMargin() const = 0;
};

@ -34,7 +34,7 @@ class StridingMeshInterface
public:
StridingMeshInterface() :m_scaling(1.f,1.f,1.f)
{
}
virtual ~StridingMeshInterface();
@ -64,6 +64,8 @@ class StridingMeshInterface
{
m_scaling = scaling;
}
};
#endif //STRIDING_MESHINTERFACE_H

@ -27,6 +27,7 @@ struct MyTriangle
class TriangleMesh : public StridingMeshInterface
{
std::vector<MyTriangle> m_triangles;
public:
TriangleMesh ();
@ -56,8 +57,7 @@ class TriangleMesh : public StridingMeshInterface
virtual void preallocateVertices(int numverts){}
virtual void preallocateIndices(int numindices){}
};
#endif //TRIANGLE_MESH_H

@ -17,7 +17,8 @@
TriangleMeshShape::TriangleMeshShape(StridingMeshInterface* meshInterface)
: m_meshInterface(meshInterface)
: m_meshInterface(meshInterface),
m_collisionMargin(0.1f)
{
}
@ -31,16 +32,16 @@ TriangleMeshShape::~TriangleMeshShape()
void TriangleMeshShape::GetAabb(const SimdTransform& trans,SimdVector3& aabbMin,SimdVector3& aabbMax) const
{
SimdScalar margin = 0.5f;
for (int i=0;i<3;i++)
{
SimdVector3 vec(0.f,0.f,0.f);
vec[i] = 1.f;
SimdVector3 tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
aabbMax[i] = tmp[i]+margin;
aabbMax[i] = tmp[i]+m_collisionMargin;
vec[i] = -1.f;
tmp = trans(LocalGetSupportingVertex(vec*trans.getBasis()));
aabbMin[i] = tmp[i]-margin;
aabbMin[i] = tmp[i]-m_collisionMargin;
}
}

@ -24,7 +24,8 @@ class TriangleMeshShape : public CollisionShape
{
StridingMeshInterface* m_meshInterface;
float m_collisionMargin;
public:
TriangleMeshShape(StridingMeshInterface* meshInterface);
@ -57,6 +58,16 @@ public:
//debugging
virtual char* GetName()const {return "TRIANGLEMESH";}
virtual float GetMargin() const {
return m_collisionMargin;
}
virtual void SetMargin(float collisionMargin)
{
m_collisionMargin = collisionMargin;
}
};

@ -120,13 +120,18 @@ bool ContinuousConvexCollision::calcTimeOfImpact(
lambda = lambda + dLambda;
if (lambda > 1.f)
return false;
if (lambda < 0.f)
return false;
//todo: next check with relative epsilon
if (lambda <= lastLambda)
break;
lastLambda = lambda;
if (lambda > 1.f)
return false;
//interpolate to next lambda
SimdTransform interpolatedTransA,interpolatedTransB,relativeTrans;

@ -83,6 +83,8 @@ void BoxTriangleCallback::ProcessTriangle(SimdVector3* triangle)
if (m_boxProxy->IsConvexShape())
{
TriangleShape tm(triangle[0],triangle[1],triangle[2]);
tm.SetMargin(m_collisionMarginTriangle);
RigidBody* triangleBody = (RigidBody* )m_triangleProxy.m_clientObject;
triangleBody->SetCollisionShape(&tm);
@ -97,11 +99,12 @@ void BoxTriangleCallback::ProcessTriangle(SimdVector3* triangle)
void BoxTriangleCallback::SetTimeStepAndCounters(float timeStep,int stepCount,bool useContinuous)
void BoxTriangleCallback::SetTimeStepAndCounters(float timeStep,int stepCount,float collisionMarginTriangle,bool useContinuous)
{
m_timeStep = timeStep;
m_stepCount = stepCount;
m_useContinuous = useContinuous;
m_collisionMarginTriangle = collisionMarginTriangle;
//recalc aabbs
RigidBody* boxBody = (RigidBody* )m_boxProxy->m_clientObject;
@ -141,8 +144,9 @@ void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,Broadp
if (m_convex.IsConvexShape())
{
float collisionMarginTriangle = triangleMesh->GetMargin();
m_boxTriangleCallback.SetTimeStepAndCounters(timeStep,stepCount, useContinuous);
m_boxTriangleCallback.SetTimeStepAndCounters(timeStep,stepCount, collisionMarginTriangle,useContinuous);
#ifdef USE_BOX_TRIANGLE
m_boxTriangleCallback.m_manifoldPtr->ClearManifold();
#endif
@ -161,6 +165,8 @@ void ConvexConcaveCollisionAlgorithm::ProcessCollision (BroadphaseProxy* ,Broadp
float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,BroadphaseProxy* ,float timeStep,int stepCount)
{
return 1.f;
//quick approximation using raycast, todo: use proper continuou collision detection
RigidBody* convexbody = (RigidBody* )m_convex.m_clientObject;
const SimdVector3& from = convexbody->getCenterOfMassPosition();
@ -193,7 +199,7 @@ float ConvexConcaveCollisionAlgorithm::CalculateTimeOfImpact(BroadphaseProxy* ,B
RigidBody* concavebody = (RigidBody* )m_concave.m_clientObject;
TriangleMeshShape* triangleMesh = (TriangleMeshShape*) concavebody->GetCollisionShape();
if (triangleMesh)
{
triangleMesh->ProcessAllTriangles(&raycastCallback,aabbMin,aabbMax);

@ -33,6 +33,7 @@ class BoxTriangleCallback : public TriangleCallback
float m_timeStep;
int m_stepCount;
bool m_useContinuous;
float m_collisionMarginTriangle;
public:
@ -40,7 +41,7 @@ public:
BoxTriangleCallback(Dispatcher* dispatcher,BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
void SetTimeStepAndCounters(float timeStep,int stepCount, bool useContinuous);
void SetTimeStepAndCounters(float timeStep,int stepCount, float collisionMarginTriangle,bool useContinuous);
virtual ~BoxTriangleCallback();

@ -92,16 +92,14 @@ class SimdQuadWord
}
SIMD_FORCE_INLINE SimdQuadWord()
:m_x(0),m_y(0),m_z(0)
//todo, remove this in release/simd ?
,m_unusedW(0)
:m_x(0.f),m_y(0.f),m_z(0.f),m_unusedW(0.f)
{
}
SIMD_FORCE_INLINE SimdQuadWord(const SimdScalar& x, const SimdScalar& y, const SimdScalar& z)
:m_x(x),m_y(y),m_z(z)
//todo, remove this in release/simd ?
,m_unusedW(0)
,m_unusedW(0.f)
{
}

@ -52,7 +52,8 @@
#include "MT_random.h"
#include "NM_Scalar.h"
typedef double MT_Scalar;
typedef double MT_Scalar; //this should be float !
const MT_Scalar MT_DEGS_PER_RAD(57.29577951308232286465);
const MT_Scalar MT_RADS_PER_DEG(0.01745329251994329547);

@ -170,7 +170,22 @@ static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& sce
return (Scene*) maggie->scene.first;
}
#include "KX_PythonInit.h"
#ifdef USE_BULLET
struct BlenderDebugDraw : public PHY_IPhysicsDebugDraw
{
virtual void DrawLine(const SimdVector3& from,const SimdVector3& to,const SimdVector3& color)
{
MT_Vector3 kxfrom(from[0],from[1],from[2]);
MT_Vector3 kxto(to[0],to[1],to[2]);
MT_Vector3 kxcolor(color[0],color[1],color[2]);
KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
}
};
#endif
void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
class KX_Scene* destinationscene,
@ -226,7 +241,9 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
#ifdef USE_BULLET
case UseBullet:
{
destinationscene->SetPhysicsEnvironment(new CcdPhysicsEnvironment());
CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment();
ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
break;
}
#endif

@ -173,6 +173,7 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
int lines;
char* s = tmpstr.Ptr();
char* p;
// Save and change OpenGL settings
int texture2D;
@ -182,6 +183,11 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
glGetIntegerv(GL_FOG, (GLint*)&fog);
glDisable(GL_FOG);
int light;
glGetIntegerv(GL_LIGHTING, (GLint*)&light);
glDisable(GL_LIGHTING);
// Set up viewing settings
glMatrixMode(GL_PROJECTION);
glPushMatrix();
@ -228,6 +234,10 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
glEnable(GL_TEXTURE_2D);
else
glDisable(GL_TEXTURE_2D);
if (light)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
/**

@ -35,7 +35,13 @@
/* These are defined by the build system... */
//#define USE_SUMO_SOLID
//#define USE_ODE
//#define USE_BULLET
//on visual studio 8, always enable BULLET.
//you can have multiple physics engines running anyway, and
//the build system doesn't really support this at the moment.
#if 1400 > _MSC_VER
#define USE_BULLET
#endif
class RAS_MeshObject;
class KX_Scene;

@ -854,6 +854,7 @@ static CollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool p
void KX_ConvertBulletObject( class KX_GameObject* gameobj,
class RAS_MeshObject* meshobj,
class KX_Scene* kxscene,
@ -864,6 +865,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
assert(env);
bool dyna = false;
@ -954,6 +957,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
if (bm)
{
bm->CalculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
bm->SetMargin(0.f);
}
break;
}

@ -213,5 +213,6 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
"Reinstance the physics mesh.")
{
return Py_Success(KX_ReInstanceShapeFromMesh(m_meshobj));
//this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ?
return Py_None;//Py_Success(KX_ReInstanceShapeFromMesh(m_meshobj));
}

@ -78,6 +78,12 @@ static RAS_ICanvas* gp_Canvas = NULL;
static KX_Scene* gp_KetsjiScene = NULL;
static RAS_IRasterizer* gp_Rasterizer = NULL;
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
if (gp_Rasterizer)
gp_Rasterizer->DrawDebugLine(from,to,color);
}
/* Macro for building the keyboard translation */
//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name))
#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name))

@ -51,6 +51,9 @@ void exitGamePlayerPythonScripting();
PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
void exitGamePythonScripting();
void PHY_SetActiveScene(class KX_Scene* scene);
#include "MT_Vector3.h"
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color);
#endif //__KX_PYTHON_INIT

@ -1,3 +1,6 @@
#include "KX_ConvertPhysicsObject.h"
#ifdef USE_SUMO_SOLID
#ifdef WIN32
#pragma warning (disable : 4786)
@ -216,3 +219,4 @@ KX_SumoPhysicsController::~KX_SumoPhysicsController()
}
#endif//USE_SUMO_SOLID

@ -7,7 +7,7 @@
class BP_Proxy;
bool gEnableSleeping = true;//false;//true;
bool gEnableSleeping = false;//false;//true;
#include "Dynamics/MassProps.h"
SimdVector3 startVel(0,0,0);//-10000);

@ -47,6 +47,43 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
static void DrawAabb(PHY_IPhysicsDebugDraw* debugDrawer,const SimdVector3& from,const SimdVector3& to,const SimdVector3& color)
{
SimdVector3 halfExtents = (to-from)* 0.5f;
SimdVector3 center = (to+from) *0.5f;
int i,j;
SimdVector3 edgecoord(1.f,1.f,1.f),pa,pb;
for (i=0;i<4;i++)
{
for (j=0;j<3;j++)
{
pa = SimdVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
edgecoord[2]*halfExtents[2]);
pa+=center;
int othercoord = j%3;
edgecoord[othercoord]*=-1.f;
pb = SimdVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
edgecoord[2]*halfExtents[2]);
pb+=center;
debugDrawer->DrawLine(pa,pb,color);
}
edgecoord = SimdVector3(-1.f,-1.f,-1.f);
if (i<3)
edgecoord[i]*=-1.f;
}
}
CcdPhysicsEnvironment::CcdPhysicsEnvironment(ToiContactDispatcher* dispatcher,BroadphaseInterface* bp)
:m_dispatcher(dispatcher),
m_broadphase(bp),
@ -402,10 +439,16 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
SimdPoint3 minAabb,maxAabb;
CollisionShape* shapeinterface = ctrl->GetCollisionShape();
shapeinterface->CalculateTemporalAabb(body->getCenterOfMassTransform(),
body->getLinearVelocity(),body->getAngularVelocity(),
timeStep,minAabb,maxAabb);
shapeinterface->GetAabb(body->getCenterOfMassTransform(),
minAabb,maxAabb);
BroadphaseProxy* bp = (BroadphaseProxy*) ctrl->m_broadphaseHandle;
if (bp)
@ -414,7 +457,11 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
#ifdef WIN32
SimdVector3 color (1,0,0);
if (m_debugDrawer)
m_debugDrawer->DrawLine(minAabb,maxAabb,color);
{
//draw aabb
DrawAabb(m_debugDrawer,minAabb,maxAabb,color);
}
#endif
scene->SetAabb(bp,minAabb,maxAabb);
}

@ -333,6 +333,7 @@ public:
*/
virtual void SetPolygonOffset(float mult, float add) = 0;
virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0;
};
#endif //__RAS_IRASTERIZER

@ -401,6 +401,21 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void)
void RAS_OpenGLRasterizer::EndFrame()
{
//DrawDebugLines
glBegin(GL_LINES);
for (unsigned int i=0;i<m_debugLines.size();i++)
{
glColor4f(m_debugLines[i].m_color[0],m_debugLines[i].m_color[1],m_debugLines[i].m_color[2],1.f);
const MT_Scalar* fromPtr = &m_debugLines[i].m_from.x();
const MT_Scalar* toPtr= &m_debugLines[i].m_to.x();
glVertex3dv(fromPtr);
glVertex3dv(toPtr);
}
glEnd();
m_debugLines.clear();
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
m_2DCanvas->EndFrame();
}

@ -44,6 +44,13 @@ using namespace std;
#include "RAS_MaterialBucket.h"
#include "RAS_ICanvas.h"
struct OglDebugLine
{
MT_Vector3 m_from;
MT_Vector3 m_to;
MT_Vector3 m_color;
};
/**
* 3D rendering device context.
*/
@ -226,6 +233,17 @@ public:
);
virtual void SetPolygonOffset(float mult, float add);
virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
OglDebugLine line;
line.m_from = from;
line.m_to = to;
line.m_color = color;
m_debugLines.push_back(line);
}
std::vector <OglDebugLine> m_debugLines;
};
#endif //__RAS_OPENGLRASTERIZER