MorphAnimMesh class
class MorphAnimMesh extends Mesh { num duration; bool mirroredLoop; num time; num lastKeyframe, currentKeyframe; num direction; bool directionBackwards; num _startKeyframe, _endKeyframe, _length; MorphAnimMesh(Geometry geometry, Material material) : duration = 1000, // milliseconds mirroredLoop = false, time = 0, lastKeyframe = 0, currentKeyframe = 0, direction = 1, directionBackwards = false, super(geometry, material) { setFrameRange( 0, geometry.morphTargets.length - 1 ); } setFrameRange( start, end ) { _startKeyframe = start; _endKeyframe = end; _length = _endKeyframe - _startKeyframe + 1; } setDirectionForward() { direction = 1; directionBackwards = false; } setDirectionBackward() { direction = -1; directionBackwards = true; } parseAnimations() { if ( geometry["animations"] == null ) geometry["animations"] = {}; var firstAnimation, animations = geometry["animations"]; RegExp pattern = new RegExp('''([a-z]+)(\d+)'''); var il = geometry.morphTargets.length; for ( var i = 0; i < il; i ++ ) { var morph = geometry.morphTargets[ i ]; // TODO(aforsell) Is this really correct use of RegExp? var parts = morph.name.allMatches( pattern.toString() ).toList(); if ( parts && parts.length > 1 ) { var label = parts[ 1 ]; var num = parts[ 2 ]; if ( ! animations[ label ] ) animations[ label ] = { "start": double.INFINITY, "end": double.NEGATIVE_INFINITY }; var animation = animations[ label ]; if ( i < animation.start ) animation.start = i; if ( i > animation.end ) animation.end = i; if ( ! firstAnimation ) firstAnimation = label; } } geometry["firstAnimation"] = firstAnimation; } setAnimationLabel( label, start, end ) { if ( geometry["animations"] == null ) geometry["animations"] = {}; geometry["animations"][ label ] = { "start": start, "end": end }; } playAnimation( label, fps ) { var animation = geometry["animations"][ label ]; if ( animation != null) { setFrameRange( animation.start, animation.end ); duration = 1000 * ( ( animation.end - animation.start ) / fps ); time = 0; } else { print( "animation[$label] undefined" ); } } updateAnimation( delta ) { var frameTime = duration / _length; time += direction * delta; if ( mirroredLoop ) { if ( time > duration || time < 0 ) { direction *= -1; if ( time > duration ) { time = duration; directionBackwards = true; } if ( time < 0 ) { time = 0; directionBackwards = false; } } } else { time = time % duration; if ( time < 0 ) time += duration; } var keyframe = _startKeyframe + ThreeMath.clamp( ( time / frameTime ).floor(), 0, _length - 1 ); if ( keyframe != currentKeyframe ) { morphTargetInfluences[ lastKeyframe ] = 0; morphTargetInfluences[ currentKeyframe ] = 1; morphTargetInfluences[ keyframe ] = 0; lastKeyframe = currentKeyframe; currentKeyframe = keyframe; } var mix = ( time % frameTime ) / frameTime; if ( directionBackwards ) { mix = 1 - mix; } morphTargetInfluences[ currentKeyframe ] = mix; morphTargetInfluences[ lastKeyframe ] = 1 - mix; } }
Extends
Object3D > Mesh > MorphAnimMesh
Constructors
new MorphAnimMesh(Geometry geometry, Material material) #
Creates a new Object instance.
Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.
docs inherited from Object
MorphAnimMesh(Geometry geometry, Material material) : duration = 1000, // milliseconds mirroredLoop = false, time = 0, lastKeyframe = 0, currentKeyframe = 0, direction = 1, directionBackwards = false, super(geometry, material) { setFrameRange( 0, geometry.morphTargets.length - 1 ); }
Properties
bool frustumCulled #
inherited from Object3D
bool visible = false, castShadow = false, receiveShadow = false, frustumCulled = false
bool isDynamic #
inherited from Object3D
bool get isDynamic => _dynamic;
set isDynamic(bool flag) => _dynamic = flag;
Matrix4 matrixRotationWorld #
inherited from Object3D
Matrix4 matrix, matrixWorld, matrixRotationWorld
bool matrixWorldNeedsUpdate #
inherited from Object3D
bool matrixAutoUpdate = false, matrixWorldNeedsUpdate = false
bool receiveShadow #
inherited from Object3D
bool visible = false, castShadow = false, receiveShadow = false
Operators
Methods
void add(Object3D object) #
inherited from Object3D
void add( Object3D object ) { if ( object == this ) { print( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' ); return; } if ( object.parent != null ) { object.parent.remove( object ); } object.parent = this; children.add( object ); // add to scene Object3D scene = this; while ( scene.parent != null ) { scene = scene.parent; } if ( scene is Scene ) { scene.addObject( object ); } }
void applyMatrix(Matrix4 matrix) #
inherited from Object3D
void applyMatrix ( Matrix4 matrix ) { this.matrix = matrix * this.matrix; this.scale = getScaleFromMatrix( this.matrix ); Matrix4 mat = extractRotation(new Matrix4.identity(), this.matrix ); this.rotation = calcEulerFromRotationMatrix( mat, this.eulerOrder ); this.position = this.matrix.getTranslation(); }
Object3D getChildByName(String name, bool doRecurse) #
inherited from Object3D
Object3D getChildByName( String name, bool doRecurse ) { int c; int cl = children.length; Object3D child, recurseResult; children.forEach((child){ if ( child.name == name ) { return child; } if ( doRecurse ) { recurseResult = child.getChildByName( name, doRecurse ); if ( recurseResult != null ) { return recurseResult; } } }); return null; }
num getMorphTargetIndexByName(name) #
inherited from Mesh
num getMorphTargetIndexByName( name ) { if ( _morphTargetDictionary[ name ] != null ) { return _morphTargetDictionary[ name ]; } print( "THREE.Mesh.getMorphTargetIndexByName: morph target $name does not exist. Returning 0." ); return 0; }
dynamic localToWorld(Vector3 vector) #
inherited from Object3D
localToWorld(Vector3 vector) => vector.applyProjection(matrixWorld);
void lookAt(Vector3 vector) #
inherited from Object3D
void lookAt( Vector3 vector ) { // TODO: Add hierarchy support. makeLookAt( matrix, vector, position, up ); if ( rotationAutoUpdate ) { if(useQuaternion) quaternion.setFromRotationMatrix(matrix); else rotation = calcEulerFromRotationMatrix( matrix, eulerOrder ); } }
dynamic parseAnimations() #
parseAnimations() { if ( geometry["animations"] == null ) geometry["animations"] = {}; var firstAnimation, animations = geometry["animations"]; RegExp pattern = new RegExp('''([a-z]+)(\d+)'''); var il = geometry.morphTargets.length; for ( var i = 0; i < il; i ++ ) { var morph = geometry.morphTargets[ i ]; // TODO(aforsell) Is this really correct use of RegExp? var parts = morph.name.allMatches( pattern.toString() ).toList(); if ( parts && parts.length > 1 ) { var label = parts[ 1 ]; var num = parts[ 2 ]; if ( ! animations[ label ] ) animations[ label ] = { "start": double.INFINITY, "end": double.NEGATIVE_INFINITY }; var animation = animations[ label ]; if ( i < animation.start ) animation.start = i; if ( i > animation.end ) animation.end = i; if ( ! firstAnimation ) firstAnimation = label; } } geometry["firstAnimation"] = firstAnimation; }
dynamic playAnimation(label, fps) #
playAnimation( label, fps ) { var animation = geometry["animations"][ label ]; if ( animation != null) { setFrameRange( animation.start, animation.end ); duration = 1000 * ( ( animation.end - animation.start ) / fps ); time = 0; } else { print( "animation[$label] undefined" ); } }
void remove(Object3D object) #
inherited from Object3D
void remove( Object3D object ) { int index = children.indexOf( object ); if ( index != - 1 ){ object.parent = null; children.removeAt(index); // remove from scene Object3D scene = this; while ( scene.parent != null ) { scene = scene.parent; } if (scene is Scene ) { scene.removeObject( object ); } } }
dynamic setAnimationLabel(label, start, end) #
setAnimationLabel( label, start, end ) { if ( geometry["animations"] == null ) geometry["animations"] = {}; geometry["animations"][ label ] = { "start": start, "end": end }; }
dynamic setDirectionBackward() #
setDirectionBackward() { direction = -1; directionBackwards = true; }
dynamic setDirectionForward() #
setDirectionForward() { direction = 1; directionBackwards = false; }
dynamic setFrameRange(start, end) #
setFrameRange( start, end ) { _startKeyframe = start; _endKeyframe = end; _length = _endKeyframe - _startKeyframe + 1; }
void translate(num distance, Vector3 axis) #
inherited from Object3D
void translate( num distance, Vector3 axis ) { matrix.rotate3( axis ); axis.normalize(); position.add( axis.scale( distance ) ); }
void translateX(num distance) #
inherited from Object3D
void translateX( num distance ) => translate( distance, _vector.setValues( 1.0, 0.0, 0.0 ) );
void translateY(num distance) #
inherited from Object3D
void translateY( num distance ) => translate( distance, _vector.setValues( 0.0, 1.0, 0.0 ) );
void translateZ(num distance) #
inherited from Object3D
void translateZ( num distance ) => translate( distance, _vector.setValues( 0.0, 0.0, 1.0 ) );
dynamic updateAnimation(delta) #
updateAnimation( delta ) { var frameTime = duration / _length; time += direction * delta; if ( mirroredLoop ) { if ( time > duration || time < 0 ) { direction *= -1; if ( time > duration ) { time = duration; directionBackwards = true; } if ( time < 0 ) { time = 0; directionBackwards = false; } } } else { time = time % duration; if ( time < 0 ) time += duration; } var keyframe = _startKeyframe + ThreeMath.clamp( ( time / frameTime ).floor(), 0, _length - 1 ); if ( keyframe != currentKeyframe ) { morphTargetInfluences[ lastKeyframe ] = 0; morphTargetInfluences[ currentKeyframe ] = 1; morphTargetInfluences[ keyframe ] = 0; lastKeyframe = currentKeyframe; currentKeyframe = keyframe; } var mix = ( time % frameTime ) / frameTime; if ( directionBackwards ) { mix = 1 - mix; } morphTargetInfluences[ currentKeyframe ] = mix; morphTargetInfluences[ lastKeyframe ] = 1 - mix; }
void updateMatrix() #
inherited from Object3D
void updateMatrix() { if ( useQuaternion ) { setRotationFromQuaternion( matrix, quaternion ); } else { setRotationFromEuler( matrix, rotation, eulerOrder ); } matrix.setTranslation( position ); if ( scale.x != 1.0 || scale.y != 1.0 || scale.z != 1.0 ) { matrix.scale( scale ); boundRadiusScale = Math.max( scale.x, Math.max( scale.y, scale.z ) ); } matrixWorldNeedsUpdate = true; }
void updateMatrixWorld({bool force: false}) #
inherited from Object3D
void updateMatrixWorld( {bool force: false} ) { if (matrixAutoUpdate) updateMatrix(); // update matrixWorld if ( matrixWorldNeedsUpdate || force ) { if ( parent != null ) { matrixWorld = parent.matrixWorld * matrix; } else { matrixWorld = matrix.clone(); } matrixWorldNeedsUpdate = false; force = true; } // update children children.forEach((c) => c.updateMatrixWorld( force: force ) ); }