Переглянути джерело

Merge pull request #977 from sgrenier/next

Fixed an issue with static rigid bodies attached to a node within a node hierarchy
Steve Grenier 12 роки тому
батько
коміт
8f9ce4636e

+ 28 - 15
gameplay/src/Node.cpp

@@ -191,7 +191,12 @@ void Node::remove()
 
     if (parent && parent->_notifyHierarchyChanged)
     {
+        Node* group = Scene::getScene()->findNode("group1");
+        Node* node = Scene::getScene()->findNode("board");
         parent->hierarchyChanged();
+        node->getWorldMatrix();
+        node = NULL;
+        group = NULL;
     }
 }
 
@@ -402,6 +407,11 @@ Node* Node::getRootNode() const
     return n;
 }
 
+bool Node::isStatic() const
+{
+    return (_collisionObject && _collisionObject->isStatic());
+}
+
 const Matrix& Node::getWorldMatrix() const
 {
     if (_dirtyBits & NODE_DIRTY_WORLD)
@@ -410,23 +420,26 @@ const Matrix& Node::getWorldMatrix() const
         // parent calls our getWorldMatrix() method as a result of the following calculations.
         _dirtyBits &= ~NODE_DIRTY_WORLD;
 
-        // If we have a parent, multiply our parent world transform by our local
-        // transform to obtain our final resolved world transform.
-        Node* parent = getParent();
-        if (parent && (!_collisionObject || _collisionObject->isKinematic()))
-        {
-            Matrix::multiply(parent->getWorldMatrix(), getMatrix(), &_world);
-        }
-        else
+        if (!isStatic())
         {
-            _world = getMatrix();
-        }
+            // If we have a parent, multiply our parent world transform by our local
+            // transform to obtain our final resolved world transform.
+            Node* parent = getParent();
+            if (parent)
+            {
+                Matrix::multiply(parent->getWorldMatrix(), getMatrix(), &_world);
+            }
+            else
+            {
+                _world = getMatrix();
+            }
 
-        // Our world matrix was just updated, so call getWorldMatrix() on all child nodes
-        // to force their resolved world matrices to be updated.
-        for (Node* child = getFirstChild(); child != NULL; child = child->getNextSibling())
-        {
-            child->getWorldMatrix();
+            // Our world matrix was just updated, so call getWorldMatrix() on all child nodes
+            // to force their resolved world matrices to be updated.
+            for (Node* child = getFirstChild(); child != NULL; child = child->getNextSibling())
+            {
+                child->getWorldMatrix();
+            }
         }
     }
 

+ 11 - 0
gameplay/src/Node.h

@@ -230,6 +230,17 @@ public:
      * Gets the top level node in this node's parent hierarchy.
      */
     Node* getRootNode() const;
+    
+    /**
+     * Returns whether the transformation of this node is static.
+     *
+     * Nodes that have static rigid bodies attached to them are considered static.
+     *
+     * @return True if the transformation of this Node is static, false otherwise.
+     *
+     * @see Transform::isStatic()
+     */
+    bool isStatic() const;
 
     /**
      * Gets the world matrix corresponding to this node.

+ 6 - 0
gameplay/src/PhysicsCollisionObject.cpp

@@ -85,6 +85,12 @@ bool PhysicsCollisionObject::isKinematic() const
     }
 }
 
+bool PhysicsCollisionObject::isStatic() const
+{
+    GP_ASSERT(getCollisionObject());
+    return getCollisionObject()->isStaticObject();
+}
+
 bool PhysicsCollisionObject::isDynamic() const
 {
     GP_ASSERT(getCollisionObject());

+ 10 - 0
gameplay/src/PhysicsCollisionObject.h

@@ -178,6 +178,16 @@ public:
      */
     bool isKinematic() const;
 
