void Transforms::setDirection(const Vector3& vec, tTransformSpace relativeTo, const Vector3& localDirectionVector) { // Do nothing if given a zero vector if (vec == Vector3::ZERO) return; // The direction we want the local direction point to Vector3 targetDir = vec.normalisedCopy(); // Retrieve the parent transforms of this component Transforms* pParentTransforms = getTransforms(); // Transform target direction to world space switch (relativeTo) { case TS_LOCAL: targetDir = getWorldOrientation() * targetDir; break; case TS_PARENT: if (m_bInheritOrientation && pParentTransforms) targetDir = pParentTransforms->getWorldOrientation() * targetDir; break; case TS_WORLD: // default orientation break; } // Calculate target orientation relative to world space Quaternion targetOrientation; // Get current local direction relative to world space const Quaternion& currentOrient = getWorldOrientation(); Vector3 currentDir = currentOrient * localDirectionVector; if ((currentDir + targetDir).squaredLength() < 0.00005f) { // Oops, a 180 degree turn (infinite possible rotation axes) // Default to yaw i.e. use current UP targetOrientation = Quaternion(-currentOrient.y, -currentOrient.z, currentOrient.w, currentOrient.x); } else { // Derive shortest arc to new direction Quaternion rotQuat = currentDir.getRotationTo(targetDir); targetOrientation = rotQuat * currentOrient; } // Set target orientation, transformed to parent space if (pParentTransforms && m_bInheritOrientation) setOrientation(pParentTransforms->getWorldOrientation().UnitInverse() * targetOrientation); else setOrientation(targetOrientation); }
void Transforms::translate(const Vector3& d, tTransformSpace relativeTo) { Vector3 adjusted; switch(relativeTo) { case TS_LOCAL: // Position is relative to parent so transform downwards m_position += m_orientation * d; break; case TS_PARENT: m_position += d; break; case TS_WORLD: { // Position is relative to parent so transform upwards Transforms* pParent = getTransforms(); if (pParent) m_position += (pParent->getWorldOrientation().Inverse() * d) / pParent->getWorldScale(); else m_position += d; break; } } needUpdate(); }
void Body::getWorldTransform(btTransform& worldTrans) const { Transforms* pTransforms = getTransforms(); if (pTransforms) { worldTrans = btTransform(toBullet(pTransforms->getWorldOrientation()), toBullet(pTransforms->getWorldPosition())); } }
Handle<Value> Transforms_GetWorldOrientation(Local<String> property, const AccessorInfo &info) { HandleScope handle_scope; Transforms* ptr = GetPtr(info.This()); assert(ptr); return handle_scope.Close(toJavaScript(ptr->getWorldOrientation())); }
void Body::setWorldTransform(const btTransform& worldTrans) { Transforms* pTransforms = getTransforms(); if (pTransforms) { pTransforms->translate(fromBullet(worldTrans.getOrigin()) - pTransforms->getWorldPosition(), Transforms::TS_WORLD); if (m_bRotationEnabled) pTransforms->rotate(pTransforms->getWorldOrientation().rotationTo(fromBullet(worldTrans.getRotation())), Transforms::TS_WORLD); } }
void Transforms::update() { if (!m_bDirty) return; Transforms* pParent = getTransforms(); if (pParent) { // Update orientation const Quaternion& parentOrientation = pParent->getWorldOrientation(); if (m_bInheritOrientation) { // Combine orientation with that of parent m_fullOrientation = parentOrientation * m_orientation; m_fullOrientation.normalise(); } else { // No inheritence m_fullOrientation = m_orientation; } // Update scale const Vector3& parentScale = pParent->getWorldScale(); if (m_bInheritScale) { // Scale own position by parent scale, NB just combine // as equivalent axes, no shearing m_fullScale = parentScale * m_scale; } else { // No inheritence m_fullScale = m_scale; } // Change position vector based on parent's orientation & scale m_fullPosition = parentOrientation * (parentScale * m_position); // Add altered position vector to parents m_fullPosition += pParent->getWorldPosition(); } else { // No parent m_fullPosition = m_position; m_fullOrientation = m_orientation; m_fullScale = m_scale; } m_bDirty = false; }