(A lot of code follows, just warning everyone...)
What's up guys.
I've spent 16+ hours trying to wrap my head around quaternions and SLERP but haven't gotten very far. Using the following code I can get my AI character to patrol then instantly rotate to face the new patrol point:
Display All
..and here's MathUtilities.GetUnsignedAngle...
Display All
...but now I want my actor to slowly rotate (SLERP). Given everything I've read, the following should accomplish what I want to do...
Display All
...this code rotates my actor CLOSE (maybe a tad more than half way) to the desired rotation but never actually gets there so my Actor just hangs. Can anyone offer any advice / improvements? It'd mean the world, thanks!
Last note: I understand that SLERP won't fully rotate unless the slerpAmount is equal to 1 so though the above code doesn't reflect it, I've definitely tried setting the slerpAmount to 1 in the case that say the forwardDot was greater than some threshold. I just didn't include it here...
What's up guys.
I've spent 16+ hours trying to wrap my head around quaternions and SLERP but haven't gotten very far. Using the following code I can get my AI character to patrol then instantly rotate to face the new patrol point:
Source Code
- TransformComponent transformComponent = _actor.GetComponent<TransformComponent>();
- Vector3 position = transformComponent.Transform.Translation;
- Vector3 currentPatrolPoint = _patrolPoints.ElementAt(_currentPatrolPoint);
- Vector3 difference = (currentPatrolPoint - position);
- if (_hasFinishedRotating == false)
- {
- Vector3 lookAtDirection = Vector3.Normalize(difference);
- Vector3 forward = Vector3.Normalize(transformComponent.Transform.Forward);
- float forwardDot = (float)Math.Round(
- Vector3.Dot(
- forward,
- lookAtDirection),
- DOT_PRECISION);
- if (forwardDot != 1)
- {
- Vector3 rotationAxis = Vector3.Cross(lookAtDirection, forward);
- float rotationAngle = MathUtilities.GetUnsignedAngle(
- forward,
- lookAtDirection);
- Vector3 right = Vector3.Normalize(transformComponent.Transform.Right);
- float rightDot = (float)Math.Round(
- Vector3.Dot(
- right,
- lookAtDirection),
- DOT_PRECISION);
- if (rightDot > 0)
- {
- rotationAngle *= -1;
- }
- Matrix rotation = transformComponent.Transform;
- rotation *= Matrix.CreateFromAxisAngle(
- rotationAxis,
- rotationAngle);
- rotation.Translation = position;
- PhysicsComponent physicsComponent = _actor.GetComponent<PhysicsComponent>();
- physicsComponent.KinematicMove(rotation);
- }
- else
- {
- _hasFinishedRotating = true;
- }
- }
..and here's MathUtilities.GetUnsignedAngle...
Source Code
...but now I want my actor to slowly rotate (SLERP). Given everything I've read, the following should accomplish what I want to do...
Source Code
- TransformComponent transformComponent = _actor.GetComponent<TransformComponent>();
- Vector3 position = transformComponent.Transform.Translation;
- Vector3 currentPatrolPoint = _patrolPoints.ElementAt(_currentPatrolPoint);
- Vector3 difference = (currentPatrolPoint - position);
- if (_isCurrentlyRotating == false)
- {
- Vector3 lookAtDirection = Vector3.Normalize(difference);
- Vector3 forward = Vector3.Normalize(transformComponent.Transform.Forward);
- float forwardDot = (float)Math.Round(
- Vector3.Dot(
- forward,
- lookAtDirection),
- DOT_PRECISION);
- if (forwardDot != 1)
- {
- Vector3 rotationAxis = Vector3.Cross(lookAtDirection, forward);
- float rotationAngle = MathUtilities.GetUnsignedAngle(
- forward,
- lookAtDirection);
- Vector3 right = Vector3.Normalize(transformComponent.Transform.Right);
- float rightDot = (float)Math.Round(
- Vector3.Dot(
- right,
- lookAtDirection),
- DOT_PRECISION);
- if (rightDot > 0)
- {
- rotationAngle *= -1;
- }
- Quaternion qStart = Quaternion.CreateFromRotationMatrix(transformComponent.Transform);
- Quaternion qEnd = Quaternion.CreateFromAxisAngle(rotationAxis, rotationAngle);
- Quaternion qSlerp = Quaternion.Slerp(
- qStart,
- qEnd,
- (float)gameTime.ElapsedGameTime.Milliseconds / 1000f);
- Matrix rotation = Matrix.CreateFromQuaternion(qSlerp);
- rotation.Translation = position;
- PhysicsComponent physicsComponent = _actor.GetComponent<PhysicsComponent>();
- physicsComponent.KinematicMove(rotation);
- }
- else
- {
- _isCurrentlyRotating = true;
- }
- }
...this code rotates my actor CLOSE (maybe a tad more than half way) to the desired rotation but never actually gets there so my Actor just hangs. Can anyone offer any advice / improvements? It'd mean the world, thanks!
Last note: I understand that SLERP won't fully rotate unless the slerpAmount is equal to 1 so though the above code doesn't reflect it, I've definitely tried setting the slerpAmount to 1 in the case that say the forwardDot was greater than some threshold. I just didn't include it here...
-bullgoose
The post was edited 12 times, last by bullgoose311 ().