00001 #ifndef _OGREBULLET_HEIGHTMAP_
00002 #define _OGREBULLET_HEIGHTMAP_
00003
00004
00005 #include "OgreBulletCollisionsPreRequisites.h"
00006
00007 #include "OgreBulletCollisionsShape.h"
00008 #include "Debug/OgreBulletCollisionsDebugLines.h"
00009
00010 #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
00011 #include "BulletCollision/CollisionShapes/btTriangleCallback.h"
00012
00013 namespace OgreBulletCollisions
00014 {
00015
00016 class DebugHelper : public btIDebugDraw
00017 {
00018 public:
00019
00020 DebugHelper(DebugLines* pLines) : m_pLines(pLines) {}
00021 ~DebugHelper () {}
00022
00023 void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
00024 {
00025 Ogre::Vector3 a(from.x(), from.y(), from.z());
00026 Ogre::Vector3 b(to.x(), to.y(), to.z());
00027 m_pLines->addLine(a, b);
00028 }
00029 void draw3dText(const btVector3 &,const char *)
00030 {
00031
00032 }
00033
00034 void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
00035 {
00036 }
00037
00038 void reportErrorWarning(const char* warningString)
00039 {
00040 }
00041
00042 void setDebugMode(int debugMode)
00043 {
00044 }
00045
00046 int getDebugMode() const
00047 {
00048 return -1;
00049 }
00050
00051 private:
00052 DebugLines* m_pLines;
00053 };
00054
00055 class DebugTriangleDrawCallback : public btTriangleCallback
00056 {
00057 private:
00058
00059 DebugHelper *mDebugHelper;
00060 btTransform mTransform;
00061 btVector3 mColor;
00062
00063 public:
00064
00065 DebugTriangleDrawCallback(DebugHelper *db, btTransform &bt, const btVector3& color) :
00066 btTriangleCallback(),
00067 mDebugHelper(db),
00068 mTransform(bt),
00069 mColor(color)
00070 {
00071
00072 }
00073
00074 void processTriangle(btVector3* triangle, int partId, int triangleIndex)
00075 {
00076 mDebugHelper->drawLine (*triangle, *(triangle+1), mColor);
00077 mDebugHelper->drawLine (*(triangle+1), *(triangle+2), mColor);
00078 mDebugHelper->drawLine (*(triangle+2), *triangle, mColor);
00079 }
00080 };
00081
00082 class HeightmapCollisionShape : public CollisionShape
00083 {
00084 public:
00085 HeightmapCollisionShape(int width, int length, Ogre::Vector3& scale, Ogre::Real* pHeightData, bool bFlip)
00086 {
00087 int upIndex = 1;
00088 bool useFloatDatam=true;
00089 bool flipQuadEdges=bFlip;
00090
00091 btHeightfieldTerrainShape* pHeightShape =
00092 new btHeightfieldTerrainShape(width, length, pHeightData, scale.y, upIndex, useFloatDatam, flipQuadEdges);
00093 pHeightShape->setUseDiamondSubdivision(true);
00094
00095 mShape = pHeightShape;
00096
00097 btVector3 sc(scale.x, scale.y, scale.z);
00098 mShape->setLocalScaling(sc);
00099
00100 }
00101
00102 virtual ~HeightmapCollisionShape()
00103 {
00104 }
00105
00106 bool drawWireFrame(DebugLines *wire,
00107 const Ogre::Vector3 &pos = Ogre::Vector3::ZERO,
00108 const Ogre::Quaternion &quat= Ogre::Quaternion::IDENTITY) const
00109 {
00110 btHeightfieldTerrainShape* pHeightShape = static_cast<btHeightfieldTerrainShape*>(mShape);
00111
00112 btTransform bt;
00113 bt.setIdentity();
00114
00115 btVector3 colour(255.0, 255.0, 255.0);
00116
00117 DebugHelper ddraw(wire);
00118 DebugTriangleDrawCallback cb(&ddraw, bt, colour);
00119
00120 btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
00121 btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
00122 pHeightShape->processAllTriangles(&cb, aabbMin, aabbMax);
00123 return true;
00124 }
00125
00126 };
00127 }
00128
00129
00130 #endif // _OGREBULLET_HEIGHTMAP_