initial commit
This commit is contained in:
430
lib/core/BufferAttribute.js
Normal file
430
lib/core/BufferAttribute.js
Normal file
@ -0,0 +1,430 @@
|
||||
import { Vector4 } from '../math/Vector4.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
function BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
if ( Array.isArray( array ) ) {
|
||||
|
||||
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
||||
|
||||
}
|
||||
|
||||
this.name = '';
|
||||
|
||||
this.array = array;
|
||||
this.itemSize = itemSize;
|
||||
this.count = array !== undefined ? array.length / itemSize : 0;
|
||||
this.normalized = normalized === true;
|
||||
|
||||
this.dynamic = false;
|
||||
this.updateRange = { offset: 0, count: - 1 };
|
||||
|
||||
this.version = 0;
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
|
||||
|
||||
set: function ( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
Object.assign( BufferAttribute.prototype, {
|
||||
|
||||
isBufferAttribute: true,
|
||||
|
||||
onUploadCallback: function () {},
|
||||
|
||||
setArray: function ( array ) {
|
||||
|
||||
if ( Array.isArray( array ) ) {
|
||||
|
||||
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
||||
|
||||
}
|
||||
|
||||
this.count = array !== undefined ? array.length / this.itemSize : 0;
|
||||
this.array = array;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setDynamic: function ( value ) {
|
||||
|
||||
this.dynamic = value;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
this.name = source.name;
|
||||
this.array = new source.array.constructor( source.array );
|
||||
this.itemSize = source.itemSize;
|
||||
this.count = source.count;
|
||||
this.normalized = source.normalized;
|
||||
|
||||
this.dynamic = source.dynamic;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyAt: function ( index1, attribute, index2 ) {
|
||||
|
||||
index1 *= this.itemSize;
|
||||
index2 *= attribute.itemSize;
|
||||
|
||||
for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
|
||||
|
||||
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyArray: function ( array ) {
|
||||
|
||||
this.array.set( array );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyColorsArray: function ( colors ) {
|
||||
|
||||
var array = this.array, offset = 0;
|
||||
|
||||
for ( var i = 0, l = colors.length; i < l; i ++ ) {
|
||||
|
||||
var color = colors[ i ];
|
||||
|
||||
if ( color === undefined ) {
|
||||
|
||||
console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
|
||||
color = new Color();
|
||||
|
||||
}
|
||||
|
||||
array[ offset ++ ] = color.r;
|
||||
array[ offset ++ ] = color.g;
|
||||
array[ offset ++ ] = color.b;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyVector2sArray: function ( vectors ) {
|
||||
|
||||
var array = this.array, offset = 0;
|
||||
|
||||
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
||||
|
||||
var vector = vectors[ i ];
|
||||
|
||||
if ( vector === undefined ) {
|
||||
|
||||
console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
|
||||
vector = new Vector2();
|
||||
|
||||
}
|
||||
|
||||
array[ offset ++ ] = vector.x;
|
||||
array[ offset ++ ] = vector.y;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyVector3sArray: function ( vectors ) {
|
||||
|
||||
var array = this.array, offset = 0;
|
||||
|
||||
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
||||
|
||||
var vector = vectors[ i ];
|
||||
|
||||
if ( vector === undefined ) {
|
||||
|
||||
console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
|
||||
vector = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
array[ offset ++ ] = vector.x;
|
||||
array[ offset ++ ] = vector.y;
|
||||
array[ offset ++ ] = vector.z;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyVector4sArray: function ( vectors ) {
|
||||
|
||||
var array = this.array, offset = 0;
|
||||
|
||||
for ( var i = 0, l = vectors.length; i < l; i ++ ) {
|
||||
|
||||
var vector = vectors[ i ];
|
||||
|
||||
if ( vector === undefined ) {
|
||||
|
||||
console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
|
||||
vector = new Vector4();
|
||||
|
||||
}
|
||||
|
||||
array[ offset ++ ] = vector.x;
|
||||
array[ offset ++ ] = vector.y;
|
||||
array[ offset ++ ] = vector.z;
|
||||
array[ offset ++ ] = vector.w;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
set: function ( value, offset ) {
|
||||
|
||||
if ( offset === undefined ) offset = 0;
|
||||
|
||||
this.array.set( value, offset );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getX: function ( index ) {
|
||||
|
||||
return this.array[ index * this.itemSize ];
|
||||
|
||||
},
|
||||
|
||||
setX: function ( index, x ) {
|
||||
|
||||
this.array[ index * this.itemSize ] = x;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getY: function ( index ) {
|
||||
|
||||
return this.array[ index * this.itemSize + 1 ];
|
||||
|
||||
},
|
||||
|
||||
setY: function ( index, y ) {
|
||||
|
||||
this.array[ index * this.itemSize + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getZ: function ( index ) {
|
||||
|
||||
return this.array[ index * this.itemSize + 2 ];
|
||||
|
||||
},
|
||||
|
||||
setZ: function ( index, z ) {
|
||||
|
||||
this.array[ index * this.itemSize + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getW: function ( index ) {
|
||||
|
||||
return this.array[ index * this.itemSize + 3 ];
|
||||
|
||||
},
|
||||
|
||||
setW: function ( index, w ) {
|
||||
|
||||
this.array[ index * this.itemSize + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setXY: function ( index, x, y ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setXYZ: function ( index, x, y, z ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
this.array[ index + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setXYZW: function ( index, x, y, z, w ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
this.array[ index + 2 ] = z;
|
||||
this.array[ index + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
onUpload: function ( callback ) {
|
||||
|
||||
this.onUploadCallback = callback;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new this.constructor( this.array, this.itemSize ).copy( this );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
|
||||
function Int8BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
|
||||
|
||||
|
||||
function Uint8BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
|
||||
|
||||
|
||||
function Uint8ClampedBufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
|
||||
|
||||
|
||||
function Int16BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
|
||||
|
||||
|
||||
function Uint16BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
|
||||
|
||||
|
||||
function Int32BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
|
||||
|
||||
|
||||
function Uint32BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
|
||||
|
||||
|
||||
function Float32BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
|
||||
|
||||
|
||||
function Float64BufferAttribute( array, itemSize, normalized ) {
|
||||
|
||||
BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
|
||||
Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
|
||||
|
||||
//
|
||||
|
||||
export {
|
||||
Float64BufferAttribute,
|
||||
Float32BufferAttribute,
|
||||
Uint32BufferAttribute,
|
||||
Int32BufferAttribute,
|
||||
Uint16BufferAttribute,
|
||||
Int16BufferAttribute,
|
||||
Uint8ClampedBufferAttribute,
|
||||
Uint8BufferAttribute,
|
||||
Int8BufferAttribute,
|
||||
BufferAttribute
|
||||
};
|
1129
lib/core/BufferGeometry.js
Normal file
1129
lib/core/BufferGeometry.js
Normal file
File diff suppressed because it is too large
Load Diff
73
lib/core/Clock.js
Normal file
73
lib/core/Clock.js
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
function Clock( autoStart ) {
|
||||
|
||||
this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
|
||||
|
||||
this.startTime = 0;
|
||||
this.oldTime = 0;
|
||||
this.elapsedTime = 0;
|
||||
|
||||
this.running = false;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Clock.prototype, {
|
||||
|
||||
start: function () {
|
||||
|
||||
this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
|
||||
|
||||
this.oldTime = this.startTime;
|
||||
this.elapsedTime = 0;
|
||||
this.running = true;
|
||||
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
|
||||
this.getElapsedTime();
|
||||
this.running = false;
|
||||
this.autoStart = false;
|
||||
|
||||
},
|
||||
|
||||
getElapsedTime: function () {
|
||||
|
||||
this.getDelta();
|
||||
return this.elapsedTime;
|
||||
|
||||
},
|
||||
|
||||
getDelta: function () {
|
||||
|
||||
var diff = 0;
|
||||
|
||||
if ( this.autoStart && ! this.running ) {
|
||||
|
||||
this.start();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if ( this.running ) {
|
||||
|
||||
var newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
|
||||
|
||||
diff = ( newTime - this.oldTime ) / 1000;
|
||||
this.oldTime = newTime;
|
||||
|
||||
this.elapsedTime += diff;
|
||||
|
||||
}
|
||||
|
||||
return diff;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { Clock };
|
274
lib/core/DirectGeometry.js
Normal file
274
lib/core/DirectGeometry.js
Normal file
@ -0,0 +1,274 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
|
||||
function DirectGeometry() {
|
||||
|
||||
this.vertices = [];
|
||||
this.normals = [];
|
||||
this.colors = [];
|
||||
this.uvs = [];
|
||||
this.uvs2 = [];
|
||||
|
||||
this.groups = [];
|
||||
|
||||
this.morphTargets = {};
|
||||
|
||||
this.skinWeights = [];
|
||||
this.skinIndices = [];
|
||||
|
||||
// this.lineDistances = [];
|
||||
|
||||
this.boundingBox = null;
|
||||
this.boundingSphere = null;
|
||||
|
||||
// update flags
|
||||
|
||||
this.verticesNeedUpdate = false;
|
||||
this.normalsNeedUpdate = false;
|
||||
this.colorsNeedUpdate = false;
|
||||
this.uvsNeedUpdate = false;
|
||||
this.groupsNeedUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( DirectGeometry.prototype, {
|
||||
|
||||
computeGroups: function ( geometry ) {
|
||||
|
||||
var group;
|
||||
var groups = [];
|
||||
var materialIndex = undefined;
|
||||
|
||||
var faces = geometry.faces;
|
||||
|
||||
for ( var i = 0; i < faces.length; i ++ ) {
|
||||
|
||||
var face = faces[ i ];
|
||||
|
||||
// materials
|
||||
|
||||
if ( face.materialIndex !== materialIndex ) {
|
||||
|
||||
materialIndex = face.materialIndex;
|
||||
|
||||
if ( group !== undefined ) {
|
||||
|
||||
group.count = ( i * 3 ) - group.start;
|
||||
groups.push( group );
|
||||
|
||||
}
|
||||
|
||||
group = {
|
||||
start: i * 3,
|
||||
materialIndex: materialIndex
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( group !== undefined ) {
|
||||
|
||||
group.count = ( i * 3 ) - group.start;
|
||||
groups.push( group );
|
||||
|
||||
}
|
||||
|
||||
this.groups = groups;
|
||||
|
||||
},
|
||||
|
||||
fromGeometry: function ( geometry ) {
|
||||
|
||||
var faces = geometry.faces;
|
||||
var vertices = geometry.vertices;
|
||||
var faceVertexUvs = geometry.faceVertexUvs;
|
||||
|
||||
var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
|
||||
var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
|
||||
|
||||
// morphs
|
||||
|
||||
var morphTargets = geometry.morphTargets;
|
||||
var morphTargetsLength = morphTargets.length;
|
||||
|
||||
var morphTargetsPosition;
|
||||
|
||||
if ( morphTargetsLength > 0 ) {
|
||||
|
||||
morphTargetsPosition = [];
|
||||
|
||||
for ( var i = 0; i < morphTargetsLength; i ++ ) {
|
||||
|
||||
morphTargetsPosition[ i ] = {
|
||||
name: morphTargets[ i ].name,
|
||||
data: []
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.morphTargets.position = morphTargetsPosition;
|
||||
|
||||
}
|
||||
|
||||
var morphNormals = geometry.morphNormals;
|
||||
var morphNormalsLength = morphNormals.length;
|
||||
|
||||
var morphTargetsNormal;
|
||||
|
||||
if ( morphNormalsLength > 0 ) {
|
||||
|
||||
morphTargetsNormal = [];
|
||||
|
||||
for ( var i = 0; i < morphNormalsLength; i ++ ) {
|
||||
|
||||
morphTargetsNormal[ i ] = {
|
||||
name: morphNormals[ i ].name,
|
||||
data: []
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.morphTargets.normal = morphTargetsNormal;
|
||||
|
||||
}
|
||||
|
||||
// skins
|
||||
|
||||
var skinIndices = geometry.skinIndices;
|
||||
var skinWeights = geometry.skinWeights;
|
||||
|
||||
var hasSkinIndices = skinIndices.length === vertices.length;
|
||||
var hasSkinWeights = skinWeights.length === vertices.length;
|
||||
|
||||
//
|
||||
|
||||
if ( vertices.length > 0 && faces.length === 0 ) {
|
||||
|
||||
console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < faces.length; i ++ ) {
|
||||
|
||||
var face = faces[ i ];
|
||||
|
||||
this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
|
||||
|
||||
var vertexNormals = face.vertexNormals;
|
||||
|
||||
if ( vertexNormals.length === 3 ) {
|
||||
|
||||
this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
|
||||
|
||||
} else {
|
||||
|
||||
var normal = face.normal;
|
||||
|
||||
this.normals.push( normal, normal, normal );
|
||||
|
||||
}
|
||||
|
||||
var vertexColors = face.vertexColors;
|
||||
|
||||
if ( vertexColors.length === 3 ) {
|
||||
|
||||
this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
|
||||
|
||||
} else {
|
||||
|
||||
var color = face.color;
|
||||
|
||||
this.colors.push( color, color, color );
|
||||
|
||||
}
|
||||
|
||||
if ( hasFaceVertexUv === true ) {
|
||||
|
||||
var vertexUvs = faceVertexUvs[ 0 ][ i ];
|
||||
|
||||
if ( vertexUvs !== undefined ) {
|
||||
|
||||
this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
|
||||
|
||||
this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( hasFaceVertexUv2 === true ) {
|
||||
|
||||
var vertexUvs = faceVertexUvs[ 1 ][ i ];
|
||||
|
||||
if ( vertexUvs !== undefined ) {
|
||||
|
||||
this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
|
||||
|
||||
this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// morphs
|
||||
|
||||
for ( var j = 0; j < morphTargetsLength; j ++ ) {
|
||||
|
||||
var morphTarget = morphTargets[ j ].vertices;
|
||||
|
||||
morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
|
||||
|
||||
}
|
||||
|
||||
for ( var j = 0; j < morphNormalsLength; j ++ ) {
|
||||
|
||||
var morphNormal = morphNormals[ j ].vertexNormals[ i ];
|
||||
|
||||
morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c );
|
||||
|
||||
}
|
||||
|
||||
// skins
|
||||
|
||||
if ( hasSkinIndices ) {
|
||||
|
||||
this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
|
||||
|
||||
}
|
||||
|
||||
if ( hasSkinWeights ) {
|
||||
|
||||
this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.computeGroups( geometry );
|
||||
|
||||
this.verticesNeedUpdate = geometry.verticesNeedUpdate;
|
||||
this.normalsNeedUpdate = geometry.normalsNeedUpdate;
|
||||
this.colorsNeedUpdate = geometry.colorsNeedUpdate;
|
||||
this.uvsNeedUpdate = geometry.uvsNeedUpdate;
|
||||
this.groupsNeedUpdate = geometry.groupsNeedUpdate;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { DirectGeometry };
|
86
lib/core/EventDispatcher.js
Normal file
86
lib/core/EventDispatcher.js
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* https://github.com/mrdoob/eventdispatcher.js/
|
||||
*/
|
||||
|
||||
function EventDispatcher() {}
|
||||
|
||||
Object.assign( EventDispatcher.prototype, {
|
||||
|
||||
addEventListener: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) this._listeners = {};
|
||||
|
||||
var listeners = this._listeners;
|
||||
|
||||
if ( listeners[ type ] === undefined ) {
|
||||
|
||||
listeners[ type ] = [];
|
||||
|
||||
}
|
||||
|
||||
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
|
||||
|
||||
listeners[ type ].push( listener );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
hasEventListener: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return false;
|
||||
|
||||
var listeners = this._listeners;
|
||||
|
||||
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
|
||||
|
||||
},
|
||||
|
||||
removeEventListener: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
var listeners = this._listeners;
|
||||
var listenerArray = listeners[ type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
var index = listenerArray.indexOf( listener );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
listenerArray.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
dispatchEvent: function ( event ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
var listeners = this._listeners;
|
||||
var listenerArray = listeners[ event.type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
event.target = this;
|
||||
|
||||
var array = listenerArray.slice( 0 );
|
||||
|
||||
for ( var i = 0, l = array.length; i < l; i ++ ) {
|
||||
|
||||
array[ i ].call( this, event );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { EventDispatcher };
|
63
lib/core/Face3.js
Normal file
63
lib/core/Face3.js
Normal file
@ -0,0 +1,63 @@
|
||||
import { Color } from '../math/Color.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
function Face3( a, b, c, normal, color, materialIndex ) {
|
||||
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
|
||||
this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
|
||||
this.vertexNormals = Array.isArray( normal ) ? normal : [];
|
||||
|
||||
this.color = ( color && color.isColor ) ? color : new Color();
|
||||
this.vertexColors = Array.isArray( color ) ? color : [];
|
||||
|
||||
this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Face3.prototype, {
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
},
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
this.a = source.a;
|
||||
this.b = source.b;
|
||||
this.c = source.c;
|
||||
|
||||
this.normal.copy( source.normal );
|
||||
this.color.copy( source.color );
|
||||
|
||||
this.materialIndex = source.materialIndex;
|
||||
|
||||
for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
|
||||
|
||||
this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {
|
||||
|
||||
this.vertexColors[ i ] = source.vertexColors[ i ].clone();
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { Face3 };
|
1435
lib/core/Geometry.js
Normal file
1435
lib/core/Geometry.js
Normal file
File diff suppressed because it is too large
Load Diff
45
lib/core/InstancedBufferAttribute.js
Normal file
45
lib/core/InstancedBufferAttribute.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { BufferAttribute } from './BufferAttribute.js';
|
||||
|
||||
/**
|
||||
* @author benaadams / https://twitter.com/ben_a_adams
|
||||
*/
|
||||
|
||||
function InstancedBufferAttribute( array, itemSize, normalized, meshPerAttribute ) {
|
||||
|
||||
if ( typeof ( normalized ) === 'number' ) {
|
||||
|
||||
meshPerAttribute = normalized;
|
||||
|
||||
normalized = false;
|
||||
|
||||
console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' );
|
||||
|
||||
}
|
||||
|
||||
BufferAttribute.call( this, array, itemSize, normalized );
|
||||
|
||||
this.meshPerAttribute = meshPerAttribute || 1;
|
||||
|
||||
}
|
||||
|
||||
InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
|
||||
|
||||
constructor: InstancedBufferAttribute,
|
||||
|
||||
isInstancedBufferAttribute: true,
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
BufferAttribute.prototype.copy.call( this, source );
|
||||
|
||||
this.meshPerAttribute = source.meshPerAttribute;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
|
||||
export { InstancedBufferAttribute };
|
40
lib/core/InstancedBufferGeometry.js
Normal file
40
lib/core/InstancedBufferGeometry.js
Normal file
@ -0,0 +1,40 @@
|
||||
import { BufferGeometry } from './BufferGeometry.js';
|
||||
|
||||
/**
|
||||
* @author benaadams / https://twitter.com/ben_a_adams
|
||||
*/
|
||||
|
||||
function InstancedBufferGeometry() {
|
||||
|
||||
BufferGeometry.call( this );
|
||||
|
||||
this.type = 'InstancedBufferGeometry';
|
||||
this.maxInstancedCount = undefined;
|
||||
|
||||
}
|
||||
|
||||
InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
|
||||
|
||||
constructor: InstancedBufferGeometry,
|
||||
|
||||
isInstancedBufferGeometry: true,
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
BufferGeometry.prototype.copy.call( this, source );
|
||||
|
||||
this.maxInstancedCount = source.maxInstancedCount;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
export { InstancedBufferGeometry };
|
33
lib/core/InstancedInterleavedBuffer.js
Normal file
33
lib/core/InstancedInterleavedBuffer.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { InterleavedBuffer } from './InterleavedBuffer.js';
|
||||
|
||||
/**
|
||||
* @author benaadams / https://twitter.com/ben_a_adams
|
||||
*/
|
||||
|
||||
function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
|
||||
|
||||
InterleavedBuffer.call( this, array, stride );
|
||||
|
||||
this.meshPerAttribute = meshPerAttribute || 1;
|
||||
|
||||
}
|
||||
|
||||
InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
|
||||
|
||||
constructor: InstancedInterleavedBuffer,
|
||||
|
||||
isInstancedInterleavedBuffer: true,
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
InterleavedBuffer.prototype.copy.call( this, source );
|
||||
|
||||
this.meshPerAttribute = source.meshPerAttribute;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
export { InstancedInterleavedBuffer };
|
111
lib/core/InterleavedBuffer.js
Normal file
111
lib/core/InterleavedBuffer.js
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
/**
|
||||
* @author benaadams / https://twitter.com/ben_a_adams
|
||||
*/
|
||||
|
||||
function InterleavedBuffer( array, stride ) {
|
||||
|
||||
this.array = array;
|
||||
this.stride = stride;
|
||||
this.count = array !== undefined ? array.length / stride : 0;
|
||||
|
||||
this.dynamic = false;
|
||||
this.updateRange = { offset: 0, count: - 1 };
|
||||
|
||||
this.version = 0;
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
|
||||
|
||||
set: function ( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
Object.assign( InterleavedBuffer.prototype, {
|
||||
|
||||
isInterleavedBuffer: true,
|
||||
|
||||
onUploadCallback: function () {},
|
||||
|
||||
setArray: function ( array ) {
|
||||
|
||||
if ( Array.isArray( array ) ) {
|
||||
|
||||
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
||||
|
||||
}
|
||||
|
||||
this.count = array !== undefined ? array.length / this.stride : 0;
|
||||
this.array = array;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setDynamic: function ( value ) {
|
||||
|
||||
this.dynamic = value;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copy: function ( source ) {
|
||||
|
||||
this.array = new source.array.constructor( source.array );
|
||||
this.count = source.count;
|
||||
this.stride = source.stride;
|
||||
this.dynamic = source.dynamic;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
copyAt: function ( index1, attribute, index2 ) {
|
||||
|
||||
index1 *= this.stride;
|
||||
index2 *= attribute.stride;
|
||||
|
||||
for ( var i = 0, l = this.stride; i < l; i ++ ) {
|
||||
|
||||
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
set: function ( value, offset ) {
|
||||
|
||||
if ( offset === undefined ) offset = 0;
|
||||
|
||||
this.array.set( value, offset );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
},
|
||||
|
||||
onUpload: function ( callback ) {
|
||||
|
||||
this.onUploadCallback = callback;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { InterleavedBuffer };
|
139
lib/core/InterleavedBufferAttribute.js
Normal file
139
lib/core/InterleavedBufferAttribute.js
Normal file
@ -0,0 +1,139 @@
|
||||
|
||||
/**
|
||||
* @author benaadams / https://twitter.com/ben_a_adams
|
||||
*/
|
||||
|
||||
function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
|
||||
|
||||
this.data = interleavedBuffer;
|
||||
this.itemSize = itemSize;
|
||||
this.offset = offset;
|
||||
|
||||
this.normalized = normalized === true;
|
||||
|
||||
}
|
||||
|
||||
Object.defineProperties( InterleavedBufferAttribute.prototype, {
|
||||
|
||||
count: {
|
||||
|
||||
get: function () {
|
||||
|
||||
return this.data.count;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
array: {
|
||||
|
||||
get: function () {
|
||||
|
||||
return this.data.array;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
Object.assign( InterleavedBufferAttribute.prototype, {
|
||||
|
||||
isInterleavedBufferAttribute: true,
|
||||
|
||||
setX: function ( index, x ) {
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset ] = x;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setY: function ( index, y ) {
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setZ: function ( index, z ) {
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setW: function ( index, w ) {
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getX: function ( index ) {
|
||||
|
||||
return this.data.array[ index * this.data.stride + this.offset ];
|
||||
|
||||
},
|
||||
|
||||
getY: function ( index ) {
|
||||
|
||||
return this.data.array[ index * this.data.stride + this.offset + 1 ];
|
||||
|
||||
},
|
||||
|
||||
getZ: function ( index ) {
|
||||
|
||||
return this.data.array[ index * this.data.stride + this.offset + 2 ];
|
||||
|
||||
},
|
||||
|
||||
getW: function ( index ) {
|
||||
|
||||
return this.data.array[ index * this.data.stride + this.offset + 3 ];
|
||||
|
||||
},
|
||||
|
||||
setXY: function ( index, x, y ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setXYZ: function ( index, x, y, z ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
this.data.array[ index + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setXYZW: function ( index, x, y, z, w ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
this.data.array[ index + 2 ] = z;
|
||||
this.data.array[ index + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { InterleavedBufferAttribute };
|
46
lib/core/Layers.js
Normal file
46
lib/core/Layers.js
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
function Layers() {
|
||||
|
||||
this.mask = 1 | 0;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Layers.prototype, {
|
||||
|
||||
set: function ( channel ) {
|
||||
|
||||
this.mask = 1 << channel | 0;
|
||||
|
||||
},
|
||||
|
||||
enable: function ( channel ) {
|
||||
|
||||
this.mask |= 1 << channel | 0;
|
||||
|
||||
},
|
||||
|
||||
toggle: function ( channel ) {
|
||||
|
||||
this.mask ^= 1 << channel | 0;
|
||||
|
||||
},
|
||||
|
||||
disable: function ( channel ) {
|
||||
|
||||
this.mask &= ~ ( 1 << channel | 0 );
|
||||
|
||||
},
|
||||
|
||||
test: function ( layers ) {
|
||||
|
||||
return ( this.mask & layers.mask ) !== 0;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { Layers };
|
893
lib/core/Object3D.js
Normal file
893
lib/core/Object3D.js
Normal file
@ -0,0 +1,893 @@
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { EventDispatcher } from './EventDispatcher.js';
|
||||
import { Euler } from '../math/Euler.js';
|
||||
import { Layers } from './Layers.js';
|
||||
import { Matrix3 } from '../math/Matrix3.js';
|
||||
import { _Math } from '../math/Math.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author mikael emtinger / http://gomo.se/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author WestLangley / http://github.com/WestLangley
|
||||
* @author elephantatwork / www.elephantatwork.ch
|
||||
*/
|
||||
|
||||
var object3DId = 0;
|
||||
|
||||
function Object3D() {
|
||||
|
||||
Object.defineProperty( this, 'id', { value: object3DId ++ } );
|
||||
|
||||
this.uuid = _Math.generateUUID();
|
||||
|
||||
this.name = '';
|
||||
this.type = 'Object3D';
|
||||
|
||||
this.parent = null;
|
||||
this.children = [];
|
||||
|
||||
this.up = Object3D.DefaultUp.clone();
|
||||
|
||||
var position = new Vector3();
|
||||
var rotation = new Euler();
|
||||
var quaternion = new Quaternion();
|
||||
var scale = new Vector3( 1, 1, 1 );
|
||||
|
||||
function onRotationChange() {
|
||||
|
||||
quaternion.setFromEuler( rotation, false );
|
||||
|
||||
}
|
||||
|
||||
function onQuaternionChange() {
|
||||
|
||||
rotation.setFromQuaternion( quaternion, undefined, false );
|
||||
|
||||
}
|
||||
|
||||
rotation.onChange( onRotationChange );
|
||||
quaternion.onChange( onQuaternionChange );
|
||||
|
||||
Object.defineProperties( this, {
|
||||
position: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: position
|
||||
},
|
||||
rotation: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: rotation
|
||||
},
|
||||
quaternion: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: quaternion
|
||||
},
|
||||
scale: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: scale
|
||||
},
|
||||
modelViewMatrix: {
|
||||
value: new Matrix4()
|
||||
},
|
||||
normalMatrix: {
|
||||
value: new Matrix3()
|
||||
}
|
||||
} );
|
||||
|
||||
this.matrix = new Matrix4();
|
||||
this.matrixWorld = new Matrix4();
|
||||
|
||||
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
|
||||
this.layers = new Layers();
|
||||
this.visible = true;
|
||||
|
||||
this.castShadow = false;
|
||||
this.receiveShadow = false;
|
||||
|
||||
this.frustumCulled = true;
|
||||
this.renderOrder = 0;
|
||||
|
||||
this.userData = {};
|
||||
|
||||
}
|
||||
|
||||
Object3D.DefaultUp = new Vector3( 0, 1, 0 );
|
||||
Object3D.DefaultMatrixAutoUpdate = true;
|
||||
|
||||
Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
|
||||
|
||||
constructor: Object3D,
|
||||
|
||||
isObject3D: true,
|
||||
|
||||
onBeforeRender: function () {},
|
||||
onAfterRender: function () {},
|
||||
|
||||
applyMatrix: function ( matrix ) {
|
||||
|
||||
this.matrix.multiplyMatrices( matrix, this.matrix );
|
||||
|
||||
this.matrix.decompose( this.position, this.quaternion, this.scale );
|
||||
|
||||
},
|
||||
|
||||
applyQuaternion: function ( q ) {
|
||||
|
||||
this.quaternion.premultiply( q );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
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 Quaternion();
|
||||
|
||||
return function rotateOnAxis( axis, angle ) {
|
||||
|
||||
q1.setFromAxisAngle( axis, angle );
|
||||
|
||||
this.quaternion.multiply( q1 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
rotateOnWorldAxis: function () {
|
||||
|
||||
// rotate object on axis in world space
|
||||
// axis is assumed to be normalized
|
||||
// method assumes no rotated parent
|
||||
|
||||
var q1 = new Quaternion();
|
||||
|
||||
return function rotateOnWorldAxis( axis, angle ) {
|
||||
|
||||
q1.setFromAxisAngle( axis, angle );
|
||||
|
||||
this.quaternion.premultiply( q1 );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
rotateX: function () {
|
||||
|
||||
var v1 = new Vector3( 1, 0, 0 );
|
||||
|
||||
return function rotateX( angle ) {
|
||||
|
||||
return this.rotateOnAxis( v1, angle );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
rotateY: function () {
|
||||
|
||||
var v1 = new Vector3( 0, 1, 0 );
|
||||
|
||||
return function rotateY( angle ) {
|
||||
|
||||
return this.rotateOnAxis( v1, angle );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
rotateZ: function () {
|
||||
|
||||
var v1 = new Vector3( 0, 0, 1 );
|
||||
|
||||
return function rotateZ( 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 Vector3();
|
||||
|
||||
return function translateOnAxis( axis, distance ) {
|
||||
|
||||
v1.copy( axis ).applyQuaternion( this.quaternion );
|
||||
|
||||
this.position.add( v1.multiplyScalar( distance ) );
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
translateX: function () {
|
||||
|
||||
var v1 = new Vector3( 1, 0, 0 );
|
||||
|
||||
return function translateX( distance ) {
|
||||
|
||||
return this.translateOnAxis( v1, distance );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
translateY: function () {
|
||||
|
||||
var v1 = new Vector3( 0, 1, 0 );
|
||||
|
||||
return function translateY( distance ) {
|
||||
|
||||
return this.translateOnAxis( v1, distance );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
translateZ: function () {
|
||||
|
||||
var v1 = new Vector3( 0, 0, 1 );
|
||||
|
||||
return function translateZ( distance ) {
|
||||
|
||||
return this.translateOnAxis( v1, distance );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
localToWorld: function ( vector ) {
|
||||
|
||||
return vector.applyMatrix4( this.matrixWorld );
|
||||
|
||||
},
|
||||
|
||||
worldToLocal: function () {
|
||||
|
||||
var m1 = new Matrix4();
|
||||
|
||||
return function worldToLocal( vector ) {
|
||||
|
||||
return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
lookAt: function () {
|
||||
|
||||
// This method does not support objects having non-uniformly-scaled parent(s)
|
||||
|
||||
var q1 = new Quaternion();
|
||||
var m1 = new Matrix4();
|
||||
var target = new Vector3();
|
||||
var position = new Vector3();
|
||||
|
||||
return function lookAt( x, y, z ) {
|
||||
|
||||
if ( x.isVector3 ) {
|
||||
|
||||
target.copy( x );
|
||||
|
||||
} else {
|
||||
|
||||
target.set( x, y, z );
|
||||
|
||||
}
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
position.setFromMatrixPosition( this.matrixWorld );
|
||||
|
||||
if ( this.isCamera ) {
|
||||
|
||||
m1.lookAt( position, target, this.up );
|
||||
|
||||
} else {
|
||||
|
||||
m1.lookAt( target, position, this.up );
|
||||
|
||||
}
|
||||
|
||||
this.quaternion.setFromRotationMatrix( m1 );
|
||||
|
||||
if ( parent ) {
|
||||
|
||||
m1.extractRotation( parent.matrixWorld );
|
||||
q1.setFromRotationMatrix( m1 );
|
||||
this.quaternion.premultiply( q1.inverse() );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
add: function ( object ) {
|
||||
|
||||
if ( arguments.length > 1 ) {
|
||||
|
||||
for ( var i = 0; i < arguments.length; i ++ ) {
|
||||
|
||||
this.add( arguments[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if ( object === this ) {
|
||||
|
||||
console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if ( ( object && object.isObject3D ) ) {
|
||||
|
||||
if ( object.parent !== null ) {
|
||||
|
||||
object.parent.remove( object );
|
||||
|
||||
}
|
||||
|
||||
object.parent = this;
|
||||
object.dispatchEvent( { type: 'added' } );
|
||||
|
||||
this.children.push( object );
|
||||
|
||||
} else {
|
||||
|
||||
console.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 ] );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
var index = this.children.indexOf( object );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
object.parent = null;
|
||||
|
||||
object.dispatchEvent( { type: 'removed' } );
|
||||
|
||||
this.children.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
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 ( target ) {
|
||||
|
||||
if ( target === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
|
||||
target = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
this.updateMatrixWorld( true );
|
||||
|
||||
return target.setFromMatrixPosition( this.matrixWorld );
|
||||
|
||||
},
|
||||
|
||||
getWorldQuaternion: function () {
|
||||
|
||||
var position = new Vector3();
|
||||
var scale = new Vector3();
|
||||
|
||||
return function getWorldQuaternion( target ) {
|
||||
|
||||
if ( target === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
|
||||
target = new Quaternion();
|
||||
|
||||
}
|
||||
|
||||
this.updateMatrixWorld( true );
|
||||
|
||||
this.matrixWorld.decompose( position, target, scale );
|
||||
|
||||
return target;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
getWorldScale: function () {
|
||||
|
||||
var position = new Vector3();
|
||||
var quaternion = new Quaternion();
|
||||
|
||||
return function getWorldScale( target ) {
|
||||
|
||||
if ( target === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
|
||||
target = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
this.updateMatrixWorld( true );
|
||||
|
||||
this.matrixWorld.decompose( position, quaternion, target );
|
||||
|
||||
return target;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
getWorldDirection: function ( target ) {
|
||||
|
||||
if ( target === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
|
||||
target = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
this.updateMatrixWorld( true );
|
||||
|
||||
var e = this.matrixWorld.elements;
|
||||
|
||||
return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
|
||||
|
||||
},
|
||||
|
||||
raycast: function () {},
|
||||
|
||||
traverse: function ( callback ) {
|
||||
|
||||
callback( this );
|
||||
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].traverse( callback );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
traverseVisible: function ( callback ) {
|
||||
|
||||
if ( this.visible === false ) return;
|
||||
|
||||
callback( this );
|
||||
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].traverseVisible( callback );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
traverseAncestors: function ( callback ) {
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
if ( parent !== null ) {
|
||||
|
||||
callback( parent );
|
||||
|
||||
parent.traverseAncestors( callback );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
updateMatrix: function () {
|
||||
|
||||
this.matrix.compose( this.position, this.quaternion, this.scale );
|
||||
|
||||
this.matrixWorldNeedsUpdate = true;
|
||||
|
||||
},
|
||||
|
||||
updateMatrixWorld: function ( force ) {
|
||||
|
||||
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
||||
|
||||
if ( this.matrixWorldNeedsUpdate || force ) {
|
||||
|
||||
if ( this.parent === null ) {
|
||||
|
||||
this.matrixWorld.copy( this.matrix );
|
||||
|
||||
} else {
|
||||
|
||||
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
|
||||
|
||||
}
|
||||
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
|
||||
force = true;
|
||||
|
||||
}
|
||||
|
||||
// update children
|
||||
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].updateMatrixWorld( force );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
updateWorldMatrix: function ( updateParents, updateChildren ) {
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
if ( updateParents === true && parent !== null ) {
|
||||
|
||||
parent.updateWorldMatrix( true, false );
|
||||
|
||||
}
|
||||
|
||||
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
||||
|
||||
if ( this.parent === null ) {
|
||||
|
||||
this.matrixWorld.copy( this.matrix );
|
||||
|
||||
} else {
|
||||
|
||||
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
|
||||
|
||||
}
|
||||
|
||||
// update children
|
||||
|
||||
if ( updateChildren === true ) {
|
||||
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].updateWorldMatrix( false, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
toJSON: function ( meta ) {
|
||||
|
||||
// meta is a string when called from JSON.stringify
|
||||
var isRootObject = ( meta === undefined || typeof meta === 'string' );
|
||||
|
||||
var output = {};
|
||||
|
||||
// meta is a hash used to collect geometries, materials.
|
||||
// not providing it implies that this is the root object
|
||||
// being serialized.
|
||||
if ( isRootObject ) {
|
||||
|
||||
// initialize meta obj
|
||||
meta = {
|
||||
geometries: {},
|
||||
materials: {},
|
||||
textures: {},
|
||||
images: {},
|
||||
shapes: {}
|
||||
};
|
||||
|
||||
output.metadata = {
|
||||
version: 4.5,
|
||||
type: 'Object',
|
||||
generator: 'Object3D.toJSON'
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// standard Object3D serialization
|
||||
|
||||
var object = {};
|
||||
|
||||
object.uuid = this.uuid;
|
||||
object.type = this.type;
|
||||
|
||||
if ( this.name !== '' ) object.name = this.name;
|
||||
if ( this.castShadow === true ) object.castShadow = true;
|
||||
if ( this.receiveShadow === true ) object.receiveShadow = true;
|
||||
if ( this.visible === false ) object.visible = false;
|
||||
if ( this.frustumCulled === false ) object.frustumCulled = false;
|
||||
if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
|
||||
if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
|
||||
|
||||
object.layers = this.layers.mask;
|
||||
object.matrix = this.matrix.toArray();
|
||||
|
||||
if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
|
||||
|
||||
//
|
||||
|
||||
function serialize( library, element ) {
|
||||
|
||||
if ( library[ element.uuid ] === undefined ) {
|
||||
|
||||
library[ element.uuid ] = element.toJSON( meta );
|
||||
|
||||
}
|
||||
|
||||
return element.uuid;
|
||||
|
||||
}
|
||||
|
||||
if ( this.isMesh || this.isLine || this.isPoints ) {
|
||||
|
||||
object.geometry = serialize( meta.geometries, this.geometry );
|
||||
|
||||
var parameters = this.geometry.parameters;
|
||||
|
||||
if ( parameters !== undefined && parameters.shapes !== undefined ) {
|
||||
|
||||
var shapes = parameters.shapes;
|
||||
|
||||
if ( Array.isArray( shapes ) ) {
|
||||
|
||||
for ( var i = 0, l = shapes.length; i < l; i ++ ) {
|
||||
|
||||
var shape = shapes[ i ];
|
||||
|
||||
serialize( meta.shapes, shape );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
serialize( meta.shapes, shapes );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.material !== undefined ) {
|
||||
|
||||
if ( Array.isArray( this.material ) ) {
|
||||
|
||||
var uuids = [];
|
||||
|
||||
for ( var i = 0, l = this.material.length; i < l; i ++ ) {
|
||||
|
||||
uuids.push( serialize( meta.materials, this.material[ i ] ) );
|
||||
|
||||
}
|
||||
|
||||
object.material = uuids;
|
||||
|
||||
} else {
|
||||
|
||||
object.material = serialize( meta.materials, this.material );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( this.children.length > 0 ) {
|
||||
|
||||
object.children = [];
|
||||
|
||||
for ( var i = 0; i < this.children.length; i ++ ) {
|
||||
|
||||
object.children.push( this.children[ i ].toJSON( meta ).object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( isRootObject ) {
|
||||
|
||||
var geometries = extractFromCache( meta.geometries );
|
||||
var materials = extractFromCache( meta.materials );
|
||||
var textures = extractFromCache( meta.textures );
|
||||
var images = extractFromCache( meta.images );
|
||||
var shapes = extractFromCache( meta.shapes );
|
||||
|
||||
if ( geometries.length > 0 ) output.geometries = geometries;
|
||||
if ( materials.length > 0 ) output.materials = materials;
|
||||
if ( textures.length > 0 ) output.textures = textures;
|
||||
if ( images.length > 0 ) output.images = images;
|
||||
if ( shapes.length > 0 ) output.shapes = shapes;
|
||||
|
||||
}
|
||||
|
||||
output.object = object;
|
||||
|
||||
return output;
|
||||
|
||||
// extract data from the cache hash
|
||||
// remove metadata on each item
|
||||
// and return as array
|
||||
function extractFromCache( cache ) {
|
||||
|
||||
var values = [];
|
||||
for ( var key in cache ) {
|
||||
|
||||
var data = cache[ key ];
|
||||
delete data.metadata;
|
||||
values.push( data );
|
||||
|
||||
}
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
clone: function ( recursive ) {
|
||||
|
||||
return new this.constructor().copy( this, recursive );
|
||||
|
||||
},
|
||||
|
||||
copy: function ( source, recursive ) {
|
||||
|
||||
if ( recursive === undefined ) recursive = true;
|
||||
|
||||
this.name = source.name;
|
||||
|
||||
this.up.copy( source.up );
|
||||
|
||||
this.position.copy( source.position );
|
||||
this.quaternion.copy( source.quaternion );
|
||||
this.scale.copy( source.scale );
|
||||
|
||||
this.matrix.copy( source.matrix );
|
||||
this.matrixWorld.copy( source.matrixWorld );
|
||||
|
||||
this.matrixAutoUpdate = source.matrixAutoUpdate;
|
||||
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
|
||||
|
||||
this.layers.mask = source.layers.mask;
|
||||
this.visible = source.visible;
|
||||
|
||||
this.castShadow = source.castShadow;
|
||||
this.receiveShadow = source.receiveShadow;
|
||||
|
||||
this.frustumCulled = source.frustumCulled;
|
||||
this.renderOrder = source.renderOrder;
|
||||
|
||||
this.userData = JSON.parse( JSON.stringify( source.userData ) );
|
||||
|
||||
if ( recursive === true ) {
|
||||
|
||||
for ( var i = 0; i < source.children.length; i ++ ) {
|
||||
|
||||
var child = source.children[ i ];
|
||||
this.add( child.clone() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { Object3D };
|
134
lib/core/Raycaster.js
Normal file
134
lib/core/Raycaster.js
Normal file
@ -0,0 +1,134 @@
|
||||
import { Ray } from '../math/Ray.js';
|
||||
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author bhouston / http://clara.io/
|
||||
* @author stephomi / http://stephaneginier.com/
|
||||
*/
|
||||
|
||||
function Raycaster( origin, direction, near, far ) {
|
||||
|
||||
this.ray = new Ray( origin, direction );
|
||||
// direction is assumed to be normalized (for accurate distance calculations)
|
||||
|
||||
this.near = near || 0;
|
||||
this.far = far || Infinity;
|
||||
|
||||
this.params = {
|
||||
Mesh: {},
|
||||
Line: {},
|
||||
LOD: {},
|
||||
Points: { threshold: 1 },
|
||||
Sprite: {}
|
||||
};
|
||||
|
||||
Object.defineProperties( this.params, {
|
||||
PointCloud: {
|
||||
get: function () {
|
||||
|
||||
console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
|
||||
return this.Points;
|
||||
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
function ascSort( a, b ) {
|
||||
|
||||
return a.distance - b.distance;
|
||||
|
||||
}
|
||||
|
||||
function intersectObject( object, raycaster, intersects, recursive ) {
|
||||
|
||||
if ( object.visible === false ) return;
|
||||
|
||||
object.raycast( raycaster, intersects );
|
||||
|
||||
if ( recursive === true ) {
|
||||
|
||||
var children = object.children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
intersectObject( children[ i ], raycaster, intersects, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Raycaster.prototype, {
|
||||
|
||||
linePrecision: 1,
|
||||
|
||||
set: function ( origin, direction ) {
|
||||
|
||||
// direction is assumed to be normalized (for accurate distance calculations)
|
||||
|
||||
this.ray.set( origin, direction );
|
||||
|
||||
},
|
||||
|
||||
setFromCamera: function ( coords, camera ) {
|
||||
|
||||
if ( ( camera && camera.isPerspectiveCamera ) ) {
|
||||
|
||||
this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
|
||||
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
|
||||
|
||||
} else if ( ( camera && camera.isOrthographicCamera ) ) {
|
||||
|
||||
this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
|
||||
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.Raycaster: Unsupported camera type.' );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
intersectObject: function ( object, recursive, optionalTarget ) {
|
||||
|
||||
var intersects = optionalTarget || [];
|
||||
|
||||
intersectObject( object, this, intersects, recursive );
|
||||
|
||||
intersects.sort( ascSort );
|
||||
|
||||
return intersects;
|
||||
|
||||
},
|
||||
|
||||
intersectObjects: function ( objects, recursive, optionalTarget ) {
|
||||
|
||||
var intersects = optionalTarget || [];
|
||||
|
||||
if ( Array.isArray( objects ) === false ) {
|
||||
|
||||
console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
|
||||
return intersects;
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0, l = objects.length; i < l; i ++ ) {
|
||||
|
||||
intersectObject( objects[ i ], this, intersects, recursive );
|
||||
|
||||
}
|
||||
|
||||
intersects.sort( ascSort );
|
||||
|
||||
return intersects;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { Raycaster };
|
24
lib/core/Uniform.js
Normal file
24
lib/core/Uniform.js
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
function Uniform( value ) {
|
||||
|
||||
if ( typeof value === 'string' ) {
|
||||
|
||||
console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
|
||||
value = arguments[ 1 ];
|
||||
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
Uniform.prototype.clone = function () {
|
||||
|
||||
return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
|
||||
|
||||
};
|
||||
|
||||
export { Uniform };
|
Reference in New Issue
Block a user