Quellcode durchsuchen

Added support for bounding spheres in Scene::drawDebug().
Updated PhysicsCharacter with some in-progress/experimental code to apply impulses to dynamic rigid bodies.

Steve Grenier vor 13 Jahren
Ursprung
Commit
e4b1a881e4

+ 9 - 14
gameplay/src/PhysicsCharacter.cpp

@@ -71,9 +71,6 @@ PhysicsCharacter::PhysicsCharacter(Node* node, const PhysicsCollisionShape::Defi
 {
 	setMaxSlopeAngle(45.0f);
 
-    // Set the collision flags on the ghost object to indicate it's a character
-    //_ghostObject->setCollisionFlags(_ghostObject->getCollisionFlags() | btCollisionObject::CF_CHARACTER_OBJECT);
-
     // Register ourselves as an action on the physics world so we are called back during physics ticks
     Game::getInstance()->getPhysicsController()->_world->addAction(this);
 }
@@ -432,7 +429,7 @@ void PhysicsCharacter::stepForwardAndStrafe(btCollisionWorld* collisionWorld, fl
     {
         // No velocity, so we aren't moving
         return;
-    }
+	}
 
     // Translate the target position by the velocity vector (already scaled by t)
     btVector3 targetPosition = _currentPosition + velocity;
@@ -474,15 +471,14 @@ void PhysicsCharacter::stepForwardAndStrafe(btCollisionWorld* collisionWorld, fl
 
 		if (callback.hasHit())
         {
-			// We hit something so can move only a fraction
-			//btScalar hitDistance = (callback.m_hitPointWorld - _currentPosition).length();
-
-            //targetPosition = _currentPosition;
-			//targetPosition.setInterpolate3(_currentPosition, targetPosition, callback.m_closestHitFraction * 0.1f);
-
-			//btVector3 normalDir = callback.m_hitNormalWorld;
-			//normalDir.normalize();
-			//targetPosition = callback.m_hitPointWorld + (normalDir * 0.2f);
+			Vector3 normal(callback.m_hitNormalWorld.x(), callback.m_hitNormalWorld.y(), callback.m_hitNormalWorld.z());
+			PhysicsCollisionObject* o = Game::getInstance()->getPhysicsController()->getCollisionObject(callback.m_hitCollisionObject);
+			if (o->getType() == PhysicsCollisionObject::RIGID_BODY && o->isDynamic())
+			{
+				PhysicsRigidBody* rb = static_cast<PhysicsRigidBody*>(o);
+				normal.normalize();
+				rb->applyImpulse(-normal);
+			}
 
 			updateTargetPositionFromCollision(targetPosition, callback.m_hitNormalWorld);
 			btVector3 currentDir = targetPosition - _currentPosition;
@@ -501,7 +497,6 @@ void PhysicsCharacter::stepForwardAndStrafe(btCollisionWorld* collisionWorld, fl
         else
         {
             // Nothing in our way
-            //_currentPosition = targetPosition;
             break;
         }
     }

+ 5 - 0
gameplay/src/PhysicsCollisionShape.cpp

@@ -10,6 +10,11 @@ PhysicsCollisionShape::PhysicsCollisionShape(Type type, btCollisionShape* shape)
 	memset(&_shapeData, 0, sizeof(_shapeData));
 }
 
+PhysicsCollisionShape::PhysicsCollisionShape(const PhysicsCollisionShape& copy)
+{
+	// hidden
+}
+
 PhysicsCollisionShape::~PhysicsCollisionShape()
 {
 	if (_shape)

+ 5 - 0
gameplay/src/PhysicsCollisionShape.h

@@ -195,6 +195,11 @@ private:
 	 */
 	PhysicsCollisionShape(Type type, btCollisionShape* shape);
 
+	/** 
+	 * Hidden copy constructor.
+	 */
+	PhysicsCollisionShape(const PhysicsCollisionShape& copy);
+
 	/**
 	 * Destructor.
 	 */

+ 45 - 1
gameplay/src/Scene.cpp

@@ -356,6 +356,7 @@ void drawDebugLine(MeshBatch* batch, const Vector3& point1, const Vector3& point
 }
 
 #define DEBUG_BOX_COLOR Vector3(0, 1, 0)
+#define DEBUG_SPHERE_COLOR Vector3(0, 1, 0)
 
 void drawDebugBox(MeshBatch* batch, const BoundingBox& box, const Matrix& matrix)
 {
@@ -384,6 +385,49 @@ void drawDebugBox(MeshBatch* batch, const BoundingBox& box, const Matrix& matrix
 
 void drawDebugSphere(MeshBatch* batch, const BoundingSphere& sphere)
 {
+	// Draw three rings for the sphere (one for the x, y and z axes)
+	Vector3 pos1, pos2;
+	float step = MATH_PI * 0.2f;
+	float max = MATH_PIX2 + step;
+
+	// X ring
+	for (float r = 0.0f; r < max; r += step)
+	{
+		pos2.x = sphere.center.x;
+		pos2.y = sphere.center.y + std::cos(r) * sphere.radius;
+		pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
+
+		if (r > 0)
+			drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
+
+		pos1 = pos2;
+	}
+
+	// Y ring
+	for (float r = 0.0f; r < max; r += step)
+	{
+		pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
+		pos2.y = sphere.center.y;
+		pos2.z = sphere.center.z + std::sin(r) * sphere.radius;
+
+		if (r > 0)
+			drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
+
+		pos1 = pos2;
+	}
+
+	// Z ring
+	for (float r = 0.0f; r < max; r += step)
+	{
+		pos2.x = sphere.center.x + std::cos(r) * sphere.radius;
+		pos2.y = sphere.center.y + std::sin(r) * sphere.radius;
+		pos2.z = sphere.center.z;
+
+		if (r > 0)
+			drawDebugLine(batch, pos1, pos2, DEBUG_SPHERE_COLOR);
+
+		pos1 = pos2;
+	}
 }
 
 void drawDebugNode(MeshBatch* batch, Node* node, unsigned int debugFlags)
@@ -406,7 +450,7 @@ void drawDebugNode(MeshBatch* batch, Node* node, unsigned int debugFlags)
 		}
 	}
 
-	if ((debugFlags & Scene::DEBUG_SPHERES) && !node->getBoundingSphere().isEmpty())
+	if ((debugFlags & Scene::DEBUG_SPHERES) && model)
 	{
 		drawDebugSphere(batch, node->getBoundingSphere());
 	}