From 0222c6544ee8ec6aaab87a5abc0410a0d02f265d Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Mon, 9 Dec 2013 17:32:51 -0800 Subject: [PATCH] Migration to Mat4x4 Armature not migrated yet Signed-off-by: Ricardo Quesada --- cocos/2d/CCNode.cpp | 130 ++++++++++++++----- cocos/2d/CCNode.h | 30 +++-- cocos/2d/CCSprite.cpp | 30 +++-- cocos/2d/CCSprite.h | 3 +- cocos/2d/renderer/CCNewSprite.cpp | 6 +- cocos/base/CCAffineTransform.cpp | 34 +++++ cocos/base/CCAffineTransform.h | 4 + extensions/GUI/CCEditBox/CCEditBox.cpp | 2 +- extensions/physics-nodes/CCPhysicsSprite.cpp | 10 +- extensions/physics-nodes/CCPhysicsSprite.h | 2 +- 10 files changed, 180 insertions(+), 71 deletions(-) diff --git a/cocos/2d/CCNode.cpp b/cocos/2d/CCNode.cpp index 65b0532b31..835a44d56e 100644 --- a/cocos/2d/CCNode.cpp +++ b/cocos/2d/CCNode.cpp @@ -103,9 +103,6 @@ Node::Node(void) , _anchorPointInPoints(Point::ZERO) , _anchorPoint(Point::ZERO) , _contentSize(Size::ZERO) -, _additionalTransform(AffineTransform::IDENTITY) -, _transform(AffineTransform::IDENTITY) -, _inverse(AffineTransform::IDENTITY) , _additionalTransformDirty(false) , _transformDirty(true) , _inverseDirty(true) @@ -144,6 +141,10 @@ Node::Node(void) ScriptEngineProtocol* pEngine = ScriptEngineManager::getInstance()->getScriptEngine(); _scriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone; + + kmMat4Identity(&_transform); + kmMat4Identity(&_inverse); + kmMat4Identity(&_additionalTransform); } Node::~Node() @@ -543,7 +544,7 @@ void Node::setShaderProgram(GLProgram *pShaderProgram) Rect Node::getBoundingBox() const { Rect rect = Rect(0, 0, _contentSize.width, _contentSize.height); - return RectApplyAffineTransform(rect, getNodeToParentTransform()); + return RectApplyAffineTransform(rect, getNodeToParentAffineTransform()); } Node * Node::create(void) @@ -906,14 +907,12 @@ void Node::transform() updatePhysicsTransform(); #endif - kmMat4 transfrom4x4; - - // Convert 3x3 into 4x4 matrix - CGAffineToGL(this->getNodeToParentTransform(), transfrom4x4.mat); + kmMat4 transfrom4x4 = this->getNodeToParentTransform(); // Update Z vertex manually transfrom4x4.mat[14] = _vertexZ; + kmGLMultMatrix( &transfrom4x4 ); // saves the MV matrix @@ -1184,16 +1183,25 @@ void Node::update(float fDelta) } } -const AffineTransform& Node::getNodeToParentTransform() const +AffineTransform Node::getNodeToParentAffineTransform() const { - if (_transformDirty) + AffineTransform ret; + kmMat4 ret4 = getNodeToParentTransform(); + GLToCGAffine(ret4.mat, &ret); + + return ret; +} + +const kmMat4& Node::getNodeToParentTransform() const +{ + if (_transformDirty) { // Translate values float x = _position.x; float y = _position.y; - if (_ignoreAnchorPointForPosition) + if (_ignoreAnchorPointForPosition) { x += _anchorPointInPoints.x; y += _anchorPointInPoints.y; @@ -1228,80 +1236,132 @@ const AffineTransform& Node::getNodeToParentTransform() const // Build Transform Matrix // Adjusted transform calculation for rotational skew - _transform = AffineTransformMake( cy * _scaleX, sy * _scaleX, - -sx * _scaleY, cx * _scaleY, - x, y ); + _transform = { cy * _scaleX, sy * _scaleX, 0, 0, + -sx * _scaleY, cx * _scaleY, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1 }; // XXX: Try to inline skew // If skew is needed, apply skew and then anchor point - if (needsSkewMatrix) + if (needsSkewMatrix) { - AffineTransform skewMatrix = AffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(_skewY)), - tanf(CC_DEGREES_TO_RADIANS(_skewX)), 1.0f, - 0.0f, 0.0f ); - _transform = AffineTransformConcat(skewMatrix, _transform); + kmMat4 skewMtrix = { 1, tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0, + tanf(CC_DEGREES_TO_RADIANS(_skewX)),1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + + kmMat4Multiply(&_transform, &skewMtrix, &_transform); // adjust anchor point if (!_anchorPointInPoints.equals(Point::ZERO)) { - _transform = AffineTransformTranslate(_transform, -_anchorPointInPoints.x, -_anchorPointInPoints.y); + // XXX: Argh, kmMat needs a "translate" method + _transform.mat[12] += -_anchorPointInPoints.x; + _transform.mat[13] += -_anchorPointInPoints.y; } } - + if (_additionalTransformDirty) { - _transform = AffineTransformConcat(_transform, _additionalTransform); + kmMat4Multiply(&_transform, &_transform, &_additionalTransform); _additionalTransformDirty = false; } - + _transformDirty = false; } - + return _transform; } void Node::setAdditionalTransform(const AffineTransform& additionalTransform) +{ + CGAffineToGL(additionalTransform, _additionalTransform.mat); + _transformDirty = true; + _additionalTransformDirty = true; +} + +void Node::setAdditionalTransform(const kmMat4& additionalTransform) { _additionalTransform = additionalTransform; _transformDirty = true; _additionalTransformDirty = true; } -const AffineTransform& Node::getParentToNodeTransform() const + +AffineTransform Node::getParentToNodeAffineTransform() const +{ + AffineTransform ret; + kmMat4 ret4 = getParentToNodeTransform(); + + GLToCGAffine(ret4.mat,&ret); + return ret; +} + +const kmMat4& Node::getParentToNodeTransform() const { if ( _inverseDirty ) { - _inverse = AffineTransformInvert(this->getNodeToParentTransform()); + kmMat4Inverse(&_inverse, &_transform); _inverseDirty = false; } return _inverse; } -AffineTransform Node::getNodeToWorldTransform() const + +AffineTransform Node::getNodeToWorldAffineTransform() const { - AffineTransform t = this->getNodeToParentTransform(); + AffineTransform t = this->getNodeToParentAffineTransform(); for (Node *p = _parent; p != NULL; p = p->getParent()) - t = AffineTransformConcat(t, p->getNodeToParentTransform()); + t = AffineTransformConcat(t, p->getNodeToParentAffineTransform()); return t; } -AffineTransform Node::getWorldToNodeTransform() const +kmMat4 Node::getNodeToWorldTransform() const { - return AffineTransformInvert(this->getNodeToWorldTransform()); + kmMat4 t = this->getNodeToParentTransform(); + + for (Node *p = _parent; p != NULL; p = p->getParent()) + kmMat4Multiply(&t, &t, &p->getNodeToParentTransform()); + + return t; } +AffineTransform Node::getWorldToNodeAffineTransform() const +{ + return AffineTransformInvert(this->getNodeToWorldAffineTransform()); +} + +kmMat4 Node::getWorldToNodeTransform() const +{ + kmMat4 tmp, tmp2; + + tmp2 = this->getNodeToWorldTransform(); + kmMat4Inverse(&tmp, &tmp2); + return tmp; +} + + Point Node::convertToNodeSpace(const Point& worldPoint) const { - Point ret = PointApplyAffineTransform(worldPoint, getWorldToNodeTransform()); - return ret; + kmMat4 tmp = getWorldToNodeTransform(); + kmVec3 vec3 = {worldPoint.x, worldPoint.y, 0}; + kmVec3 ret; + kmVec3Transform(&ret, &vec3, &tmp); + Point p = {ret.x, ret.y }; + return p; } Point Node::convertToWorldSpace(const Point& nodePoint) const { - Point ret = PointApplyAffineTransform(nodePoint, getNodeToWorldTransform()); - return ret; + kmMat4 tmp = getNodeToWorldTransform(); + kmVec3 vec3 = {nodePoint.x, nodePoint.y, 0}; + kmVec3 ret; + kmVec3Transform(&ret, &vec3, &tmp); + Point p = {ret.x, ret.y }; + return p; + } Point Node::convertToNodeSpaceAR(const Point& worldPoint) const diff --git a/cocos/2d/CCNode.h b/cocos/2d/CCNode.h index bb49b013a4..17b287a3c1 100644 --- a/cocos/2d/CCNode.h +++ b/cocos/2d/CCNode.h @@ -1228,35 +1228,40 @@ public: * Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates. * The matrix is in Pixels. */ - virtual const AffineTransform& getNodeToParentTransform() const; + virtual const kmMat4& getNodeToParentTransform() const; + virtual AffineTransform getNodeToParentAffineTransform() const; /** @deprecated use getNodeToParentTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToParentTransform() const { return getNodeToParentTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToParentTransform() const { return getNodeToParentAffineTransform(); } /** * Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates. * The matrix is in Pixels. */ - virtual const AffineTransform& getParentToNodeTransform() const; + virtual const kmMat4& getParentToNodeTransform() const; + virtual AffineTransform getParentToNodeAffineTransform() const; /** @deprecated Use getParentToNodeTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform parentToNodeTransform() const { return getParentToNodeTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform parentToNodeTransform() const { return getParentToNodeAffineTransform(); } /** * Returns the world affine transform matrix. The matrix is in Pixels. */ - virtual AffineTransform getNodeToWorldTransform() const; + virtual kmMat4 getNodeToWorldTransform() const; + virtual AffineTransform getNodeToWorldAffineTransform() const; /** @deprecated Use getNodeToWorldTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToWorldTransform() const { return getNodeToWorldTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform nodeToWorldTransform() const { return getNodeToWorldAffineTransform(); } /** * Returns the inverse world affine transform matrix. The matrix is in Pixels. */ - virtual AffineTransform getWorldToNodeTransform() const; + virtual kmMat4 getWorldToNodeTransform() const; + virtual AffineTransform getWorldToNodeAffineTransform() const; + /** @deprecated Use worldToNodeTransform() instead */ - CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeTransform(); } + CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeAffineTransform(); } /// @} end of Transformations @@ -1345,6 +1350,7 @@ public: @endcode */ void setAdditionalTransform(const AffineTransform& additionalTransform); + void setAdditionalTransform(const kmMat4& additionalTransform); /// @} end of Coordinate Converters @@ -1428,13 +1434,13 @@ protected: Size _contentSize; ///< untransformed size of the node // "cache" variables are allowed to be mutable - mutable AffineTransform _additionalTransform; ///< transform - mutable AffineTransform _transform; ///< transform - mutable AffineTransform _inverse; ///< inverse transform + mutable kmMat4 _additionalTransform; ///< transform + mutable kmMat4 _transform; ///< transform + mutable kmMat4 _inverse; ///< inverse transform + kmMat4 _modelViewTransform; ///< ModelView transform of the Node. mutable bool _additionalTransformDirty; ///< The flag to check whether the additional transform is dirty mutable bool _transformDirty; ///< transform dirty flag mutable bool _inverseDirty; ///< inverse transform dirty flag - kmMat4 _modelViewTransform; ///< ModelView transform of the Node. Camera *_camera; ///< a camera diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index ceaeb8df18..10a2be7fd5 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -524,7 +524,9 @@ void Sprite::updateTransform(void) else { CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); - _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); + kmMat4 nodeToParent = getNodeToParentTransform(); + kmMat4 parentTransform = static_cast(_parent)->_transformToBatch; + kmMat4Multiply(&_transformToBatch, &nodeToParent, &parentTransform); } // @@ -538,13 +540,13 @@ void Sprite::updateTransform(void) float x2 = x1 + size.width; float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; + float x = _transformToBatch.mat[12]; + float y = _transformToBatch.mat[13]; - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; + float cr = _transformToBatch.mat[0]; + float sr = _transformToBatch.mat[1]; + float cr2 = _transformToBatch.mat[5]; + float sr2 = -_transformToBatch.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; @@ -719,13 +721,13 @@ void Sprite::updateQuadVertices() float x2 = x1 + size.width; float y2 = y1 + size.height; - float x = _transformToBatch.tx; - float y = _transformToBatch.ty; + float x = _transformToBatch.mat[12]; + float y = _transformToBatch.mat[13]; - float cr = _transformToBatch.a; - float sr = _transformToBatch.b; - float cr2 = _transformToBatch.d; - float sr2 = -_transformToBatch.c; + float cr = _transformToBatch.mat[0]; + float sr = _transformToBatch.mat[1]; + float cr2 = _transformToBatch.mat[5]; + float sr2 = -_transformToBatch.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; @@ -1208,7 +1210,7 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode) } else { // using batch - _transformToBatch = AffineTransformIdentity; + kmMat4Identity(&_transformToBatch); setTextureAtlas(_batchNode->getTextureAtlas()); // weak ref } } diff --git a/cocos/2d/CCSprite.h b/cocos/2d/CCSprite.h index 8b009dd21a..1b53acc3db 100644 --- a/cocos/2d/CCSprite.h +++ b/cocos/2d/CCSprite.h @@ -37,6 +37,7 @@ THE SOFTWARE. #include "CCGLBufferedNode.h" #endif // EMSCRIPTEN #include "CCPhysicsBody.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -544,7 +545,7 @@ protected: bool _recursiveDirty; /// Whether all of the sprite's children needs to be updated bool _hasChildren; /// Whether the sprite contains children bool _shouldBeHidden; /// should not be drawn because one of the ancestors is not visible - AffineTransform _transformToBatch; + kmMat4 _transformToBatch; // // Data used when the sprite is self-rendered diff --git a/cocos/2d/renderer/CCNewSprite.cpp b/cocos/2d/renderer/CCNewSprite.cpp index 22301e9f7d..685f854052 100644 --- a/cocos/2d/renderer/CCNewSprite.cpp +++ b/cocos/2d/renderer/CCNewSprite.cpp @@ -92,7 +92,7 @@ void NewSprite::updateQuadVertices() // // calculate the Quad based on the Affine Matrix // - Rect newRect = RectApplyAffineTransform(_rect, _transformToBatch); + Rect newRect = RectApplyTransform(_rect, _transformToBatch); _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ ); @@ -125,13 +125,13 @@ bool NewSprite::culling() const { Frustum* frustum = Director::getInstance()->getFrustum(); //TODO optimize this transformation, should use parent's transformation instead - AffineTransform worldTM = getNodeToWorldTransform(); + kmMat4 worldTM = getNodeToWorldTransform(); //generate aabb // // calculate the Quad based on the Affine Matrix // - Rect newRect = RectApplyAffineTransform(_rect, worldTM); + Rect newRect = RectApplyTransform(_rect, worldTM); kmVec3 point = {newRect.getMinX(), newRect.getMinY(), _vertexZ}; diff --git a/cocos/base/CCAffineTransform.cpp b/cocos/base/CCAffineTransform.cpp index 2e39f344cc..7fbbd62eed 100644 --- a/cocos/base/CCAffineTransform.cpp +++ b/cocos/base/CCAffineTransform.cpp @@ -45,6 +45,14 @@ Point __CCPointApplyAffineTransform(const Point& point, const AffineTransform& t return p; } +Point PointApplyTransform(const Point& point, const kmMat4& transform) +{ + kmVec3 vec = {point.x, point.y, 0}; + kmVec3Transform(&vec, &vec, &transform); + return Point(vec.x, vec.y); +} + + Size __CCSizeApplyAffineTransform(const Size& size, const AffineTransform& t) { Size s; @@ -82,6 +90,32 @@ Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineT return Rect(minX, minY, (maxX - minX), (maxY - minY)); } +Rect RectApplyTransform(const Rect& rect, const kmMat4& transform) +{ + float top = rect.getMinY(); + float left = rect.getMinX(); + float right = rect.getMaxX(); + float bottom = rect.getMaxY(); + + kmVec3 topLeft = {left, top}; + kmVec3 topRight = {right, top}; + kmVec3 bottomLeft = {left, bottom}; + kmVec3 bottomRight = {right, bottom}; + + kmVec3Transform(&topLeft, &topLeft, &transform); + kmVec3Transform(&topRight, &topRight, &transform); + kmVec3Transform(&bottomLeft, &bottomLeft, &transform); + kmVec3Transform(&bottomRight, &bottomRight, &transform); + + float minX = min(min(topLeft.x, topRight.x), min(bottomLeft.x, bottomRight.x)); + float maxX = max(max(topLeft.x, topRight.x), max(bottomLeft.x, bottomRight.x)); + float minY = min(min(topLeft.y, topRight.y), min(bottomLeft.y, bottomRight.y)); + float maxY = max(max(topLeft.y, topRight.y), max(bottomLeft.y, bottomRight.y)); + + return Rect(minX, minY, (maxX - minX), (maxY - minY)); +} + + AffineTransform AffineTransformTranslate(const AffineTransform& t, float tx, float ty) { return __CCAffineTransformMake(t.a, t.b, t.c, t.d, t.tx + t.a * tx + t.c * ty, t.ty + t.b * tx + t.d * ty); diff --git a/cocos/base/CCAffineTransform.h b/cocos/base/CCAffineTransform.h index 66c76fc5f0..f1dbb6aece 100644 --- a/cocos/base/CCAffineTransform.h +++ b/cocos/base/CCAffineTransform.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include "CCGeometry.h" #include "CCPlatformMacros.h" +#include "kazmath/kazmath.h" NS_CC_BEGIN @@ -49,6 +50,9 @@ CC_DLL Size __CCSizeApplyAffineTransform(const Size& size, const AffineTransform CC_DLL AffineTransform AffineTransformMakeIdentity(); CC_DLL Rect RectApplyAffineTransform(const Rect& rect, const AffineTransform& anAffineTransform); +CC_DLL Rect RectApplyTransform(const Rect& rect, const kmMat4& transform); +CC_DLL Point PointApplyTransform(const Point& point, const kmMat4& transform); + CC_DLL AffineTransform AffineTransformTranslate(const AffineTransform& t, float tx, float ty); CC_DLL AffineTransform AffineTransformRotate(const AffineTransform& aTransform, float anAngle); CC_DLL AffineTransform AffineTransformScale(const AffineTransform& t, float sx, float sy); diff --git a/extensions/GUI/CCEditBox/CCEditBox.cpp b/extensions/GUI/CCEditBox/CCEditBox.cpp index df598cd2af..db1d47a884 100644 --- a/extensions/GUI/CCEditBox/CCEditBox.cpp +++ b/extensions/GUI/CCEditBox/CCEditBox.cpp @@ -343,7 +343,7 @@ static Rect getRect(Node * pNode) { Size contentSize = pNode->getContentSize(); Rect rect = Rect(0, 0, contentSize.width, contentSize.height); - return RectApplyAffineTransform(rect, pNode->getNodeToWorldTransform()); + return RectApplyTransform(rect, pNode->getNodeToWorldTransform()); } void EditBox::keyboardWillShow(IMEKeyboardNotificationInfo& info) diff --git a/extensions/physics-nodes/CCPhysicsSprite.cpp b/extensions/physics-nodes/CCPhysicsSprite.cpp index 44054544bf..ff86d74120 100644 --- a/extensions/physics-nodes/CCPhysicsSprite.cpp +++ b/extensions/physics-nodes/CCPhysicsSprite.cpp @@ -342,7 +342,7 @@ void PhysicsSprite::setRotation(float fRotation) } // returns the transform matrix according the Chipmunk Body values -const AffineTransform& PhysicsSprite::getNodeToParentTransform() const +const kmMat4& PhysicsSprite::getNodeToParentTransform() const { // Although scale is not used by physics engines, it is calculated just in case // the sprite is animated (scaled up/down) using actions. @@ -360,9 +360,11 @@ const AffineTransform& PhysicsSprite::getNodeToParentTransform() const y += _anchorPointInPoints.y; } - return (_transform = AffineTransformMake(rot.x * _scaleX, rot.y * _scaleX, - -rot.y * _scaleY, rot.x * _scaleY, - x, y)); + _transform = { (kmScalar)rot.x * _scaleX, (kmScalar)rot.y * _scaleX, 0, 0, + (kmScalar)-rot.y * _scaleY, (kmScalar)rot.x * _scaleY, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1}; + return _transform; #elif CC_ENABLE_BOX2D_INTEGRATION diff --git a/extensions/physics-nodes/CCPhysicsSprite.h b/extensions/physics-nodes/CCPhysicsSprite.h index 1252af5919..50eb8a4158 100644 --- a/extensions/physics-nodes/CCPhysicsSprite.h +++ b/extensions/physics-nodes/CCPhysicsSprite.h @@ -111,7 +111,7 @@ public: virtual void setPosition(const Point &position) override; virtual float getRotation() const override; virtual void setRotation(float fRotation) override; - virtual const AffineTransform& getNodeToParentTransform() const override; + virtual const kmMat4& getNodeToParentTransform() const override; protected: const Point& getPosFromPhysics() const;