#include "rparticle/Utilities/Transform.h" NS_RRP_BEGIN #if REDREAM_EDITOR static cocos2d::Node* ContentLayerNode = nullptr; void Transform::SetContentLayerNode(cocos2d::Node* node) { ContentLayerNode = node; } Matrix4x4f Transform::GetContentToWorldMatrix() { return ContentLayerNode ? GetLocalToWorldMatrix(ContentLayerNode) : Matrix4x4f::IDENTITY; } #endif Matrix4x4f Transform::GetLocalToWorldMatrix (const cocos2d::Node* node) { Matrix4x4f m; GetLocalToWorldMatrix(node, m); return m; } const Matrix4x4f& Transform::GetLocalToWorldMatrix (const cocos2d::Node* node, Matrix4x4f& m) { Quaternionf rot; Vector3f pos; // GetPositionAndRotation(node, pos, rot); // m.SetTR (pos, rot); #if REDREAM_EDITOR m = node->getNodeToParentTransform(ContentLayerNode); return m; #else m = node->getNodeToWorldTransform(); return m; #endif } Matrix4x4f Transform::GetLocalToWorldMatrixNoScale (const cocos2d::Node* node) { Matrix4x4f m; GetLocalToWorldMatrixNoScale(node, m); return m; } const Matrix4x4f& Transform::GetLocalToWorldMatrixNoScale (const cocos2d::Node* node, Matrix4x4f& m) { Quaternionf rot; Vector3f pos; // GetPositionAndRotation(node, pos, rot); // m.SetTR (pos, rot); #if REDREAM_EDITOR m = node->getNodeToParentTransform(ContentLayerNode); m.decompose(nullptr, &rot, &pos); #else m = node->getNodeToWorldTransform(); m.decompose(nullptr, &rot, &pos); #endif m.SetTR(pos, rot); return m; } Matrix3x3f Transform::GetWorldScale (const cocos2d::Node* node) { Matrix3x3f invRotation; QuaternionToMatrix (Inverse (GetRotation (node)), invRotation); Matrix3x3f scaleAndRotation = GetWorldRotationAndScale (node); return invRotation * scaleAndRotation; } Vector3f Transform::GetWorldScaleLossy (const cocos2d::Node* node) { Matrix3x3f rot = GetWorldScale (node); return Vector3f (rot.Get (0, 0), rot.Get (1, 1), rot.Get (2, 2)); } Vector3f Transform::GetPosition (const cocos2d::Node* node) { Vector3f pos; #if REDREAM_EDITOR auto m = node->getNodeToParentTransform(ContentLayerNode); pos = m.GetPosition(); #else auto m = node->getNodeToWorldTransform(); pos = m.GetPosition(); #endif return pos; } Matrix3x3f Transform::GetWorldRotationAndScale (const cocos2d::Node* node) { Matrix3x3f scale; //scale.SetScale (m_LocalScale); scale.SetScale (Vector3f(node->getScaleX(), node->getScaleY(), node->getScaleZ())); Matrix3x3f rotation; //QuaternionToMatrix (m_LocalRotation, rotation); QuaternionToMatrix (node->getRotationQuat(), rotation); //Transform* parent = GetParent (); auto parent = node->getParent(); #if REDREAM_EDITOR if (parent == ContentLayerNode) return rotation * scale; #endif if (parent) { ///@TODO optimize: Special case multiplication Matrix3x3f parentTransform = GetWorldRotationAndScale (parent); return parentTransform * rotation * scale; } return rotation * scale; } Quaternionf Transform::GetRotation (const cocos2d::Node* node) { //Quaternionf worldRot = m_LocalRotation; Quaternionf worldRot = node->getRotationQuat(); //Transform* cur = GetParent (); auto cur = node->getParent(); while (cur) { //worldRot = cur->m_LocalRotation * worldRot; //cur = cur->GetParent (); worldRot = cur->getRotationQuat() * worldRot; cur = cur->getParent(); #if REDREAM_EDITOR if (cur == ContentLayerNode) break; #endif } return worldRot; } NS_RRP_END