瀏覽代碼

PhysicsCharacter updates.
Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-sgrenier

Steve Grenier 14 年之前
父節點
當前提交
4bdf569269

+ 3 - 3
gameplay/src/AnimationClip.cpp

@@ -509,17 +509,17 @@ void AnimationClip::onEnd()
     }
 }
 
-bool AnimationClip::isClipStateBitSet(char bit) const
+bool AnimationClip::isClipStateBitSet(unsigned char bit) const
 {
     return (_stateBits & bit) == bit;
 }
 
-void AnimationClip::setClipStateBit(char bit)
+void AnimationClip::setClipStateBit(unsigned char bit)
 {
     _stateBits |= bit;
 }
 
-void AnimationClip::resetClipStateBit(char bit)
+void AnimationClip::resetClipStateBit(unsigned char bit)
 {
     _stateBits &= ~bit;
 }

+ 13 - 13
gameplay/src/AnimationClip.h

@@ -228,15 +228,15 @@ private:
     /**
      * State bits.
      */
-    static const char CLIP_IS_PLAYING_BIT = 0x01;             // Bit representing whether AnimationClip is a running clip in AnimationController
-    static const char CLIP_IS_STARTED_BIT = 0x02;             // Bit representing whether the AnimationClip has actually been started (ie: received first call to update())
-    static const char CLIP_IS_FADING_OUT_STARTED_BIT = 0x04;  // Bit representing that a cross fade has started.
-    static const char CLIP_IS_FADING_OUT_BIT = 0x08;          // Bit representing whether the clip is fading out.
-    static const char CLIP_IS_FADING_IN_BIT = 0x10;           // Bit representing whether the clip is fading out.
-    static const char CLIP_IS_MARKED_FOR_REMOVAL_BIT = 0x20;  // Bit representing whether the clip has ended and should be removed from the AnimationController.
-    static const char CLIP_IS_RESTARTED_BIT = 0x40;           // Bit representing if the clip should be restarted by the AnimationController.
-    static const char CLIP_IS_PAUSED_BIT = 0x80;              // Bit representing if the clip is currently paused.
-    static const char CLIP_ALL_BITS = 0xFF;                   // Bit mask for all the state bits.
+    static const unsigned char CLIP_IS_PLAYING_BIT = 0x01;             // Bit representing whether AnimationClip is a running clip in AnimationController
+    static const unsigned char CLIP_IS_STARTED_BIT = 0x02;             // Bit representing whether the AnimationClip has actually been started (ie: received first call to update())
+    static const unsigned char CLIP_IS_FADING_OUT_STARTED_BIT = 0x04;  // Bit representing that a cross fade has started.
+    static const unsigned char CLIP_IS_FADING_OUT_BIT = 0x08;          // Bit representing whether the clip is fading out.
+    static const unsigned char CLIP_IS_FADING_IN_BIT = 0x10;           // Bit representing whether the clip is fading out.
+    static const unsigned char CLIP_IS_MARKED_FOR_REMOVAL_BIT = 0x20;  // Bit representing whether the clip has ended and should be removed from the AnimationController.
+    static const unsigned char CLIP_IS_RESTARTED_BIT = 0x40;           // Bit representing if the clip should be restarted by the AnimationController.
+    static const unsigned char CLIP_IS_PAUSED_BIT = 0x80;              // Bit representing if the clip is currently paused.
+    static const unsigned char CLIP_ALL_BITS = 0xFF;                   // Bit mask for all the state bits.
 
     /**
      * ListenerEvent.
@@ -297,24 +297,24 @@ private:
     /**
      * Determines whether the given bit is set in the AnimationClip's state.
      */
-    bool isClipStateBitSet(char bit) const;
+    bool isClipStateBitSet(unsigned char bit) const;
 
     /**
      * Sets the given bit in the AnimationClip's state.
      */
-    void setClipStateBit(char bit);
+    void setClipStateBit(unsigned char bit);
 
     /**
      * Resets the given bit in the AnimationClip's state.
      */
-    void resetClipStateBit(char bit);
+    void resetClipStateBit(unsigned char bit);
 
     std::string _id;                                    // AnimationClip ID.
     Animation* _animation;                              // The Animation this clip is created from.
     unsigned long _startTime;                           // Start time of the clip.
     unsigned long _endTime;                             // End time of the clip.
     unsigned long _duration;                            // The total duration.
-    char _stateBits;                                    // Bit flag used to keep track of the clip's current state.
+    unsigned char _stateBits;                           // Bit flag used to keep track of the clip's current state.
     float _repeatCount;                                 // The clip's repeat count.
     unsigned long _activeDuration;                      // The active duration of the clip.
     float _speed;                                       // The speed that the clip is playing. Default is 1.0. Negative goes in reverse.

+ 2 - 1
gameplay/src/Camera.cpp

