Doodle3D-Slicer/three.js-master/src/core/Object3D.js
2015-06-12 15:58:26 +02:00

782 lines
14 KiB
JavaScript
Executable File

/**
* @author mrdoob / http://mrdoob.com/
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
*/
THREE.Object3D = function () {
Object.defineProperty( this, 'id', { value: THREE.Object3DIdCount ++ } );
this.uuid = THREE.Math.generateUUID();
this.name = '';
this.type = 'Object3D';
this.parent = undefined;
this.children = [];
this.up = THREE.Object3D.DefaultUp.clone();
var position = new THREE.Vector3();
var rotation = new THREE.Euler();
var quaternion = new THREE.Quaternion();
var scale = new THREE.Vector3( 1, 1, 1 );
var onRotationChange = function () {
quaternion.setFromEuler( rotation, false );
};
var onQuaternionChange = function () {
rotation.setFromQuaternion( quaternion, undefined, false );
};
rotation.onChange( onRotationChange );
quaternion.onChange( onQuaternionChange );
Object.defineProperties( this, {
position: {
enumerable: true,
value: position
},
rotation: {
enumerable: true,
value: rotation
},
quaternion: {
enumerable: true,
value: quaternion
},
scale: {
enumerable: true,
value: scale
}
} );
this.rotationAutoUpdate = true;
this.matrix = new THREE.Matrix4();
this.matrixWorld = new THREE.Matrix4();
this.matrixAutoUpdate = true;
this.matrixWorldNeedsUpdate = false;
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this.frustumCulled = true;
this.renderOrder = 0;
this.userData = {};
};
THREE.Object3D.DefaultUp = new THREE.Vector3( 0, 1, 0 );
THREE.Object3D.prototype = {
constructor: THREE.Object3D,
get eulerOrder () {
THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' );
return this.rotation.order;
},
set eulerOrder ( value ) {
THREE.warn( 'THREE.Object3D: .eulerOrder has been moved to .rotation.order.' );
this.rotation.order = value;
},
get useQuaternion () {
THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
},
set useQuaternion ( value ) {
THREE.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
},
applyMatrix: function ( matrix ) {
this.matrix.multiplyMatrices( matrix, this.matrix );
this.matrix.decompose( this.position, this.quaternion, this.scale );
},
setRotationFromAxisAngle: function ( axis, angle ) {
// assumes axis is normalized
this.quaternion.setFromAxisAngle( axis, angle );
},
setRotationFromEuler: function ( euler ) {
this.quaternion.setFromEuler( euler, true );
},
setRotationFromMatrix: function ( m ) {
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
this.quaternion.setFromRotationMatrix( m );
},
setRotationFromQuaternion: function ( q ) {
// assumes q is normalized
this.quaternion.copy( q );
},
rotateOnAxis: function () {
// rotate object on axis in object space
// axis is assumed to be normalized
var q1 = new THREE.Quaternion();
return function ( axis, angle ) {
q1.setFromAxisAngle( axis, angle );
this.quaternion.multiply( q1 );
return this;
}
}(),
rotateX: function () {
var v1 = new THREE.Vector3( 1, 0, 0 );
return function ( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
rotateY: function () {
var v1 = new THREE.Vector3( 0, 1, 0 );
return function ( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
rotateZ: function () {
var v1 = new THREE.Vector3( 0, 0, 1 );
return function ( angle ) {
return this.rotateOnAxis( v1, angle );
};
}(),
translateOnAxis: function () {
// translate object by distance along axis in object space
// axis is assumed to be normalized
var v1 = new THREE.Vector3();
return function ( axis, distance ) {
v1.copy( axis ).applyQuaternion( this.quaternion );
this.position.add( v1.multiplyScalar( distance ) );
return this;
}
}(),
translate: function ( distance, axis ) {
THREE.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
return this.translateOnAxis( axis, distance );
},
translateX: function () {
var v1 = new THREE.Vector3( 1, 0, 0 );
return function ( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
translateY: function () {
var v1 = new THREE.Vector3( 0, 1, 0 );
return function ( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
translateZ: function () {
var v1 = new THREE.Vector3( 0, 0, 1 );
return function ( distance ) {
return this.translateOnAxis( v1, distance );
};
}(),
localToWorld: function ( vector ) {
return vector.applyMatrix4( this.matrixWorld );
},
worldToLocal: function () {
var m1 = new THREE.Matrix4();
return function ( vector ) {
return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
};
}(),
lookAt: function () {
// This routine does not support objects with rotated and/or translated parent(s)
var m1 = new THREE.Matrix4();
return function ( vector ) {
m1.lookAt( vector, this.position, this.up );
this.quaternion.setFromRotationMatrix( m1 );
};
}(),
add: function ( object ) {
if ( arguments.length > 1 ) {
for ( var i = 0; i < arguments.length; i ++ ) {
this.add( arguments[ i ] );
}
return this;
};
if ( object === this ) {
THREE.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
return this;
}
if ( object instanceof THREE.Object3D ) {
if ( object.parent !== undefined ) {
object.parent.remove( object );
}
object.parent = this;
object.dispatchEvent( { type: 'added' } );
this.children.push( object );
} else {
THREE.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
}
return this;
},
remove: function ( object ) {
if ( arguments.length > 1 ) {
for ( var i = 0; i < arguments.length; i ++ ) {
this.remove( arguments[ i ] );
}
};
var index = this.children.indexOf( object );
if ( index !== - 1 ) {
object.parent = undefined;
object.dispatchEvent( { type: 'removed' } );
this.children.splice( index, 1 );
}
},
getChildByName: function ( name ) {
THREE.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
return this.getObjectByName( name );
},
getObjectById: function ( id ) {
return this.getObjectByProperty( 'id', id );
},
getObjectByName: function ( name ) {
return this.getObjectByProperty( 'name', name );
},
getObjectByProperty: function ( name, value ) {
if ( this[ name ] === value ) return this;
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
var child = this.children[ i ];
var object = child.getObjectByProperty( name, value );
if ( object !== undefined ) {
return object;
}
}
return undefined;
},
getWorldPosition: function ( optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
this.updateMatrixWorld( true );
return result.setFromMatrixPosition( this.matrixWorld );
},
getWorldQuaternion: function () {
var position = new THREE.Vector3();
var scale = new THREE.Vector3();
return function ( optionalTarget ) {
var result = optionalTarget || new THREE.Quaternion();
this.updateMatrixWorld( true );
this.matrixWorld.decompose( position, result, scale );
return result;
}
}(),
getWorldRotation: function () {
var quaternion = new THREE.Quaternion();
return function ( optionalTarget ) {
var result = optionalTarget || new THREE.Euler();
this.getWorldQuaternion( quaternion );
return result.setFromQuaternion( quaternion, this.rotation.order, false );
}
}(),
getWorldScale: function () {
var position = new THREE.Vector3();
var quaternion = new THREE.Quaternion();
return function ( optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
this.updateMatrixWorld( true );
this.matrixWorld.decompose( position, quaternion, result );
return result;
}
}(),
getWorldDirection: function () {
var quaternion = new THREE.Quaternion();
return function ( optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
this.getWorldQuaternion( quaternion );
return result.set( 0, 0, 1 ).applyQuaternion( quaternion );
}
}(),
raycast: function () {},
traverse: function ( callback ) {
callback( this );
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
this.children[ i ].traverse( callback );
}
},
traverseVisible: function ( callback ) {
if ( this.visible === false ) return;
callback( this );
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
this.children[ i ].traverseVisible( callback );
}
},
traverseAncestors: function ( callback ) {
if ( this.parent ) {
callback( this.parent );
this.parent.traverseAncestors( callback );
}
},
updateMatrix: function () {
this.matrix.compose( this.position, this.quaternion, this.scale );
this.matrixWorldNeedsUpdate = true;
},
updateMatrixWorld: function ( force ) {
if ( this.matrixAutoUpdate === true ) this.updateMatrix();
if ( this.matrixWorldNeedsUpdate === true || force === true ) {
if ( this.parent === undefined ) {
this.matrixWorld.copy( this.matrix );
} else {
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
}
this.matrixWorldNeedsUpdate = false;
force = true;
}
// update children
for ( var i = 0, l = this.children.length; i < l; i ++ ) {
this.children[ i ].updateMatrixWorld( force );
}
},
toJSON: function () {
var output = {
metadata: {
version: 4.3,
type: 'Object',
generator: 'ObjectExporter'
}
};
//
var geometries = {};
var parseGeometry = function ( geometry ) {
if ( output.geometries === undefined ) {
output.geometries = [];
}
if ( geometries[ geometry.uuid ] === undefined ) {
var json = geometry.toJSON();
delete json.metadata;
geometries[ geometry.uuid ] = json;
output.geometries.push( json );
}
return geometry.uuid;
};
//
var materials = {};
var parseMaterial = function ( material ) {
if ( output.materials === undefined ) {
output.materials = [];
}
if ( materials[ material.uuid ] === undefined ) {
var json = material.toJSON();
delete json.metadata;
materials[ material.uuid ] = json;
output.materials.push( json );
}
return material.uuid;
};
//
var parseObject = function ( object ) {
var data = {};
data.uuid = object.uuid;
data.type = object.type;
if ( object.name !== '' ) data.name = object.name;
if ( JSON.stringify( object.userData ) !== '{}' ) data.userData = object.userData;
if ( object.visible !== true ) data.visible = object.visible;
if ( object instanceof THREE.PerspectiveCamera ) {
data.fov = object.fov;
data.aspect = object.aspect;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.OrthographicCamera ) {
data.left = object.left;
data.right = object.right;
data.top = object.top;
data.bottom = object.bottom;
data.near = object.near;
data.far = object.far;
} else if ( object instanceof THREE.AmbientLight ) {
data.color = object.color.getHex();
} else if ( object instanceof THREE.DirectionalLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
} else if ( object instanceof THREE.PointLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
data.decay = object.decay;
} else if ( object instanceof THREE.SpotLight ) {
data.color = object.color.getHex();
data.intensity = object.intensity;
data.distance = object.distance;
data.angle = object.angle;
data.exponent = object.exponent;
data.decay = object.decay;
} else if ( object instanceof THREE.HemisphereLight ) {
data.color = object.color.getHex();
data.groundColor = object.groundColor.getHex();
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
data.geometry = parseGeometry( object.geometry );
data.material = parseMaterial( object.material );
if ( object instanceof THREE.Line ) data.mode = object.mode;
} else if ( object instanceof THREE.Sprite ) {
data.material = parseMaterial( object.material );
}
data.matrix = object.matrix.toArray();
if ( object.children.length > 0 ) {
data.children = [];
for ( var i = 0; i < object.children.length; i ++ ) {
data.children.push( parseObject( object.children[ i ] ) );
}
}
return data;
}
output.object = parseObject( this );
return output;
},
clone: function ( object, recursive ) {
if ( object === undefined ) object = new THREE.Object3D();
if ( recursive === undefined ) recursive = true;
object.name = this.name;
object.up.copy( this.up );
object.position.copy( this.position );
object.quaternion.copy( this.quaternion );
object.scale.copy( this.scale );
object.rotationAutoUpdate = this.rotationAutoUpdate;
object.matrix.copy( this.matrix );
object.matrixWorld.copy( this.matrixWorld );
object.matrixAutoUpdate = this.matrixAutoUpdate;
object.matrixWorldNeedsUpdate = this.matrixWorldNeedsUpdate;
object.visible = this.visible;
object.castShadow = this.castShadow;
object.receiveShadow = this.receiveShadow;
object.frustumCulled = this.frustumCulled;
object.userData = JSON.parse( JSON.stringify( this.userData ) );
if ( recursive === true ) {
for ( var i = 0; i < this.children.length; i ++ ) {
var child = this.children[ i ];
object.add( child.clone() );
}
}
return object;
}
};
THREE.EventDispatcher.prototype.apply( THREE.Object3D.prototype );
THREE.Object3DIdCount = 0;