PM_Avatar

PM_Avatar

Extends the smoothed pawn mixin to create an avatar under direct user control. Movement commands from the user are routed through the pawn to the actor. The pawn speculatively executes these movement commands for a more responsive user experience. (Otherwise the actor wouldn't respond until the command had made the round trip through the reflector and back.)

The pawn still converges on the actor's "true position", so if the pawn's speculative execution turns out to be in error, it will automatically correct itself over the next few frames.

Instead of setting an avatar actor's translation and rotation directly, avatar pawns usually set the actor's velocity and spin instead. This allows the actor to update its own position during its tick, rather than the pawn sending every position change through the reflector.

Note: PM_Avatar must be paired with AM_Avatar in the actor.

Extends

Members

# translation :Array.<number>

The local translation of the pawn relative to its parent. The value is a 3D vector. This is the interpolated value. If you want the actor's true value, use this.actor.translation.

Type:
  • Array.<number>
Inherited From:

# rotation :Array.<number>

The local rotation of the pawn relative to its parent. The value is a quaternion. This is the interpolated value. If you want the actor's true value, use this.actor.translation.

Type:
  • Array.<number>
Inherited From:

# scale :Array.<number>

The local scale of the pawn relative to its parent. The value is a 3D vector. This is the interpolated value. If you want the actor's true value, use this.actor.scale.

Type:
  • Array.<number>
Inherited From:

# tug :number

A value ranging from 0 to 1 that determines how quickly the pawn will converge on the actor's position during interpolation. If it's set to 0, the pawn will never move at all. If the tug is set to 1, the pawn will snap to the actor's current position every frame.

A pawn's tug is a trade-off between smoothness and responsiveness. Higher tug values converge faster, but also more jittery, and vice versa.

Note: If pawns are arranged in a hierachy in the scene graph, the children will use the tug of their parents. (Mixing different tug values leads to jitter.)

Type:
  • number
Inherited From:
Example:
class SmoothedPawn extends mix(Pawn).with(PM_Smoothed) {
      constructor(...args) {
          super(...args);
          this.tug = 0.02. // Converge slowly.
      }
}

# local :Array.<number>

The local 4x4 transformation matrix. This is the pawn's transform relative to its parent, and is derived from its translation, rotation, and scale. This value is read directly from the spatial pawn's actor.

Type:
  • Array.<number>
Inherited From:

# global :Array.<number>

The global 4x4 transformation matrix. This is the pawn's transform relative to world space, taking into account its local transform and the local transforms of all of its parents.

Type:
  • Array.<number>
Inherited From:

# lookGlobal :Array.<number>

By default, this is the same as global. However you can override it if you want to add an additional transform for a camera attached to the pawn. (For example, first-person avatars should override lookGlobal to let the user look up and down without changing the pawn's facing.)

Type:
  • Array.<number>
Inherited From:

# parent :Pawn

The parent of the pawn in the hierarchical tree. This is the pawn associated with the parent of this pawn's actor. This property is updated automatically, when the actor's parent changes.

Type:
Inherited From:
Example:
if (treePawn.parent.actor === treePawn.actor.parent ) {console.log("Always true!")};

Methods

# moveTo(translation)

Sends an event through the reflector telling the actor to move to a new position. The pawn will speculatively perform the same move under the assumption that the actor will successfully complete it.

Note: If you're frequently calling moveTo(), consider using throttledMoveTo() instead to avoid flooding the reflector with events.

Parameters:
Name Type Description
translation Array.<number>
Example
myAvatarPawn.moveTo([10,0,0]);

# throttledMoveTo(translation)

The same as moveTo(), but limits the number of events that are sent to the reflector. The frequency of the throttled events is determined by the moveThrottle

Parameters:
Name Type Description
translation Array.<number>
Example
myAvatarPawn.throttledMoveTo([10,0,0]);

# rotateTo(rotation)

Sends an event through the reflector telling the actor to rotate to a new position. The pawn will speculatively perform the same rotation under the assumption that the actor will successfully complete it.

Note: If you're frequently calling rotateTo() , consider using throttledRotateTo() instead to avoid flooding the reflector with events.

Parameters:
Name Type Description
rotation Array.<number>
Example
myAvatarPawn.rotateTo(q_axisAngle([1,0,0], toRad(45))); // Rotate to 45 degrees around the x axis.

# throttledRotateTo(rotation)

The same as rotateTo(), but limits the number of events that are sent to the reflector. The frequency of the throttled events is determined by the rotateThrottle

Parameters:
Name Type Description
rotation Array.<number>
Example
myAvatarPawn.throttledRotateTo(q_axisAngle([1,0,0], toRad(45))); // Rotate to 45 degrees around the x axis.

# setVelocity(velocity)

Sends an event through the reflector setting the actor's velocity in xyz units per millisecond. Both the actor and the pawn will then move at this velocity every tick/frame. The pawn's movement will be speculative under the assumption that it's matching the actor, but if the actor does something else, the pawn will smoothly blend to the actor's true position.

Note: Try to use setVelocity() whenever possible instead of moveTo(). It's a much more efficient way for the pawn to control the actor.

Parameters:
Name Type Description
velocity Array.<number>

3-vector in units per millisecond

Example
myAvatarPawn.setVelocity([10,0,0]);

# setSpin(spin)

Sends an event through the reflector setting the actor's spin in radians per millisecond. Both the actor and the pawn will then rotate at this spin every tick/frame. The pawn's rotation will be speculative under the assumption that it's matching the actor, but if the actor does something else, the pawn will smoothly blend to the actor's true position.

Note: Try to use setSpin() whenever possible instead of rotateTo(). It's a much more efficient way for the pawn to control the actor.

Parameters:
Name Type Description
spin Array.<number>

quaternion in radians per millisecond

Example
myAvatarPawn.setSpin(q_axisAngle([1,0,0], toRad(2))); // Rotate at 2 radians per millisecond around the x axis.
myAvatarPawn.setSpin(q_identity()); // Stop the rotation

# update(time, delta)

Called every frame by ViewRoot. Overload this to create your pawn's custom update.

Parameters:
Name Type Description
time number

The view time in milliseconds of the current frame.

delta number

The elapsed time in milliseconds since the previous frame.

Inherited From:

# preUpdate(time, delta)

Called every frame by ViewRoot right before update(). Use this only for operations that must occur before everything else.

Parameters:
Name Type Description
time number

The view time in milliseconds of the current frame.

delta number

The elapsed time in milliseconds since the previous frame.

Inherited From:

# postUpdate(time, delta)

Called every frame by ViewRoot right after update(). Use this only for operations that must occur after everything else.

Parameters:
Name Type Description
time number

The view time in milliseconds of the current frame.

delta number

The elapsed time in milliseconds since the previous frame.

Inherited From: