Migration to Mat4x4

Armature not migrated yet

Signed-off-by: Ricardo Quesada <ricardoquesada@gmail.com>
This commit is contained in:
Ricardo Quesada 2013-12-09 17:32:51 -08:00
parent aa00137fde
commit 0222c6544e
10 changed files with 180 additions and 71 deletions

View File

@ -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

View File

@ -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

View File

@ -524,7 +524,9 @@ void Sprite::updateTransform(void)
else
{
CCASSERT( dynamic_cast<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
_transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<Sprite*>(_parent)->_transformToBatch );
kmMat4 nodeToParent = getNodeToParentTransform();
kmMat4 parentTransform = static_cast<Sprite*>(_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
}
}

View File

@ -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

View File

@ -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};

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;