The Quaternion concept is new to me, I watched some youtube videos but still have hard time to figure out how the concept applied in the CharacterDemo program.
Some basic questions here:
-
What is meaning of this statement? How the pitch and the Vector3::RIGHT value work?
Quaternion dir = rot * Quaternion(character_->controls_.pitch_, Vector3::RIGHT); -
In this case, why uses use GetWorldPosition instead of just GetPosition(). How the value of Vector3 here impact the position of the camera?
cameraNode_->SetPosition(headNode->GetWorldPosition() + rot * Vector3(0.0f, 0.15f, 0.2f));
cameraNode_->SetRotation(dir);
Really appreciate any advise or a brief explanation in layman terms of key concepts used in this function.
Source code of the function from the CharacterDemo:
void CharacterDemo::HandlePostUpdate(StringHash eventType, VariantMap& eventData)
{
if (!character_)
return;
Node* characterNode = character_->GetNode();
// Get camera lookat dir from character yaw + pitch
const Quaternion& rot = characterNode->GetRotation();
Quaternion dir = rot * Quaternion(character_->controls_.pitch_, Vector3::RIGHT);
// Turn head to camera pitch, but limit to avoid unnatural animation
Node* headNode = characterNode->GetChild("Mutant:Head", true);
float limitPitch = Clamp(character_->controls_.pitch_, -45.0f, 45.0f);
Quaternion headDir = rot * Quaternion(limitPitch, Vector3(1.0f, 0.0f, 0.0f));
// This could be expanded to look at an arbitrary target, now just look at a point in front
Vector3 headWorldTarget = headNode->GetWorldPosition() + headDir * Vector3(0.0f, 0.0f, -1.0f);
headNode->LookAt(headWorldTarget, Vector3(0.0f, 1.0f, 0.0f));
if (firstPerson_)
{
cameraNode_->SetPosition(headNode->GetWorldPosition() + rot * Vector3(0.0f, 0.15f, 0.2f));
cameraNode_->SetRotation(dir);
}
else
{
// Third person camera: position behind the character
Vector3 aimPoint = characterNode->GetPosition() + rot * Vector3(0.0f, 1.7f, 0.0f);
// Collide camera ray with static physics objects (layer bitmask 2) to ensure we see the character properly
Vector3 rayDir = dir * Vector3::BACK;
float rayDistance = touch_ ? touch_->cameraDistance_ : CAMERA_INITIAL_DIST;
PhysicsRaycastResult result;
scene_->GetComponent<PhysicsWorld>()->RaycastSingle(result, Ray(aimPoint, rayDir), rayDistance, 2);
if (result.body_)
rayDistance = Min(rayDistance, result.distance_);
rayDistance = Clamp(rayDistance, CAMERA_MIN_DIST, CAMERA_MAX_DIST);
cameraNode_->SetPosition(aimPoint + rayDir * rayDistance);
cameraNode_->SetRotation(dir);
}
}