@@ -2,6 +2,8 @@
 #include "Camera.h"
 #include "Game.h"
 #include "Node.h"
+#include "Game.h"
+#include "PhysicsController.h"
 
 // Camera dirty bits
 #define CAMERA_DIRTY_VIEW 1
@@ -341,7 +343,6 @@ void Camera::pickRay(const Viewport* viewport, float x, float y, Ray* dst)
     dst->set(nearPoint, direction);
 }
 
-
 void Camera::transformChanged(Transform* transform, long cookie)
 {
     _dirtyBits |= CAMERA_DIRTY_VIEW | CAMERA_DIRTY_INV_VIEW | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;

+ 4 - 4
gameplay/src/Node.cpp

@@ -717,12 +717,12 @@ void Node::setParticleEmitter(ParticleEmitter* emitter)
     }
 }
 
-PhysicsRigidBody* Node::getPhysicsRigidBody() const
+PhysicsRigidBody* Node::getRigidBody() const
 {
     return _physicsRigidBody;
 }
 
-void Node::setPhysicsRigidBody(PhysicsRigidBody::Type type, float mass, float friction,
+void Node::setRigidBody(PhysicsRigidBody::Type type, float mass, float friction,
         float restitution, float linearDamping, float angularDamping)
 {
     SAFE_DELETE(_physicsRigidBody);
@@ -731,14 +731,14 @@ void Node::setPhysicsRigidBody(PhysicsRigidBody::Type type, float mass, float fr
         _physicsRigidBody = new PhysicsRigidBody(this, type, mass, friction, restitution, linearDamping, angularDamping);
 }
 
-void Node::setPhysicsRigidBody(const char* filePath)
+void Node::setRigidBody(const char* filePath)
 {
     SAFE_DELETE(_physicsRigidBody);
 
     _physicsRigidBody = PhysicsRigidBody::create(this, filePath);
 }
 
-void Node::setPhysicsRigidBody(Properties* properties)
+void Node::setRigidBody(Properties* properties)
 {
     SAFE_DELETE(_physicsRigidBody);
 

+ 4 - 4
gameplay/src/Node.h

@@ -365,7 +365,7 @@ public:
      *
      * @return The pointer to this node's physics rigid body or NULL.
      */
-    PhysicsRigidBody* getPhysicsRigidBody() const;
+    PhysicsRigidBody* getRigidBody() const;
 
     /**
      * Sets (or disables) the physics rigid body for this node.
@@ -382,7 +382,7 @@ public:
      * @param linearDamping The percentage of linear velocity lost per second (between 0.0 and 1.0).
      * @param angularDamping The percentage of angular velocity lost per second (between 0.0 and 1.0).
      */
-    void setPhysicsRigidBody(PhysicsRigidBody::Type type, float mass = 0.0f, float friction = 0.5f,
+    void setRigidBody(PhysicsRigidBody::Type type, float mass = 0.0f, float friction = 0.5f,
         float restitution = 0.0f, float linearDamping = 0.0f, float angularDamping = 0.0f);
 
     /**
@@ -390,14 +390,14 @@ public:
      * 
      * @param filePath The path to the file that contains the rigid body definition.
      */
-    void setPhysicsRigidBody(const char* filePath);
+    void setRigidBody(const char* filePath);
 
     /**
      * Sets the physics rigid body for this node from the given properties object.
      * 
      * @param properties The properties object defining the rigid body (must have namespace equal to 'rigidbody').
      */
-    void setPhysicsRigidBody(Properties* properties);
+    void setRigidBody(Properties* properties);
 
     /**
      * Returns the bounding sphere for the Node, in world space.

+ 1 - 1
gameplay/src/PhysicsConstraint.cpp

@@ -155,7 +155,7 @@ Vector3 PhysicsConstraint::getWorldCenterOfMass(const Model* model)
 
 Vector3 PhysicsConstraint::offsetByCenterOfMass(const Node* node, const Vector3& v)
 {
-    btVector3 centerOfMassOffset = ((PhysicsMotionState*)node->getPhysicsRigidBody()->_body->getMotionState())->_centerOfMassOffset.getOrigin();
+    btVector3 centerOfMassOffset = ((PhysicsMotionState*)node->getRigidBody()->_body->getMotionState())->_centerOfMassOffset.getOrigin();
     return Vector3(v.x + centerOfMassOffset.x(), v.y + centerOfMassOffset.y(), v.z + centerOfMassOffset.z());
 }
 

+ 11 - 1
gameplay/src/PhysicsController.cpp

@@ -40,6 +40,16 @@ void PhysicsController::addStatusListener(Listener* listener)
     _listeners->push_back(listener);
 }
 
+PhysicsCharacter* PhysicsController::createCharacter(Node* node, float radius, float height, const Vector3& center)
+{
+    return new PhysicsCharacter(node, radius, height, center);
+}
+
+void PhysicsController::destroyCharacter(PhysicsCharacter* character)
+{
+    SAFE_DELETE(character);
+}
+
 PhysicsFixedConstraint* PhysicsController::createFixedConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b)
 {
     checkConstraintRigidBodies(a, b);
@@ -110,7 +120,7 @@ PhysicsSpringConstraint* PhysicsController::createSpringConstraint(PhysicsRigidB
     return constraint;
 }
 
-const Vector3& PhysicsController::getGravity(const Vector3& gravity) const
+const Vector3& PhysicsController::getGravity() const
 {
     return _gravity;
 }

+ 39 - 1
gameplay/src/PhysicsController.h

@@ -8,6 +8,7 @@
 #include "PhysicsSocketConstraint.h"
 #include "PhysicsSpringConstraint.h"
 #include "PhysicsRigidBody.h"
+#include "PhysicsCharacter.h"
 
 namespace gameplay
 {
@@ -18,6 +19,7 @@ namespace gameplay
 class PhysicsController : public btCollisionWorld::ContactResultCallback
 {
     friend class Game;
+    friend Camera;
     friend class PhysicsConstraint;
     friend class PhysicsRigidBody;
     friend class PhysicsCharacter;
@@ -60,6 +62,42 @@ public:
      */
     void addStatusListener(PhysicsController::Listener* listener);
 
+    /**
+     * Creates a new PhysicsCharacter.
+     *
+     * The created character is added to the physics world and automatically receives
+     * physics updates to handle interactions and collisions between the character
+     * and other physics objects in the world. The character will continue to receive
+     * updates until it is destroyed via the destroyCharacter(PhysicsCharacter*) method.
+     *
+     * The node may point to any node in the scene that you wish to control as a character.
+     * When a PhysicsCharacter is created for a particular node, the game will normally
+     * perform all movement directly through the PhysicsCharacter interface and not through
+     * the node itself.
+     *
+     * The radius, height and center parameters define a capsule volume that is used
+     * to represent the character in the physics world. All collision handling is 
+     * performed using this capsule.
+     *
+     * Note that PhysicsCharacter should not be mixed with rigid bodies. Therefore, you 
+     * should ensure that the node (and any of its children) used to create the
+     * PhysicsCharacter does not have any rigid bodies assigned. Doing so will cause
+     * unexpected results.
+     *
+     * @param node Scene node that represents the character.
+     * @param radius Radius of capsule volume used for character collisions.
+     * @param height Height of the capsule volume used for character collisions.
+     * @param center Center point of the capsule volume for the character.
+     */
+    PhysicsCharacter* createCharacter(Node* node, float radius, float height, const Vector3& center = Vector3::zero());
+
+    /**
+     * Destroys a PhysicsCharacter and removes it from the physics world.
+     *
+     * @param character PhysicsCharacter to destroy.
+     */
+    void destroyCharacter(PhysicsCharacter* character);
+
     /**
      * Creates a fixed constraint.
      * 
@@ -174,7 +212,7 @@ public:
      * 
      * @return The gravity vector.
      */
-    const Vector3& getGravity(const Vector3& gravity) const;
+    const Vector3& getGravity() const;
 
     /**
      * Sets the gravity vector for the simulated physics world.

+ 1 - 1
gameplay/src/PhysicsMotionState.cpp

@@ -22,7 +22,7 @@ PhysicsMotionState::~PhysicsMotionState()
 
 void PhysicsMotionState::getWorldTransform(btTransform &transform) const
 {
-    if (_node->getPhysicsRigidBody() && _node->getPhysicsRigidBody()->isKinematic())
+    if (_node->getRigidBody() && _node->getRigidBody()->isKinematic())
         updateTransformFromNode();
 
     transform = _centerOfMassOffset.inverse() * _worldTransform;

+ 25 - 1
gameplay/src/Ray.cpp

@@ -105,7 +105,31 @@ float Ray::intersects(const Frustum& frustum) const
 
 float Ray::intersects(const Plane& plane) const
 {
-    return plane.intersects(*this);
+    const Vector3& normal = plane.getNormal();
+    // If the origin of the ray is on the plane then the distance is zero.
+    float m = (normal.dot(_origin) + plane.getDistance());
+    if (fabs(m) < MATH_EPSILON)
+    {
+        return 0.0f;
+    }
+
+    float dot = normal.dot(_direction);
+    
+    // If the dot product of the plane's normal and this ray's direction is zero,
+    // then the ray is parallel to the plane and does not intersect it.
+    if ( dot == 0.0f )
+    {
+        return INTERSECTS_NONE;
+    }
+    
+    // Calculate the distance along the ray's direction vector to the point where
+    // the ray intersects the plane (if it is negative the plane is behind the ray).
+    float d = -m / dot;
+    if ( d < 0.0f )
+    {
+        return INTERSECTS_NONE;
+    }
+    return d;
 }
 
 void Ray::set(const Vector3& origin, const Vector3& direction)

+ 2 - 1
gameplay/src/Ray.h

@@ -110,7 +110,8 @@ public:
     float intersects(const Frustum& frustum) const;
 
     /**
-     * Tests whether this ray intersects the specified plane.
+     * Tests whether this ray intersects the specified plane and returns the distance
+     * from the origin of the ray to the plane.
      *
      * @param plane The plane to test intersection with.
      * 

+ 4 - 4
gameplay/src/SceneLoader.cpp

@@ -291,7 +291,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
                         // Set the specified model during physics rigid body creation.
                         Model* model = node->getModel();
                         node->setModel(modelNode->getModel());
-                        node->setPhysicsRigidBody(p);
+                        node->setRigidBody(p);
                         node->setModel(model);
                     }
                 }
@@ -299,7 +299,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             else if (!node->getModel())
                 WARN_VARG("Attempting to set a rigid body on node '%s', which has no model.", sceneNode._nodeID);
             else
-                node->setPhysicsRigidBody(p);
+                node->setRigidBody(p);
             break;
         }
         default:
@@ -768,7 +768,7 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
                 WARN_VARG("Node '%s' to be used as 'rigidBodyA' for constraint %s cannot be found.", name, constraint->getId());
                 continue;
             }
-            PhysicsRigidBody* rbA = rbANode->getPhysicsRigidBody();
+            PhysicsRigidBody* rbA = rbANode->getRigidBody();
             if (!rbA)
             {
                 WARN_VARG("Node '%s' to be used as 'rigidBodyA' does not have a rigid body.", name);
@@ -789,7 +789,7 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
                     WARN_VARG("Node '%s' to be used as 'rigidBodyB' for constraint %s cannot be found.", name, constraint->getId());
                     continue;
                 }
-                rbB = rbBNode->getPhysicsRigidBody();
+                rbB = rbBNode->getRigidBody();
                 if (!rbB)
                 {
                     WARN_VARG("Node '%s' to be used as 'rigidBodyB' does not have a rigid body.", name);

+ 2 - 2
gameplay/src/SpriteBatch.cpp

@@ -250,8 +250,8 @@ void SpriteBatch::draw(const Vector3& position, const Vector3& right, const Vect
 {
     // Calculate the vertex positions.
     Vector3 p[4];
-    p[0] = position - 0.5f * width * right;
-    p[1] = position + 0.5f * width * right;
+    p[0] = position - 0.5f * width * right - 0.5f * height * forward;
+    p[1] = position + 0.5f * width * right - 0.5f * height * forward;
     p[2] = p[0] + height * forward;
     p[3] = p[1] + height * forward;
 

+ 1 - 1
gameplay/src/Vector2.cpp

@@ -139,7 +139,7 @@ float Vector2::distanceSquared(const Vector2& v) const
     return (dx * dx + dy * dy);
 }
 
-float Vector2::dot(const Vector2& v)
+float Vector2::dot(const Vector2& v) const
 {
     return (x * v.x + y * v.y);
 }

+ 1 - 1
gameplay/src/Vector2.h

@@ -183,7 +183,7 @@ public:
      * 
      * @return The dot product.
      */
-    float dot(const Vector2& v);
+    float dot(const Vector2& v) const;
 
     /**
      * Returns the dot product between the specified vectors.

+ 1 - 1
gameplay/src/Vector3.cpp

@@ -203,7 +203,7 @@ float Vector3::distanceSquared(const Vector3& v) const
     return (dx * dx + dy * dy + dz * dz);
 }
 
-float Vector3::dot(const Vector3& v)
+float Vector3::dot(const Vector3& v) const
 {
     return (x * v.x + y * v.y + z * v.z);
 }

+ 1 - 1
gameplay/src/Vector3.h

@@ -230,7 +230,7 @@ public:
      * 
      * @return The dot product.
      */
-    float dot(const Vector3& v);
+    float dot(const Vector3& v) const;
 
     /**
      * Returns the dot product between the specified vectors.

+ 1 - 1
gameplay/src/Vector4.cpp

@@ -204,7 +204,7 @@ float Vector4::distanceSquared(const Vector4& v) const
     return (dx * dx + dy * dy + dz * dz + dw * dw);
 }
 
-float Vector4::dot(const Vector4& v)
+float Vector4::dot(const Vector4& v) const
 {
     return (x * v.x + y * v.y + z * v.z + w * v.w);
 }

+ 1 - 1
gameplay/src/Vector4.h

@@ -221,7 +221,7 @@ public:
      * 
      * @return The dot product.
      */
-    float dot(const Vector4& v);
+    float dot(const Vector4& v) const;
 
     /**
      * Returns the dot product between the specified vectors.