This is how it currently works with correction. There is no way to make NPC look directly at camera
or directly at anything. Some correction i needed, but I don’t know how to calculate it.
Current looking code:
void BTBlackboard::HandleSceneDrawableUpdateFinished(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData)
{
Node *head = node_->GetChild("head", true);
Node *spine = node_->GetChild("spine02", true);
Node *root = node_->GetChild("root", true);
AnimatedModel *anim = node_->GetComponent<AnimatedModel>(true);
Skeleton skel = anim->GetSkeleton();
Bone *head_bone = skel.GetBone("head");
Bone *spine_bone = skel.GetBone("spine02");
Quaternion head_r = head_bone->initialRotation_;
Quaternion spine_r = spine_bone->initialRotation_;
if (look_at_enabled && look_at) {
Node *lookat_target = look_at;
PODVector<Node *> children = look_at->GetChildrenWithTag("player");
if (children.Size() > 0) {
lookat_target = children[0];
VariantMap vars = lookat_target->GetVars();
bool first_person = vars["first_person"].GetBool();
if (first_person)
lookat_target = (Node *) vars["camera_node"].GetPtr();
else {
URHO3D_LOGINFO("no camera");
lookat_target = look_at->GetChild("head", true);
}
} else {
lookat_target = look_at->GetChild("head", true);
}
if (!lookat_target)
lookat_target = look_at;
URHO3D_LOGINFO("looking at: " + lookat_target->GetName() + " " + lookat_target->GetWorldPosition().ToString());
URHO3D_LOGINFO("from: " + head->GetWorldPosition().ToString());
Quaternion prep;
Vector3 dir = (lookat_target->GetWorldPosition() - node_->GetWorldPosition() - Vector3(0.0f, 0.7f, 0.0f));
URHO3D_LOGINFO("dir: " + dir.ToString());
prep.FromLookRotation(dir, Vector3(0.0f, 1.0f, 0.0f));
Quaternion rot = root->GetWorldRotation();
spine->SetWorldRotation(rot.Slerp(spine_r.Inverse() * prep, 0.5));
head->SetWorldRotation(head_r.Inverse() * prep);
}
}