Procházet zdrojové kódy

Draw debug geometry for individual RigidBodies or CollisionShapes.
Fixed CollisionShape shapetype being uninitialized.

Lasse Öörni před 13 roky
rodič
revize
3bb70d065e

+ 1 - 1
Bin/Data/Scripts/Editor/EditorScene.as

@@ -6,7 +6,7 @@
 const int PICK_GEOMETRIES = 0;
 const int PICK_LIGHTS = 1;
 const int PICK_ZONES = 2;
-const int PICK_COLLISIONSHAPES = 3;
+const int PICK_RIGIDBODIES = 3;
 const int MAX_PICK_MODES = 4;
 
 Scene@ editorScene;

+ 16 - 10
Bin/Data/Scripts/Editor/EditorView.as

@@ -62,7 +62,7 @@ Array<String> pickModeText = {
     "Geometries",
     "Lights",
     "Zones",
-    "Col.shapes"
+    "Rigidbodies"
 };
 
 void CreateCamera()
@@ -212,7 +212,7 @@ void MoveCamera(float timeStep)
 
         if (adjust == Vector3(0, 0, 0))
             return;
-        
+
         bool moved = false;
         adjust *= timeStep * 10;
 
@@ -222,7 +222,7 @@ void MoveCamera(float timeStep)
             if (!moveSnap)
                 moved = MoveNodes(adjust * moveStep);
             break;
-            
+
         case EDIT_ROTATE:
             if (!rotateSnap)
             {
@@ -340,14 +340,20 @@ void HandlePostRenderUpdate()
             drawable.DrawDebugGeometry(debug, false);
         else
         {
-            CollisionShape@ shape = cast<CollisionShape>(selectedComponents[i]);
-            if (shape !is null)
-                shape.DrawDebugGeometry(debug, false);
+            RigidBody@ body = cast<RigidBody>(selectedComponents[i]);
+            if (body !is null)
+                body.DrawDebugGeometry(debug, false);
             else
             {
-                Joint@ joint = cast<Joint>(selectedComponents[i]);
-                if (joint !is null)
-                    joint.DrawDebugGeometry(debug, false);
+                CollisionShape@ shape = cast<CollisionShape>(selectedComponents[i]);
+                if (shape !is null)
+                    shape.DrawDebugGeometry(debug, false);
+                else
+                {
+                    Joint@ joint = cast<Joint>(selectedComponents[i]);
+                    if (joint !is null)
+                        joint.DrawDebugGeometry(debug, false);
+                }
             }
         }
     }
@@ -379,7 +385,7 @@ void ViewRaycast(bool mouseClick)
 
     Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
 
-    if (pickMode != PICK_COLLISIONSHAPES)
+    if (pickMode != PICK_RIGIDBODIES)
     {
         if (editorScene.octree is null)
             return;

+ 23 - 1
Engine/Physics/CollisionShape.cpp

@@ -45,6 +45,7 @@
 #include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
 #include <BulletCollision/CollisionShapes/btSphereShape.h>
 #include <BulletCollision/CollisionShapes/btTriangleMesh.h>
+#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
 #include <hull.h>
 
 static const String typeNames[] = 
@@ -274,6 +275,7 @@ OBJECTTYPESTATIC(CollisionShape);
 CollisionShape::CollisionShape(Context* context) :
     Component(context),
     shape_(0),
+    shapeType_(SHAPE_BOX),
     position_(Vector3::ZERO),
     rotation_(Quaternion::IDENTITY),
     size_(Vector3::ONE),
@@ -581,7 +583,27 @@ void CollisionShape::NotifyRigidBody()
 
 void CollisionShape::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 {
-    /// \todo Implement
+    if (debug && physicsWorld_ && shape_ && node_)
+    {
+        physicsWorld_->SetDebugRenderer(debug);
+        physicsWorld_->SetDebugDepthTest(depthTest);
+        
+        // Use the rigid body's world transform if possible, as it may be different from the rendering transform
+        Matrix3x4 worldTransform;
+        RigidBody* body = GetComponent<RigidBody>();
+        if (body)
+            worldTransform = Matrix3x4(body->GetPosition(), body->GetRotation(), node_->GetWorldScale());
+        else
+            worldTransform = node_->GetWorldTransform();
+        Vector3 worldPosition = worldTransform * position_;
+        Quaternion worldRotation = worldTransform.Rotation() * rotation_;
+        
+        btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
+        world->debugDrawObject(btTransform(ToBtQuaternion(worldRotation), ToBtVector3(worldPosition)), shape_, btVector3(0.0f,
+            1.0f, 0.0f));
+        
+        physicsWorld_->SetDebugRenderer(0);
+    }
 }
 
 void CollisionShape::SetModelAttr(ResourceRef value)

+ 10 - 0
Engine/Physics/PhysicsWorld.cpp

@@ -293,6 +293,16 @@ void PhysicsWorld::DrawDebugGeometry(bool depthTest)
     debugRenderer_ = 0;
 }
 
+void PhysicsWorld::SetDebugRenderer(DebugRenderer* debug)
+{
+    debugRenderer_ = debug;
+}
+
+void PhysicsWorld::SetDebugDepthTest(bool enable)
+{
+    debugDepthTest_ = enable;
+}
+
 void PhysicsWorld::CleanupGeometryCache()
 {
     // Remove cached shapes whose only reference is the cache itself

+ 5 - 1
Engine/Physics/PhysicsWorld.h

@@ -142,6 +142,10 @@ public:
     void RemoveJoint(Joint* joint);
     /// Add debug geometry to the debug renderer.
     void DrawDebugGeometry(bool depthTest);
+    /// Set debug renderer to use.
+    void SetDebugRenderer(DebugRenderer* debug);
+    /// Set debug geometry depth test mode.
+    void SetDebugDepthTest(bool enable);
     
     /// Return the Bullet physics world.
     btDiscreteDynamicsWorld* GetWorld() { return world_; }
@@ -198,7 +202,7 @@ private:
     float maxNetworkAngularVelocity_;
     /// Interpolation flag.
     bool interpolation_;
-    /// Debug renderer.
+    /// Debug renderer to use.
     DebugRenderer* debugRenderer_;
     /// Debug draw flags.
     int debugMode_;

+ 11 - 1
Engine/Physics/RigidBody.cpp

@@ -546,7 +546,17 @@ const PODVector<unsigned char>& RigidBody::GetNetAngularVelocityAttr() const
 
 void RigidBody::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 {
-    /// \todo Implement
+    if (debug && physicsWorld_ && body_)
+    {
+        physicsWorld_->SetDebugRenderer(debug);
+        physicsWorld_->SetDebugDepthTest(depthTest);
+        
+        btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
+        world->debugDrawObject(body_->getWorldTransform(), compoundShape_, IsActive() ? btVector3(1.0f, 1.0f, 1.0f) : 
+            btVector3(0.0f, 1.0f, 0.0f));
+        
+        physicsWorld_->SetDebugRenderer(0);
+    }
 }
 
 void RigidBody::OnMarkedDirty(Node* node)