void Transform::RotateTowards(const Kiwi::Vector3& target, float maxRotation) { if(m_position == target) return; //calculate the vector between the current position and the target Kiwi::Vector3 vectorBetween(target.x - m_position.x, target.y - m_position.y, target.z - m_position.z); vectorBetween = vectorBetween.Normalized(); Kiwi::Vector3 forward = this->GetForward(); Kiwi::Vector3 up = this->GetUp(); float dot = forward.Dot(vectorBetween); if( dot < -0.999999f ) { //currently pointing in exactly opposite directions so rotate 180 degrees about the up axis this->Rotate(up, 3.141592f); return; }else if( dot > 0.9999f ) { //already facing each other, do nothing return; } Kiwi::Vector3 rotationAxis = forward.Cross(vectorBetween); float angle = std::acos( forward.Dot(vectorBetween) ); //angle = ToDegrees(angle); if(maxRotation != 0.0f && angle > maxRotation) { angle = maxRotation; } this->Rotate(rotationAxis, angle); //now the quaternion is facing the target, but it may be rotated around the z-axis //need to rotate around the z-axis to the desired up direction Kiwi::Vector3 eulerAngles = m_rotation.GetEulerAngles(); if(eulerAngles.z != 0.0f) { this->Rotate(this->GetForward(),-eulerAngles.z); } }
double const squaredDistanceBetween(Point3D const & a0, Point3D const & a1){ return squaredOf(vectorBetween(a0, a1)); }
double const distanceBetween(Point3D const & a0, Point3D const & a1){ return absoluteOf(vectorBetween(a0, a1)); }