|
@@ -81,173 +81,171 @@ function CubicPoly() {
|
|
|
const tmp = new Vector3();
|
|
|
const px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();
|
|
|
|
|
|
-function CatmullRomCurve3( points, closed, curveType, tension ) {
|
|
|
+class CatmullRomCurve3 extends Curve {
|
|
|
|
|
|
- Curve.call( this );
|
|
|
+ constructor( points, closed, curveType, tension ) {
|
|
|
|
|
|
- this.type = 'CatmullRomCurve3';
|
|
|
+ super();
|
|
|
|
|
|
- this.points = points || [];
|
|
|
- this.closed = closed || false;
|
|
|
- this.curveType = curveType || 'centripetal';
|
|
|
- this.tension = ( tension !== undefined ) ? tension : 0.5;
|
|
|
+ this.type = 'CatmullRomCurve3';
|
|
|
+ Object.defineProperty( this, 'isCatmullRomCurve3', { value: true } );
|
|
|
|
|
|
-}
|
|
|
+ this.points = points || [];
|
|
|
+ this.closed = closed || false;
|
|
|
+ this.curveType = curveType || 'centripetal';
|
|
|
+ this.tension = ( tension !== undefined ) ? tension : 0.5;
|
|
|
|
|
|
-CatmullRomCurve3.prototype = Object.create( Curve.prototype );
|
|
|
-CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
|
|
|
+ }
|
|
|
+ getPoint( t, optionalTarget ) {
|
|
|
|
|
|
-CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
|
|
|
+ const point = optionalTarget || new Vector3();
|
|
|
|
|
|
-CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) {
|
|
|
+ const points = this.points;
|
|
|
+ const l = points.length;
|
|
|
|
|
|
- const point = optionalTarget || new Vector3();
|
|
|
+ const p = ( l - ( this.closed ? 0 : 1 ) ) * t;
|
|
|
+ let intPoint = Math.floor( p );
|
|
|
+ let weight = p - intPoint;
|
|
|
|
|
|
- const points = this.points;
|
|
|
- const l = points.length;
|
|
|
+ if ( this.closed ) {
|
|
|
|
|
|
- const p = ( l - ( this.closed ? 0 : 1 ) ) * t;
|
|
|
- let intPoint = Math.floor( p );
|
|
|
- let weight = p - intPoint;
|
|
|
+ intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
|
|
|
|
|
|
- if ( this.closed ) {
|
|
|
+ } else if ( weight === 0 && intPoint === l - 1 ) {
|
|
|
|
|
|
- intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
|
|
|
+ intPoint = l - 2;
|
|
|
+ weight = 1;
|
|
|
|
|
|
- } else if ( weight === 0 && intPoint === l - 1 ) {
|
|
|
+ }
|
|
|
|
|
|
- intPoint = l - 2;
|
|
|
- weight = 1;
|
|
|
+ let p0, p3; // 4 points (p1 & p2 defined below)
|
|
|
|
|
|
- }
|
|
|
+ if ( this.closed || intPoint > 0 ) {
|
|
|
|
|
|
- let p0, p3; // 4 points (p1 & p2 defined below)
|
|
|
+ p0 = points[ ( intPoint - 1 ) % l ];
|
|
|
|
|
|
- if ( this.closed || intPoint > 0 ) {
|
|
|
+ } else {
|
|
|
|
|
|
- p0 = points[ ( intPoint - 1 ) % l ];
|
|
|
+ // extrapolate first point
|
|
|
+ tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
|
|
|
+ p0 = tmp;
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- // extrapolate first point
|
|
|
- tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
|
|
|
- p0 = tmp;
|
|
|
+ const p1 = points[ intPoint % l ];
|
|
|
+ const p2 = points[ ( intPoint + 1 ) % l ];
|
|
|
|
|
|
- }
|
|
|
+ if ( this.closed || intPoint + 2 < l ) {
|
|
|
|
|
|
- const p1 = points[ intPoint % l ];
|
|
|
- const p2 = points[ ( intPoint + 1 ) % l ];
|
|
|
+ p3 = points[ ( intPoint + 2 ) % l ];
|
|
|
|
|
|
- if ( this.closed || intPoint + 2 < l ) {
|
|
|
+ } else {
|
|
|
|
|
|
- p3 = points[ ( intPoint + 2 ) % l ];
|
|
|
+ // extrapolate last point
|
|
|
+ tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
|
|
|
+ p3 = tmp;
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- // extrapolate last point
|
|
|
- tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
|
|
|
- p3 = tmp;
|
|
|
+ if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
|
|
|
|
|
|
- }
|
|
|
+ // init Centripetal / Chordal Catmull-Rom
|
|
|
+ const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
|
|
|
+ let dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
|
|
|
+ let dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
|
|
|
+ let dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
|
|
|
|
|
|
- if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
|
|
|
+ // safety check for repeated points
|
|
|
+ if ( dt1 < 1e-4 )
|
|
|
+ dt1 = 1.0;
|
|
|
+ if ( dt0 < 1e-4 )
|
|
|
+ dt0 = dt1;
|
|
|
+ if ( dt2 < 1e-4 )
|
|
|
+ dt2 = dt1;
|
|
|
|
|
|
- // init Centripetal / Chordal Catmull-Rom
|
|
|
- const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
|
|
|
- let dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
|
|
|
- let dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
|
|
|
- let dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
|
|
|
+ px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
|
|
|
+ py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
|
|
|
+ pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
|
|
|
|
|
|
- // safety check for repeated points
|
|
|
- if ( dt1 < 1e-4 ) dt1 = 1.0;
|
|
|
- if ( dt0 < 1e-4 ) dt0 = dt1;
|
|
|
- if ( dt2 < 1e-4 ) dt2 = dt1;
|
|
|
+ } else if ( this.curveType === 'catmullrom' ) {
|
|
|
|
|
|
- px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
|
|
|
- py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
|
|
|
- pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
|
|
|
+ px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
|
|
|
+ py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
|
|
|
+ pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
|
|
|
|
|
|
- } else if ( this.curveType === 'catmullrom' ) {
|
|
|
+ }
|
|
|
|
|
|
- px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
|
|
|
- py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
|
|
|
- pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
|
|
|
+ point.set(
|
|
|
+ px.calc( weight ),
|
|
|
+ py.calc( weight ),
|
|
|
+ pz.calc( weight )
|
|
|
+ );
|
|
|
|
|
|
- }
|
|
|
+ return point;
|
|
|
|
|
|
- point.set(
|
|
|
- px.calc( weight ),
|
|
|
- py.calc( weight ),
|
|
|
- pz.calc( weight )
|
|
|
- );
|
|
|
+ }
|
|
|
+ copy( source ) {
|
|
|
|
|
|
- return point;
|
|
|
+ super.copy( source );
|
|
|
|
|
|
-};
|
|
|
+ this.points = [];
|
|
|
|
|
|
-CatmullRomCurve3.prototype.copy = function ( source ) {
|
|
|
+ for ( let i = 0, l = source.points.length; i < l; i ++ ) {
|
|
|
|
|
|
- Curve.prototype.copy.call( this, source );
|
|
|
+ const point = source.points[ i ];
|
|
|
|
|
|
- this.points = [];
|
|
|
+ this.points.push( point.clone() );
|
|
|
|
|
|
- for ( let i = 0, l = source.points.length; i < l; i ++ ) {
|
|
|
+ }
|
|
|
|
|
|
- const point = source.points[ i ];
|
|
|
+ this.closed = source.closed;
|
|
|
+ this.curveType = source.curveType;
|
|
|
+ this.tension = source.tension;
|
|
|
|
|
|
- this.points.push( point.clone() );
|
|
|
+ return this;
|
|
|
|
|
|
}
|
|
|
+ toJSON() {
|
|
|
|
|
|
- this.closed = source.closed;
|
|
|
- this.curveType = source.curveType;
|
|
|
- this.tension = source.tension;
|
|
|
-
|
|
|
- return this;
|
|
|
+ const data = super.toJSON();
|
|
|
|
|
|
-};
|
|
|
+ data.points = [];
|
|
|
|
|
|
-CatmullRomCurve3.prototype.toJSON = function () {
|
|
|
+ for ( let i = 0, l = this.points.length; i < l; i ++ ) {
|
|
|
|
|
|
- const data = Curve.prototype.toJSON.call( this );
|
|
|
+ const point = this.points[ i ];
|
|
|
+ data.points.push( point.toArray() );
|
|
|
|
|
|
- data.points = [];
|
|
|
+ }
|
|
|
|
|
|
- for ( let i = 0, l = this.points.length; i < l; i ++ ) {
|
|
|
+ data.closed = this.closed;
|
|
|
+ data.curveType = this.curveType;
|
|
|
+ data.tension = this.tension;
|
|
|
|
|
|
- const point = this.points[ i ];
|
|
|
- data.points.push( point.toArray() );
|
|
|
+ return data;
|
|
|
|
|
|
}
|
|
|
+ fromJSON( json ) {
|
|
|
|
|
|
- data.closed = this.closed;
|
|
|
- data.curveType = this.curveType;
|
|
|
- data.tension = this.tension;
|
|
|
-
|
|
|
- return data;
|
|
|
+ super.fromJSON( json );
|
|
|
|
|
|
-};
|
|
|
+ this.points = [];
|
|
|
|
|
|
-CatmullRomCurve3.prototype.fromJSON = function ( json ) {
|
|
|
+ for ( let i = 0, l = json.points.length; i < l; i ++ ) {
|
|
|
|
|
|
- Curve.prototype.fromJSON.call( this, json );
|
|
|
+ const point = json.points[ i ];
|
|
|
+ this.points.push( new Vector3().fromArray( point ) );
|
|
|
|
|
|
- this.points = [];
|
|
|
+ }
|
|
|
|
|
|
- for ( let i = 0, l = json.points.length; i < l; i ++ ) {
|
|
|
+ this.closed = json.closed;
|
|
|
+ this.curveType = json.curveType;
|
|
|
+ this.tension = json.tension;
|
|
|
|
|
|
- const point = json.points[ i ];
|
|
|
- this.points.push( new Vector3().fromArray( point ) );
|
|
|
+ return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
- this.closed = json.closed;
|
|
|
- this.curveType = json.curveType;
|
|
|
- this.tension = json.tension;
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
+}
|
|
|
|
|
|
export { CatmullRomCurve3 };
|