Closed AlexisTercero55 closed 1 year ago
animations
definitionExpected value for BasicCharacterControllerProxy
costructor:
animations = {
name_1 : {
clip: AnimationAction,
action: AnimationClip,
},
...
name_n : {
clip: AnimationAction,
action: AnimationClip,
}
}
From Enter()
of the IdleState:
Enter(prevState) {
const currentAction = this._parent._proxy._animations['idle'].action;
if (prevState) {
const prevAction = this._parent._proxy._animations[prevState.Name].action;
currentAction.time = 0.0;
currentAction.enabled = true;
currentAction.setEffectiveTimeScale(1.0);
currentAction.setEffectiveWeight(1.0);
currentAction.crossFadeFrom(prevAction, 0.5, true);
currentAction.play();
} else {
currentAction.play();
}
}
AnimationActions schedule the performance of the animations which are stored in AnimationClips.
Note: Most of AnimationAction's methods can be chained.
AnimationAction.time
: The local time of this action (in seconds, starting with 0).AnimationAction.enable
: Setting enabled to false disables this action, so that it has no impact. Default is true..weight : Number The degree of influence of this action (in the interval [0, 1]). Values between 0 (no impact) and 1 (full impact) can be used to blend between several actions. Default is 1.
.timeScale : Number Scaling factor for the time. A value of 0 causes the animation to pause. Negative values cause the animation to play backwards. Default is 1.
.crossFadeFrom ( fadeOutAction : AnimationAction, durationInSeconds : Number, warpBoolean : Boolean ) : this Causes this action to fade in, fading out another action simultaneously, within the passed time interval. This method can be chained.
If warpBoolean is true, additional warping (gradually changes of the time scales) will be applied.
Note: Like with fadeIn/fadeOut, the fading starts/ends with a weight of 1.
.play () : this Tells the mixer to activate the action. This method can be chained.
The AnimationMixer is a player for animations on a particular object in the scene. When multiple objects in the scene are animated independently, one AnimationMixer may be used for each object.
AnimationMixer( rootObject : Object3D )
rootObject - the object whose animations shall be played by this mixer.
Handles and keeps track of loaded and pending data. A default global instance of this class is created and used by loaders if not supplied manually - see DefaultLoadingManager.
In general that should be sufficient, however there are times when it can be useful to have separate loaders - for example if you want to show separate loading bars for objects and textures.
export class BasicCharacterController {
Update(timeInSeconds) {
if (!this._target) {
return;
}
// update the current state | keep walking and traslating.
this._stateMachine.Update(timeInSeconds, this._input);
// Calculate the frame deceleration based on the object's velocity
const velocity = this._velocity;
const frameDecceleration = new THREE.Vector3(
velocity.x * this._decceleration.x,
velocity.y * this._decceleration.y,
velocity.z * this._decceleration.z
);
frameDecceleration.multiplyScalar(timeInSeconds);
frameDecceleration.z = Math.sign(frameDecceleration.z) * Math.min(
Math.abs(frameDecceleration.z), Math.abs(velocity.z));
// Update the object's velocity based on the frame deceleration
velocity.add(frameDecceleration);
// Get the target object and its current orientation
const controlObject = this._target;
const _Q = new THREE.Quaternion();
const _A = new THREE.Vector3();
const _R = controlObject.quaternion.clone();
// Calculate the acceleration based on user input
const acc = this._acceleration.clone()
// If shift is pressed, double the acceleration;
if (this._input._keys.shift) {
acc.multiplyScalar(2.0);
}
// If the object is in the "dance" state, set acceleration to zero
if (this._stateMachine._currentState?.Name == 'dance') {
acc.multiplyScalar(0.0);
}
// Update the object's velocity based on user input
if (this._input._keys.forward) {
velocity.z += acc.z * timeInSeconds;
}
if (this._input._keys.backward) {
velocity.z -= acc.z * timeInSeconds;
}
// Rotate the object left around its vertical axis
if (this._input._keys.left) {
_A.set(0, 1, 0);
_Q.setFromAxisAngle(_A, 4.0 * Math.PI * timeInSeconds * this._acceleration.y);
_R.multiply(_Q);
}
// Rotate the object right around its vertical axis
if (this._input._keys.right) {
_A.set(0, 1, 0);
_Q.setFromAxisAngle(_A, 4.0 * -Math.PI * timeInSeconds * this._acceleration.y);
_R.multiply(_Q);
}
// Update the object's orientation
controlObject.quaternion.copy(_R);
// Calculate the object's new position based on its velocity and orientation
const oldPosition = new THREE.Vector3();
oldPosition.copy(controlObject.position);
const forward = new THREE.Vector3(0, 0, 1);
forward.applyQuaternion(controlObject.quaternion);
forward.normalize();
const sideways = new THREE.Vector3(1, 0, 0);
sideways.applyQuaternion(controlObject.quaternion);
sideways.normalize();
sideways.multiplyScalar(velocity.x * timeInSeconds);
forward.multiplyScalar(velocity.z * timeInSeconds);
// Update the object's position
controlObject.position.add(forward);
controlObject.position.add(sideways);
// Update the object's animation mixer (if one exists)
oldPosition.copy(controlObject.position);
if (this._mixer) {
this._mixer.update(timeInSeconds);
}
}
}
In computer graphics, velocity is a vector that represents the speed and direction of a moving object. In the code snippet provided, the velocity vector is used to update the position of the controlled object over time.
At each update, the velocity vector is updated based on the current acceleration and the frame deceleration, which is a measure of how much the object's velocity is slowing down due to friction or other forces. The new velocity vector is then used to update the position of the controlled object by moving it along its forward and sideways vectors, which are computed based on its current orientation.
Overall, this process of updating the velocity and position of an object is fundamental to many computer graphics applications, including video games, simulations, and visual effects. By controlling the velocity of an object, we can create realistic motion and interactions between objects in a virtual environment.
From BasicCharacterController:_velocity
//----------------------------------------------------------------
// Calculate the frame deceleration based on the object's velocity
// This is a measure of how much the object's velocity is slowing down due to friction or other forces.
const velocity = this._velocity;//:THREE.Vector3
// The deceleration is computed by multiplying the object's velocity with the deceleration vector.
const frameDecceleration = new THREE.Vector3(
velocity.x * this._decceleration.x,// (-0.0005, -0.0001, -5.0)
velocity.y * this._decceleration.y,
velocity.z * this._decceleration.z
);
// Multiply the frame deceleration by the time since the last frame to get a frame-specific deceleration value
// {x,y,z}*dt = {x*dt,y*dt,z*dt}
// Apply a damping effect to the deceleration in the z-axis direction to simulate ground friction
frameDecceleration.multiplyScalar(timeInSeconds);
frameDecceleration.z = Math.sign(frameDecceleration.z) * Math.min(
Math.abs(frameDecceleration.z), Math.abs(velocity.z));
// Update the object's velocity based on the frame deceleration
velocity.add(frameDecceleration);
//----------------------------------------------------------------
The damping effect is over the z-axis because in the context of 3D graphics, the z-axis usually represents the depth or height of an object in space. The code applies a damping effect to the deceleration in the z-axis direction to simulate ground friction, which is a common physical force that can slow down or stop the movement of an object in the vertical direction. This effect helps to make the movement of the object more realistic and natural-looking.
From
// Rotate the object left around its vertical axis
if (this._input._keys.left) {
_A.set(0, 1, 0);//THREE.Vector3
_Q.setFromAxisAngle(_A, 4.0 * Math.PI * timeInSeconds * this._acceleration.y);
_R.multiply(_Q);
}
// Rotate the object right around its vertical axis
if (this._input._keys.right) {
_A.set(0, 1, 0);
_Q.setFromAxisAngle(_A, 4.0 * -Math.PI * timeInSeconds * this._acceleration.y);
_R.multiply(_Q);
}
// Update the object's orientation
controlObject.quaternion.copy(_R);
This code block is responsible for rotating the controlled object left around its vertical axis in response to user input. Here's a breakdown of what the code does:
In summary, this code block is responsible for updating the orientation of the controlled object by rotating it left around its vertical axis when the left key is pressed.
Motivation
From
at https://github.com/AlexisTercero55/THREEjs_III/blob/ee016cc5a5228ad26b4f9f19b072f24d43d7984f/js/threejs_iii/III_MODELS/CController.js#L10