+    /**
+     * Returns whether this collision object is static.
+     *
+     * A static collision object is not simulated by the physics system and cannot be
+     * transformed once created.
+     *
+     * @return true if the collision object is static.
+     */
+    bool isStatic() const;
+
     /**
      * Returns whether this collision object is dynamic.
      *

+ 156 - 22
gameplay/src/Transform.cpp

@@ -92,36 +92,39 @@ const Matrix& Transform::getMatrix() const
 {
     if (_matrixDirtyBits)
     {
-        bool hasTranslation = !_translation.isZero();
-        bool hasScale = !_scale.isOne();
-        bool hasRotation = !_rotation.isIdentity();
-
-        // Compose the matrix in TRS order since we use column-major matrices with column vectors and
-        // multiply M*v (as opposed to XNA and DirectX that use row-major matrices with row vectors and multiply v*M).
-        if (hasTranslation || (_matrixDirtyBits & DIRTY_TRANSLATION) == DIRTY_TRANSLATION)
+        if (!isStatic())
         {
-            Matrix::createTranslation(_translation, &_matrix);
-            if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
+            bool hasTranslation = !_translation.isZero();
+            bool hasScale = !_scale.isOne();
+            bool hasRotation = !_rotation.isIdentity();
+
+            // Compose the matrix in TRS order since we use column-major matrices with column vectors and
+            // multiply M*v (as opposed to XNA and DirectX that use row-major matrices with row vectors and multiply v*M).
+            if (hasTranslation || (_matrixDirtyBits & DIRTY_TRANSLATION) == DIRTY_TRANSLATION)
             {
-                _matrix.rotate(_rotation);
+                Matrix::createTranslation(_translation, &_matrix);
+                if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
+                {
+                    _matrix.rotate(_rotation);
+                }
+                if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
+                {
+                    _matrix.scale(_scale);
+                }
             }
-            if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
+            else if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
             {
-                _matrix.scale(_scale);
+                Matrix::createRotation(_rotation, &_matrix);
+                if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
+                {
+                    _matrix.scale(_scale);
+                }
             }
-        }
-        else if (hasRotation || (_matrixDirtyBits & DIRTY_ROTATION) == DIRTY_ROTATION)
-        {
-            Matrix::createRotation(_rotation, &_matrix);
-            if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
+            else if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
             {
-                _matrix.scale(_scale);
+                Matrix::createScale(_scale, &_matrix);
             }
         }
-        else if (hasScale || (_matrixDirtyBits & DIRTY_SCALE) == DIRTY_SCALE)
-        {
-            Matrix::createScale(_scale, &_matrix);
-        }
 
         _matrixDirtyBits &= ~DIRTY_TRANSLATION & ~DIRTY_ROTATION & ~DIRTY_SCALE;
     }
@@ -278,6 +281,9 @@ void Transform::getRightVector(Vector3* dst) const
 
 void Transform::rotate(float qx, float qy, float qz, float qw)
 {
+    if (isStatic())
+        return;
+
     Quaternion q(qx, qy, qz, qw);
     _rotation.multiply(q);
     dirty(DIRTY_ROTATION);
@@ -285,12 +291,18 @@ void Transform::rotate(float qx, float qy, float qz, float qw)
 
 void Transform::rotate(const Quaternion& rotation)
 {
+    if (isStatic())
+        return;
+
     _rotation.multiply(rotation);
     dirty(DIRTY_ROTATION);
 }
 
 void Transform::rotate(const Vector3& axis, float angle)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromAxisAngle(axis, angle, &rotationQuat);
     _rotation.multiply(rotationQuat);
@@ -300,6 +312,9 @@ void Transform::rotate(const Vector3& axis, float angle)
 
 void Transform::rotate(const Matrix& rotation)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
     _rotation.multiply(rotationQuat);
@@ -308,6 +323,9 @@ void Transform::rotate(const Matrix& rotation)
 
 void Transform::rotateX(float angle)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromAxisAngle(Vector3::unitX(), angle, &rotationQuat);
     _rotation.multiply(rotationQuat);
@@ -316,6 +334,9 @@ void Transform::rotateX(float angle)
 
 void Transform::rotateY(float angle)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromAxisAngle(Vector3::unitY(), angle, &rotationQuat);
     _rotation.multiply(rotationQuat);
@@ -324,6 +345,9 @@ void Transform::rotateY(float angle)
 
 void Transform::rotateZ(float angle)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromAxisAngle(Vector3::unitZ(), angle, &rotationQuat);
     _rotation.multiply(rotationQuat);
@@ -332,12 +356,18 @@ void Transform::rotateZ(float angle)
 
 void Transform::scale(float scale)
 {
+    if (isStatic())
+        return;
+
     _scale.scale(scale);
     dirty(DIRTY_SCALE);
 }
 
 void Transform::scale(float sx, float sy, float sz)
 {
+    if (isStatic())
+        return;
+
     _scale.x *= sx;
     _scale.y *= sy;
     _scale.z *= sz;
@@ -346,6 +376,9 @@ void Transform::scale(float sx, float sy, float sz)
 
 void Transform::scale(const Vector3& scale)
 {
+    if (isStatic())
+        return;
+
     _scale.x *= scale.x;
     _scale.y *= scale.y;
     _scale.z *= scale.z;
@@ -354,24 +387,36 @@ void Transform::scale(const Vector3& scale)
 
 void Transform::scaleX(float sx)
 {
+    if (isStatic())
+        return;
+
     _scale.x *= sx;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::scaleY(float sy)
 {
+    if (isStatic())
+        return;
+
     _scale.y *= sy;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::scaleZ(float sz)
 {
+    if (isStatic())
+        return;
+
     _scale.z *= sz;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::set(const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
 {
+    if (isStatic())
+        return;
+
     _scale.set(scale);
     _rotation.set(rotation);
     _translation.set(translation);
@@ -380,6 +425,9 @@ void Transform::set(const Vector3& scale, const Quaternion& rotation, const Vect
 
 void Transform::set(const Vector3& scale, const Matrix& rotation, const Vector3& translation)
 {
+    if (isStatic())
+        return;
+
     _scale.set(scale);
     Quaternion rotationQuat;
     Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
@@ -390,6 +438,9 @@ void Transform::set(const Vector3& scale, const Matrix& rotation, const Vector3&
 
 void Transform::set(const Vector3& scale, const Vector3& axis, float angle, const Vector3& translation)
 {
+    if (isStatic())
+        return;
+
     _scale.set(scale);
     _rotation.set(axis, angle);
     _translation.set(translation);
@@ -398,6 +449,9 @@ void Transform::set(const Vector3& scale, const Vector3& axis, float angle, cons
 
 void Transform::set(const Transform& transform)
 {
+    if (isStatic())
+        return;
+
     _scale.set(transform._scale);
     _rotation.set(transform._rotation);
     _translation.set(transform._translation);
@@ -406,6 +460,9 @@ void Transform::set(const Transform& transform)
 
 void Transform::setIdentity()
 {
+    if (isStatic())
+        return;
+
     _scale.set(1.0f, 1.0f, 1.0f);
     _rotation.setIdentity();
     _translation.set(0.0f, 0.0f, 0.0f);
@@ -414,12 +471,18 @@ void Transform::setIdentity()
 
 void Transform::setScale(float scale)
 {
+    if (isStatic())
+        return;
+
     _scale.set(scale, scale, scale);
     dirty(DIRTY_SCALE);
 }
 
 void Transform::setScale(float sx, float sy, float sz)
 {
+    if (isStatic())
+        return;
+
     _scale.set(sx, sy, sz);
     dirty(DIRTY_SCALE);
 }
@@ -432,36 +495,54 @@ void Transform::setScale(const Vector3& scale)
 
 void Transform::setScaleX(float sx)
 {
+    if (isStatic())
+        return;
+
     _scale.x = sx;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::setScaleY(float sy)
 {
+    if (isStatic())
+        return;
+
     _scale.y = sy;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::setScaleZ(float sz)
 {
+    if (isStatic())
+        return;
+
     _scale.z = sz;
     dirty(DIRTY_SCALE);
 }
 
 void Transform::setRotation(const Quaternion& rotation)
 {
+    if (isStatic())
+        return;
+
     _rotation.set(rotation);
     dirty(DIRTY_ROTATION);
 }
 
 void Transform::setRotation(float qx, float qy, float qz, float qw)
 {
+    if (isStatic())
+        return;
+
     _rotation.set(qx, qy, qz, qw);
     dirty(DIRTY_ROTATION);
 }
 
 void Transform::setRotation(const Matrix& rotation)
 {
+    if (isStatic())
+        return;
+
     Quaternion rotationQuat;
     Quaternion::createFromRotationMatrix(rotation, &rotationQuat);
     _rotation.set(rotationQuat);
@@ -470,42 +551,63 @@ void Transform::setRotation(const Matrix& rotation)
 
 void Transform::setRotation(const Vector3& axis, float angle)
 {
+    if (isStatic())
+        return;
+
     _rotation.set(axis, angle);
     dirty(DIRTY_ROTATION);
 }
 
 void Transform::setTranslation(const Vector3& translation)
 {
+    if (isStatic())
+        return;
+
     _translation.set(translation);
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::setTranslation(float tx, float ty, float tz)
 {
+    if (isStatic())
+        return;
+
     _translation.set(tx, ty, tz);
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::setTranslationX(float tx)
 {
+    if (isStatic())
+        return;
+
     _translation.x = tx;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::setTranslationY(float ty)
 {
+    if (isStatic())
+        return;
+
     _translation.y = ty;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::setTranslationZ(float tz)
 {
+    if (isStatic())
+        return;
+
     _translation.z = tz;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::translate(float tx, float ty, float tz)
 {
+    if (isStatic())
+        return;
+
     _translation.x += tx;
     _translation.y += ty;
     _translation.z += tz;
@@ -514,6 +616,9 @@ void Transform::translate(float tx, float ty, float tz)
 
 void Transform::translate(const Vector3& translation)
 {
+    if (isStatic())
+        return;
+
     _translation.x += translation.x;
     _translation.y += translation.y;
     _translation.z += translation.z;
@@ -522,24 +627,36 @@ void Transform::translate(const Vector3& translation)
 
 void Transform::translateX(float tx)
 {
+    if (isStatic())
+        return;
+
     _translation.x += tx;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::translateY(float ty)
 {
+    if (isStatic())
+        return;
+
     _translation.y += ty;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::translateZ(float tz)
 {
+    if (isStatic())
+        return;
+
     _translation.z += tz;
     dirty(DIRTY_TRANSLATION);
 }
 
 void Transform::translateLeft(float amount)
 {
+    if (isStatic())
+        return;
+
     // Force the current transform matrix to be updated.
     getMatrix();
 
@@ -553,6 +670,9 @@ void Transform::translateLeft(float amount)
 
 void Transform::translateUp(float amount)
 {
+    if (isStatic())
+        return;
+
     // Force the current transform matrix to be updated.
     getMatrix();
 
@@ -566,6 +686,9 @@ void Transform::translateUp(float amount)
 
 void Transform::translateForward(float amount)
 {
+    if (isStatic())
+        return;
+
     // Force the current transform matrix to be updated.
     getMatrix();
 
@@ -579,6 +702,9 @@ void Transform::translateForward(float amount)
 
 void Transform::translateSmooth(const Vector3& target, float elapsedTime, float responseTime)
 {
+    if (isStatic())
+        return;
+
     if (elapsedTime > 0)
     {
         _translation += (target - _translation) * (elapsedTime / (elapsedTime + responseTime));
@@ -616,6 +742,11 @@ void Transform::transformVector(float x, float y, float z, float w, Vector3* dst
     _matrix.transformVector(x, y, z, w, dst);
 }
 
+bool Transform::isStatic() const
+{
+    return false;
+}
+
 unsigned int Transform::getAnimationPropertyComponentCount(int propertyId) const
 {
     switch (propertyId)
@@ -876,6 +1007,9 @@ void Transform::cloneInto(Transform* transform, NodeCloneContext &context) const
 
 void Transform::applyAnimationValueRotation(AnimationValue* value, unsigned int index, float blendWeight)
 {
+    if (isStatic())
+        return;
+
     GP_ASSERT(value);
     Quaternion::slerp(_rotation.x, _rotation.y, _rotation.z, _rotation.w, value->getFloat(index), value->getFloat(index + 1), value->getFloat(index + 2), value->getFloat(index + 3), blendWeight, 
         &_rotation.x, &_rotation.y, &_rotation.z, &_rotation.w);

+ 10 - 0
gameplay/src/Transform.h

@@ -747,6 +747,16 @@ public:
      */
     void transformVector(float x, float y, float z, float w, Vector3* dst);
 
+    /**
+     * Returns whether or not this Transform object is static.
+     *
+     * A static transform object cannot be transformed. This may be the case for special
+     * types of Transform objects, such as Nodes that have a static rigid body attached to them.
+     *
+     * @return True if this Transform is static, false otherwise.
+     */
+    virtual bool isStatic() const;
+
     /**
      * Adds a transform listener.
      *