Vec3 Vec3::random_deviant(const Degrees& angle, const Vec3 up) const { //Lovingly adapted from ogre Vec3 new_up = (up == Vec3()) ? perpendicular() : up; Quaternion q; kmQuaternionRotationAxisAngle(&q, this, random_gen::random_float(0, 1) * (PI * 2.0)); kmQuaternionMultiplyVec3(&new_up, &q, &new_up); kmQuaternionRotationAxisAngle(&q, &new_up, Radians(angle).value_); Vec3 ret; kmQuaternionMultiplyVec3(&ret, &q, this); return ret; }
void Camera::update_following(double dt) { ActorPtr following_actor = following_actor_.lock(); if(following_actor) { kmQuaternion actor_rotation = following_actor->absolute_rotation(); kmVec3 actor_position = following_actor->absolute_position(); kmVec3 actor_forward; kmQuaternionGetForwardVec3RH(&actor_forward, &actor_rotation); kmQuaternion initial_rotation; kmQuaternionAssign(&initial_rotation, &rotation_); float t = ((following_lag_ == 0) ? 1.0 : dt * (1.0 / following_lag_)); kmQuaternionSlerp(&rotation_, &initial_rotation, &actor_rotation, t); kmVec3 rotated_offset; kmQuaternionMultiplyVec3(&rotated_offset, &rotation_, &following_offset_); //kmMat4RotationQuaternion(&new_rotation_matrix, &rotation_); //kmVec3MultiplyMat4(&rotated_offset, &following_offset_, &new_rotation_matrix); kmVec3Add(&position_, &rotated_offset, &actor_position); update_from_parent(); } else { //The actor was destroyed, so reset following_actor_ = ActorRef(); } }
kmVec3* kmQuaternionGetForwardVec3LH(kmVec3* pOut, const kmQuaternion* pIn) { return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_Z); }
kmVec3* kmQuaternionGetRightVec3(kmVec3* pOut, const kmQuaternion* pIn) { return kmQuaternionMultiplyVec3(pOut, pIn, &KM_VEC3_POS_X); }