| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Scene/BsTransform.h"
- #include "RTTI/BsTransformRTTI.h"
- namespace bs
- {
- Transform::Transform()
- : mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ONE)
- { }
- Matrix4 Transform::getMatrix() const
- {
- return Matrix4::TRS(mPosition, mRotation, mScale);
- }
- Matrix4 Transform::getInvMatrix() const
- {
- return Matrix4::inverseTRS(mPosition, mRotation, mScale);
- }
- void Transform::makeLocal(const Transform& parent)
- {
- setWorldPosition(mPosition, parent);
- setWorldRotation(mRotation, parent);
- setWorldScale(mScale, parent);
- }
- void Transform::makeWorld(const Transform& parent)
- {
- // Update orientation
- const Quaternion& parentOrientation = parent.getRotation();
- mRotation = parentOrientation * mRotation;
- // Update scale
- const Vector3& parentScale = parent.getScale();
- // Scale own position by parent scale, just combine as equivalent axes, no shearing
- mScale = parentScale * mScale;
- // Change position vector based on parent's orientation & scale
- mPosition = parentOrientation.rotate(parentScale * mPosition);
- // Add altered position vector to parents
- mPosition += parent.getPosition();
- }
- void Transform::setWorldPosition(const Vector3& position, const Transform& parent)
- {
- Vector3 invScale = parent.getScale();
- if (invScale.x != 0) invScale.x = 1.0f / invScale.x;
- if (invScale.y != 0) invScale.y = 1.0f / invScale.y;
- if (invScale.z != 0) invScale.z = 1.0f / invScale.z;
- Quaternion invRotation = parent.getRotation().inverse();
- mPosition = invRotation.rotate(position - parent.getPosition()) * invScale;
- }
- void Transform::setWorldRotation(const Quaternion& rotation, const Transform& parent)
- {
- Quaternion invRotation = parent.getRotation().inverse();
- mRotation = invRotation * rotation;
- }
- void Transform::setWorldScale(const Vector3& scale, const Transform& parent)
- {
- Matrix3 rotScale;
- Matrix4 parentMatrix = parent.getMatrix();
- parentMatrix.extract3x3Matrix(rotScale);
- rotScale.inverse();
- Matrix3 scaleMat = Matrix3(Quaternion::IDENTITY, scale);
- scaleMat = rotScale * scaleMat;
- Quaternion rotation;
- Vector3 localScale;
- scaleMat.decomposition(rotation, localScale);
- mScale = localScale;
- }
- void Transform::lookAt(const Vector3& location, const Vector3& up)
- {
- Vector3 forward = location - getPosition();
-
- Quaternion rotation = getRotation();
- rotation.lookRotation(forward, up);
- setRotation(rotation);
- }
- void Transform::move(const Vector3& vec)
- {
- setPosition(mPosition + vec);
- }
- void Transform::moveRelative(const Vector3& vec)
- {
- // Transform the axes of the relative vector by camera's local axes
- Vector3 trans = mRotation.rotate(vec);
- setPosition(mPosition + trans);
- }
- void Transform::rotate(const Vector3& axis, const Radian& angle)
- {
- Quaternion q;
- q.fromAxisAngle(axis, angle);
- rotate(q);
- }
- void Transform::rotate(const Quaternion& q)
- {
- // Note the order of the mult, i.e. q comes after
- // Normalize the quat to avoid cumulative problems with precision
- Quaternion qnorm = q;
- qnorm.normalize();
- setRotation(qnorm * mRotation);
- }
- void Transform::roll(const Radian& angle)
- {
- // Rotate around local Z axis
- Vector3 zAxis = mRotation.rotate(Vector3::UNIT_Z);
- rotate(zAxis, angle);
- }
- void Transform::yaw(const Radian& angle)
- {
- Vector3 yAxis = mRotation.rotate(Vector3::UNIT_Y);
- rotate(yAxis, angle);
- }
- void Transform::pitch(const Radian& angle)
- {
- // Rotate around local X axis
- Vector3 xAxis = mRotation.rotate(Vector3::UNIT_X);
- rotate(xAxis, angle);
- }
- void Transform::setForward(const Vector3& forwardDir)
- {
- Quaternion currentRotation = getRotation();
- currentRotation.lookRotation(forwardDir);
- setRotation(currentRotation);
- }
- RTTITypeBase* Transform::getRTTIStatic()
- {
- return TransformRTTI::instance();
- }
- RTTITypeBase* Transform::getRTTI() const
- {
- return Transform::getRTTIStatic();
- }
- }
|