webvr js meetup initial commit
This commit is contained in:
604
node_modules/three/examples/js/loaders/3MFLoader.js
generated
vendored
Normal file
604
node_modules/three/examples/js/loaders/3MFLoader.js
generated
vendored
Normal file
@@ -0,0 +1,604 @@
|
||||
THREE.ThreeMFLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
this.availableExtensions = [];
|
||||
|
||||
};
|
||||
|
||||
THREE.ThreeMFLoader.prototype = {
|
||||
|
||||
constructor: THREE.ThreeMFLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
function loadDocument( data ) {
|
||||
|
||||
var view = new DataView( data );
|
||||
var zip = null;
|
||||
var file = null;
|
||||
|
||||
var relsName;
|
||||
var modelPartNames = [];
|
||||
var printTicketPartNames = [];
|
||||
var texturesPartNames = [];
|
||||
var otherPartNames = [];
|
||||
|
||||
var rels;
|
||||
var modelParts = {};
|
||||
var printTicketParts = {};
|
||||
var texturesParts = {};
|
||||
var otherParts = {};
|
||||
|
||||
try {
|
||||
|
||||
zip = new JSZip( data );
|
||||
|
||||
} catch ( e ) {
|
||||
|
||||
if ( e instanceof ReferenceError ) {
|
||||
|
||||
console.log( ' jszip missing and file is compressed.' );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( file in zip.files ) {
|
||||
|
||||
if ( file.match( /\.rels$/ ) ) {
|
||||
|
||||
relsName = file;
|
||||
|
||||
} else if ( file.match(/^3D\/.*\.model$/) ) {
|
||||
|
||||
modelPartNames.push( file );
|
||||
|
||||
} else if ( file.match(/^3D\/Metadata\/.*\.xml$/) ) {
|
||||
|
||||
printTicketPartNames.push( file );
|
||||
|
||||
} else if ( file.match(/^3D\/Textures\/.*/) ) {
|
||||
|
||||
texturesPartNames.push( file );
|
||||
|
||||
} else if ( file.match(/^3D\/Other\/.*/) ) {
|
||||
|
||||
otherPartNames.push( file );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var relsView = new DataView( zip.file( relsName ).asArrayBuffer() );
|
||||
var relsFileText = new TextDecoder( 'utf-8' ).decode( relsView );
|
||||
rels = parseRelsXml( relsFileText );
|
||||
|
||||
for ( var i = 0; i < modelPartNames.length; i++ ) {
|
||||
|
||||
var modelPart = modelPartNames[ i ];
|
||||
view = new DataView( zip.file( modelPart ).asArrayBuffer() );
|
||||
|
||||
if ( TextDecoder === undefined ) {
|
||||
|
||||
console.log( ' TextDecoder not present. Please use TextDecoder polyfill.' );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
var fileText = new TextDecoder( 'utf-8' ).decode( view );
|
||||
var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
|
||||
|
||||
if ( xmlData.documentElement.nodeName.toLowerCase() !== 'model' ) {
|
||||
|
||||
console.log( ' Error loading 3MF - no 3MF document found: ' + modelPart );
|
||||
|
||||
}
|
||||
|
||||
var modelNode = xmlData.querySelector( 'model' );
|
||||
var extensions = {};
|
||||
|
||||
for ( var i = 0; i < modelNode.attributes.length; i++ ) {
|
||||
|
||||
var attr = modelNode.attributes[ i ];
|
||||
if ( attr.name.match( /^xmlns:(.+)$/ ) ) {
|
||||
|
||||
extensions[ attr.value ] = RegExp.$1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var modelData = parseModelNode( modelNode );
|
||||
modelData[ 'xml' ] = modelNode;
|
||||
|
||||
if ( 0 < Object.keys( extensions ).length ) {
|
||||
|
||||
modelData[ 'extensions' ] = extensions;
|
||||
|
||||
}
|
||||
|
||||
modelParts[ modelPart ] = modelData;
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < texturesPartNames.length; i++ ) {
|
||||
|
||||
var texturesPartName = texturesPartNames[ i ];
|
||||
texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary();
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
rels: rels,
|
||||
model: modelParts,
|
||||
printTicket: printTicketParts,
|
||||
texture: texturesParts,
|
||||
other: otherParts
|
||||
};
|
||||
}
|
||||
|
||||
function parseRelsXml( relsFileText ) {
|
||||
|
||||
var relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' );
|
||||
var relsNode = relsXmlData.querySelector( 'Relationship' );
|
||||
var target = relsNode.getAttribute( 'Target' );
|
||||
var id = relsNode.getAttribute( 'Id' );
|
||||
var type = relsNode.getAttribute( 'Type' );
|
||||
|
||||
return {
|
||||
target: target,
|
||||
id: id,
|
||||
type: type
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function parseMetadataNodes( metadataNodes ) {
|
||||
|
||||
var metadataData = {};
|
||||
|
||||
for ( var i = 0; i < metadataNodes.length; i++ ) {
|
||||
|
||||
var metadataNode = metadataNodes[ i ];
|
||||
var name = metadataNode.getAttribute('name');
|
||||
var validNames = [
|
||||
'Title',
|
||||
'Designer',
|
||||
'Description',
|
||||
'Copyright',
|
||||
'LicenseTerms',
|
||||
'Rating',
|
||||
'CreationDate',
|
||||
'ModificationDate'
|
||||
];
|
||||
|
||||
if ( 0 <= validNames.indexOf( name ) ) {
|
||||
|
||||
metadataData[ name ] = metadataNode.textContent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return metadataData;
|
||||
|
||||
}
|
||||
|
||||
function parseBasematerialsNode( basematerialsNode ) {
|
||||
}
|
||||
|
||||
function parseMeshNode( meshNode, extensions ) {
|
||||
|
||||
var meshData = {};
|
||||
|
||||
var vertices = [];
|
||||
var vertexNodes = meshNode.querySelectorAll( 'vertices vertex' );
|
||||
|
||||
for ( var i = 0; i < vertexNodes.length; i++ ) {
|
||||
|
||||
var vertexNode = vertexNodes[ i ];
|
||||
var x = vertexNode.getAttribute( 'x' );
|
||||
var y = vertexNode.getAttribute( 'y' );
|
||||
var z = vertexNode.getAttribute( 'z' );
|
||||
|
||||
vertices.push( parseFloat( x ), parseFloat( y ), parseFloat( z ) );
|
||||
|
||||
}
|
||||
|
||||
meshData[ 'vertices' ] = new Float32Array( vertices.length );
|
||||
|
||||
for ( var i = 0; i < vertices.length; i++ ) {
|
||||
|
||||
meshData[ 'vertices' ][ i ] = vertices[ i ];
|
||||
|
||||
}
|
||||
|
||||
var triangleProperties = [];
|
||||
var triangles = [];
|
||||
var triangleNodes = meshNode.querySelectorAll( 'triangles triangle' );
|
||||
|
||||
for ( var i = 0; i < triangleNodes.length; i++ ) {
|
||||
|
||||
var triangleNode = triangleNodes[ i ];
|
||||
var v1 = triangleNode.getAttribute( 'v1' );
|
||||
var v2 = triangleNode.getAttribute( 'v2' );
|
||||
var v3 = triangleNode.getAttribute( 'v3' );
|
||||
var p1 = triangleNode.getAttribute( 'p1' );
|
||||
var p2 = triangleNode.getAttribute( 'p2' );
|
||||
var p3 = triangleNode.getAttribute( 'p3' );
|
||||
var pid = triangleNode.getAttribute( 'pid' );
|
||||
|
||||
triangles.push( parseInt( v1, 10 ), parseInt( v2, 10 ), parseInt( v3, 10 ) );
|
||||
|
||||
var triangleProperty = {};
|
||||
|
||||
if ( p1 ) {
|
||||
|
||||
triangleProperty[ 'p1' ] = parseInt( p1, 10 );
|
||||
|
||||
}
|
||||
|
||||
if ( p2 ) {
|
||||
|
||||
triangleProperty[ 'p2' ] = parseInt( p2, 10 );
|
||||
|
||||
}
|
||||
|
||||
if ( p3 ) {
|
||||
|
||||
triangleProperty[ 'p3' ] = parseInt( p3, 10 );
|
||||
|
||||
}
|
||||
|
||||
if ( pid ) {
|
||||
|
||||
triangleProperty[ 'pid' ] = pid;
|
||||
|
||||
}
|
||||
|
||||
if ( 0 < Object.keys( triangleProperty ).length ) {
|
||||
|
||||
triangleProperties.push( triangleProperty );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
meshData[ 'triangleProperties' ] = triangleProperties;
|
||||
meshData[ 'triangles' ] = new Uint32Array( triangles.length );
|
||||
|
||||
for ( var i = 0; i < triangles.length; i++ ) {
|
||||
|
||||
meshData[ 'triangles' ][ i ] = triangles[ i ];
|
||||
|
||||
}
|
||||
|
||||
return meshData;
|
||||
|
||||
}
|
||||
|
||||
function parseComponentsNode( componentsNode ) {
|
||||
|
||||
}
|
||||
|
||||
function parseObjectNode( objectNode ) {
|
||||
|
||||
var objectData = {
|
||||
type: objectNode.getAttribute( 'type' )
|
||||
};
|
||||
|
||||
var id = objectNode.getAttribute( 'id' );
|
||||
|
||||
if ( id ) {
|
||||
|
||||
objectData[ 'id' ] = id;
|
||||
|
||||
}
|
||||
|
||||
var pid = objectNode.getAttribute( 'pid' );
|
||||
|
||||
if ( pid ) {
|
||||
|
||||
objectData[ 'pid' ] = pid;
|
||||
|
||||
}
|
||||
|
||||
var pindex = objectNode.getAttribute( 'pindex' );
|
||||
|
||||
if ( pindex ) {
|
||||
|
||||
objectData[ 'pindex' ] = pindex;
|
||||
|
||||
}
|
||||
|
||||
var thumbnail = objectNode.getAttribute( 'thumbnail' );
|
||||
|
||||
if ( thumbnail ) {
|
||||
|
||||
objectData[ 'thumbnail' ] = thumbnail;
|
||||
|
||||
}
|
||||
|
||||
var partnumber = objectNode.getAttribute( 'partnumber' );
|
||||
|
||||
if ( partnumber ) {
|
||||
|
||||
objectData[ 'partnumber' ] = partnumber;
|
||||
|
||||
}
|
||||
|
||||
var name = objectNode.getAttribute( 'name' );
|
||||
|
||||
if ( name ) {
|
||||
|
||||
objectData[ 'name' ] = name;
|
||||
|
||||
}
|
||||
|
||||
var meshNode = objectNode.querySelector( 'mesh' );
|
||||
|
||||
if ( meshNode ) {
|
||||
|
||||
objectData[ 'mesh' ] = parseMeshNode( meshNode );
|
||||
|
||||
}
|
||||
|
||||
var componentsNode = objectNode.querySelector( 'components' );
|
||||
|
||||
if ( componentsNode ) {
|
||||
|
||||
objectData[ 'components' ] = parseComponentsNode( componentsNode );
|
||||
|
||||
}
|
||||
|
||||
return objectData;
|
||||
|
||||
}
|
||||
|
||||
function parseResourcesNode( resourcesNode ) {
|
||||
|
||||
var resourcesData = {};
|
||||
var geometry, material;
|
||||
var basematerialsNode = resourcesNode.querySelector( 'basematerials' );
|
||||
|
||||
if ( basematerialsNode ) {
|
||||
|
||||
resourcesData[ 'basematerial' ] = parseBasematerialsNode( basematerialsNode );
|
||||
|
||||
}
|
||||
|
||||
resourcesData[ 'object' ] = {};
|
||||
var objectNodes = resourcesNode.querySelectorAll( 'object' );
|
||||
|
||||
for ( var i = 0; i < objectNodes.length; i++ ) {
|
||||
|
||||
var objectNode = objectNodes[ i ];
|
||||
var objectData = parseObjectNode( objectNode );
|
||||
resourcesData[ 'object' ][ objectData[ 'id' ] ] = objectData;
|
||||
|
||||
}
|
||||
|
||||
return resourcesData;
|
||||
|
||||
}
|
||||
|
||||
function parseBuildNode( buildNode ) {
|
||||
|
||||
var buildData = [];
|
||||
var itemNodes = buildNode.querySelectorAll( 'item' );
|
||||
|
||||
for ( var i = 0; i < itemNodes.length; i++ ) {
|
||||
|
||||
var itemNode = itemNodes[ i ];
|
||||
var buildItem = {
|
||||
objectid: itemNode.getAttribute( 'objectid' )
|
||||
};
|
||||
var transform = itemNode.getAttribute( 'transform' );
|
||||
|
||||
if ( transform ) {
|
||||
|
||||
var t = [];
|
||||
transform.split( ' ' ).forEach( function( s ) {
|
||||
t.push( parseFloat( s ) );
|
||||
} );
|
||||
var mat4 = new THREE.Matrix4();
|
||||
buildItem[ 'transform' ] = mat4.set(
|
||||
t[ 0 ], t[ 1 ], t[ 2 ], 0.0,
|
||||
t[ 3 ], t[ 4 ], t[ 5 ], 0.0,
|
||||
t[ 6 ], t[ 7 ], t[ 8 ], 0.0,
|
||||
t[ 9 ], t[ 10 ], t[ 11 ], 1.0
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
buildData.push( buildItem );
|
||||
|
||||
}
|
||||
|
||||
return buildData;
|
||||
|
||||
}
|
||||
|
||||
function parseModelNode( modelNode ) {
|
||||
|
||||
var modelData = { unit: modelNode.getAttribute( 'unit' ) || 'millimeter' };
|
||||
var metadataNodes = modelNode.querySelectorAll( 'metadata' );
|
||||
|
||||
if ( metadataNodes ) {
|
||||
|
||||
modelData[ 'metadata' ] = parseMetadataNodes( metadataNodes );
|
||||
|
||||
}
|
||||
|
||||
var resourcesNode = modelNode.querySelector( 'resources' );
|
||||
|
||||
if ( resourcesNode ) {
|
||||
|
||||
modelData[ 'resources' ] = parseResourcesNode( resourcesNode );
|
||||
|
||||
}
|
||||
|
||||
var buildNode = modelNode.querySelector( 'build' );
|
||||
|
||||
if ( buildNode ) {
|
||||
|
||||
modelData[ 'build' ] = parseBuildNode( buildNode );
|
||||
|
||||
}
|
||||
|
||||
return modelData;
|
||||
|
||||
}
|
||||
|
||||
function buildMesh( meshData, data3mf ) {
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
geometry.setIndex( new THREE.BufferAttribute( meshData[ 'triangles' ], 1 ) );
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( meshData[ 'vertices' ], 3 ) );
|
||||
|
||||
if ( meshData[ 'colors' ] ) {
|
||||
|
||||
geometry.addAttribute( 'color', new THREE.BufferAttribute( meshData[ 'colors' ], 3 ) );
|
||||
|
||||
}
|
||||
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
var materialOpts = {
|
||||
shading: THREE.FlatShading
|
||||
};
|
||||
|
||||
if ( meshData[ 'colors' ] && 0 < meshData[ 'colors' ].length ) {
|
||||
|
||||
materialOpts[ 'vertexColors' ] = THREE.VertexColors;
|
||||
|
||||
} else {
|
||||
|
||||
materialOpts[ 'color' ] = 0xaaaaff;
|
||||
|
||||
}
|
||||
|
||||
var material = new THREE.MeshPhongMaterial( materialOpts );
|
||||
return new THREE.Mesh( geometry, material );
|
||||
|
||||
}
|
||||
|
||||
function applyExtensions( extensions, meshData, modelXml, data3mf ) {
|
||||
|
||||
if ( !extensions ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var availableExtensions = [];
|
||||
var keys = Object.keys( extensions );
|
||||
|
||||
for ( var i = 0; i < keys.length; i++ ) {
|
||||
|
||||
var ns = keys[ i ];
|
||||
|
||||
for ( var j = 0; j < scope.availableExtensions.length; j++ ) {
|
||||
|
||||
var extension = scope.availableExtensions[ j ];
|
||||
|
||||
if ( extension.ns === ns ) {
|
||||
|
||||
availableExtensions.push( extension );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < availableExtensions.length; i++ ) {
|
||||
|
||||
var extension = availableExtensions[ i ];
|
||||
extension.apply( modelXml, extensions[ extension[ 'ns' ] ], meshData );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function buildMeshes( data3mf ) {
|
||||
|
||||
var modelsData = data3mf.model;
|
||||
var meshes = {};
|
||||
var modelsKeys = Object.keys( modelsData );
|
||||
|
||||
for ( var i = 0; i < modelsKeys.length; i++ ) {
|
||||
|
||||
var modelsKey = modelsKeys[ i ];
|
||||
var modelData = modelsData[ modelsKey ];
|
||||
var modelXml = modelData[ 'xml' ];
|
||||
var extensions = modelData[ 'extensions' ];
|
||||
|
||||
var objectIds = Object.keys( modelData[ 'resources' ][ 'object' ] );
|
||||
|
||||
for ( var j = 0; j < objectIds.length; j++ ) {
|
||||
|
||||
var objectId = objectIds[ j ];
|
||||
var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
|
||||
var meshData = objectData[ 'mesh' ];
|
||||
applyExtensions( extensions, meshData, modelXml, data3mf );
|
||||
meshes[ objectId ] = buildMesh( meshData, data3mf );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return meshes;
|
||||
|
||||
}
|
||||
|
||||
function build( meshes, refs, data3mf ) {
|
||||
|
||||
var group = new THREE.Group();
|
||||
var buildData = data3mf.model[ refs[ 'target' ].substring( 1 ) ][ 'build' ];
|
||||
|
||||
for ( var i = 0; i < buildData.length; i++ ) {
|
||||
|
||||
var buildItem = buildData[ i ];
|
||||
var mesh = meshes[ buildItem[ 'objectid' ] ];
|
||||
|
||||
if ( buildItem[ 'transform' ] ) {
|
||||
|
||||
mesh.geometry.applyMatrix( buildItem[ 'transform' ] );
|
||||
|
||||
}
|
||||
|
||||
group.add( mesh );
|
||||
|
||||
}
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
var data3mf = loadDocument( data );
|
||||
var meshes = buildMeshes( data3mf );
|
||||
|
||||
return build( meshes, data3mf[ 'rels' ], data3mf )
|
||||
|
||||
},
|
||||
|
||||
addExtension: function( extension ) {
|
||||
|
||||
this.availableExtensions.push( extension );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
500
node_modules/three/examples/js/loaders/AMFLoader.js
generated
vendored
Normal file
500
node_modules/three/examples/js/loaders/AMFLoader.js
generated
vendored
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* @author tamarintech / https://tamarintech.com
|
||||
*
|
||||
* Description: Early release of an AMF Loader following the pattern of the
|
||||
* example loaders in the three.js project.
|
||||
*
|
||||
* More information about the AMF format: http://amf.wikispaces.com
|
||||
*
|
||||
* Usage:
|
||||
* var loader = new AMFLoader();
|
||||
* loader.load('/path/to/project.amf', function(objecttree) {
|
||||
* scene.add(objecttree);
|
||||
* });
|
||||
*
|
||||
* Materials now supported, material colors supported
|
||||
* Zip support, requires jszip
|
||||
* TextDecoder polyfill required by some browsers (particularly IE, Edge)
|
||||
* No constellation support (yet)!
|
||||
*
|
||||
*/
|
||||
|
||||
THREE.AMFLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.AMFLoader.prototype = {
|
||||
|
||||
constructor: THREE.AMFLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
function loadDocument( data ) {
|
||||
|
||||
var view = new DataView( data );
|
||||
var magic = String.fromCharCode( view.getUint8( 0 ), view.getUint8( 1 ) );
|
||||
|
||||
if ( magic === "PK" ) {
|
||||
|
||||
var zip = null;
|
||||
var file = null;
|
||||
|
||||
console.log( "Loading Zip" );
|
||||
|
||||
try {
|
||||
|
||||
zip = new JSZip( data );
|
||||
|
||||
} catch ( e ) {
|
||||
|
||||
if ( e instanceof ReferenceError ) {
|
||||
|
||||
console.log( " jszip missing and file is compressed." );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( file in zip.files ) {
|
||||
|
||||
if ( file.toLowerCase().substr( - 4 ) === '.amf' ) {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log( " Trying to load file asset: " + file );
|
||||
view = new DataView( zip.file( file ).asArrayBuffer() );
|
||||
|
||||
}
|
||||
|
||||
if ( TextDecoder === undefined ) {
|
||||
|
||||
console.log( " TextDecoder not present. Please use TextDecoder polyfill." );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
var fileText = new TextDecoder( 'utf-8' ).decode( view );
|
||||
var xmlData = new DOMParser().parseFromString( fileText, 'application/xml' );
|
||||
|
||||
if ( xmlData.documentElement.nodeName.toLowerCase() !== "amf" ) {
|
||||
|
||||
console.log( " Error loading AMF - no AMF document found." );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return xmlData;
|
||||
|
||||
}
|
||||
|
||||
function loadDocumentScale( node ) {
|
||||
|
||||
var scale = 1.0;
|
||||
var unit = 'millimeter';
|
||||
|
||||
if ( node.documentElement.attributes[ 'unit' ] !== undefined ) {
|
||||
|
||||
unit = node.documentElement.attributes[ 'unit' ].value.toLowerCase();
|
||||
|
||||
}
|
||||
|
||||
var scaleUnits = {
|
||||
'millimeter': 1.0,
|
||||
'inch': 25.4,
|
||||
'feet': 304.8,
|
||||
'meter': 1000.0,
|
||||
'micron': 0.001
|
||||
};
|
||||
|
||||
if ( scaleUnits[ unit ] !== undefined ) {
|
||||
|
||||
scale = scaleUnits[ unit ];
|
||||
|
||||
}
|
||||
|
||||
console.log( " Unit scale: " + scale );
|
||||
return scale;
|
||||
|
||||
}
|
||||
|
||||
function loadMaterials( node ) {
|
||||
|
||||
var matName = "AMF Material";
|
||||
var matId = node.attributes[ 'id' ].textContent;
|
||||
var color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
|
||||
|
||||
var loadedMaterial = null;
|
||||
|
||||
for ( var i = 0; i < node.children.length; i ++ ) {
|
||||
|
||||
var matChildEl = node.children[ i ];
|
||||
|
||||
if ( matChildEl.nodeName === "metadata" && matChildEl.attributes[ 'type' ] !== undefined ) {
|
||||
|
||||
if ( matChildEl.attributes[ 'type' ].value === 'name' ) {
|
||||
|
||||
matname = matChildEl.textContent;
|
||||
|
||||
}
|
||||
|
||||
} else if ( matChildEl.nodeName === 'color' ) {
|
||||
|
||||
color = loadColor( matChildEl );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadedMaterial = new THREE.MeshPhongMaterial( {
|
||||
shading: THREE.FlatShading,
|
||||
color: new THREE.Color( color.r, color.g, color.b ),
|
||||
name: matName
|
||||
} );
|
||||
|
||||
if ( color.a !== 1.0 ) {
|
||||
|
||||
loadedMaterial.transparent = true;
|
||||
loadedMaterial.opacity = color.a;
|
||||
|
||||
}
|
||||
|
||||
return { 'id': matId, 'material': loadedMaterial };
|
||||
|
||||
}
|
||||
|
||||
function loadColor( node ) {
|
||||
|
||||
var color = { 'r': 1.0, 'g': 1.0, 'b': 1.0, 'a': 1.0 };
|
||||
|
||||
for ( var i = 0; i < node.children.length; i ++ ) {
|
||||
|
||||
var matColor = node.children[ i ];
|
||||
|
||||
if ( matColor.nodeName === 'r' ) {
|
||||
|
||||
color.r = matColor.textContent;
|
||||
|
||||
} else if ( matColor.nodeName === 'g' ) {
|
||||
|
||||
color.g = matColor.textContent;
|
||||
|
||||
} else if ( matColor.nodeName === 'b' ) {
|
||||
|
||||
color.b = matColor.textContent;
|
||||
|
||||
} else if ( matColor.nodeName === 'a' ) {
|
||||
|
||||
color.a = matColor.textContent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
function loadMeshVolume( node ) {
|
||||
|
||||
var volume = { "name": "", "triangles": [], "materialid": null };
|
||||
|
||||
var currVolumeNode = node.firstElementChild;
|
||||
|
||||
if ( node.attributes[ 'materialid' ] !== undefined ) {
|
||||
|
||||
volume.materialId = node.attributes[ 'materialid' ].nodeValue;
|
||||
|
||||
}
|
||||
|
||||
while ( currVolumeNode ) {
|
||||
|
||||
if ( currVolumeNode.nodeName === "metadata" ) {
|
||||
|
||||
if ( currVolumeNode.attributes[ 'type' ] !== undefined ) {
|
||||
|
||||
if ( currVolumeNode.attributes[ 'type' ].value === 'name' ) {
|
||||
|
||||
volume.name = currVolumeNode.textContent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( currVolumeNode.nodeName === "triangle" ) {
|
||||
|
||||
var v1 = currVolumeNode.getElementsByTagName("v1")[0].textContent;
|
||||
var v2 = currVolumeNode.getElementsByTagName("v2")[0].textContent;
|
||||
var v3 = currVolumeNode.getElementsByTagName("v3")[0].textContent;
|
||||
|
||||
volume.triangles.push( v1 );
|
||||
volume.triangles.push( v2 );
|
||||
volume.triangles.push( v3 );
|
||||
|
||||
}
|
||||
|
||||
currVolumeNode = currVolumeNode.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
return volume;
|
||||
|
||||
}
|
||||
|
||||
function loadMeshVertices( node ) {
|
||||
|
||||
var vertArray = [];
|
||||
var normalArray = [];
|
||||
var currVerticesNode = node.firstElementChild;
|
||||
|
||||
while ( currVerticesNode ) {
|
||||
|
||||
if ( currVerticesNode.nodeName === "vertex" ) {
|
||||
|
||||
var vNode = currVerticesNode.firstElementChild;
|
||||
|
||||
while ( vNode ) {
|
||||
|
||||
if ( vNode.nodeName === "coordinates" ) {
|
||||
|
||||
var x = vNode.getElementsByTagName("x")[0].textContent;
|
||||
var y = vNode.getElementsByTagName("y")[0].textContent;
|
||||
var z = vNode.getElementsByTagName("z")[0].textContent;
|
||||
|
||||
vertArray.push(x);
|
||||
vertArray.push(y);
|
||||
vertArray.push(z);
|
||||
|
||||
} else if ( vNode.nodeName === "normal" ) {
|
||||
|
||||
var nx = vNode.getElementsByTagName("nx")[0].textContent;
|
||||
var ny = vNode.getElementsByTagName("ny")[0].textContent;
|
||||
var nz = vNode.getElementsByTagName("nz")[0].textContent;
|
||||
|
||||
normalArray.push(nx);
|
||||
normalArray.push(ny);
|
||||
normalArray.push(nz);
|
||||
|
||||
}
|
||||
|
||||
vNode = vNode.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
currVerticesNode = currVerticesNode.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
return { "vertices": vertArray, "normals": normalArray };
|
||||
|
||||
}
|
||||
|
||||
function loadObject( node ) {
|
||||
|
||||
var objId = node.attributes[ 'id' ].textContent;
|
||||
var loadedObject = { "name": "amfobject", "meshes": [] };
|
||||
var currColor = null;
|
||||
var currObjNode = node.firstElementChild;
|
||||
|
||||
while ( currObjNode ) {
|
||||
|
||||
if ( currObjNode.nodeName === "metadata" ) {
|
||||
|
||||
if ( currObjNode.attributes[ 'type' ] !== undefined ) {
|
||||
|
||||
if ( currObjNode.attributes[ 'type' ].value === 'name' ) {
|
||||
|
||||
loadedObject.name = currObjNode.textContent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( currObjNode.nodeName === "color" ) {
|
||||
|
||||
currColor = loadColor( currObjNode );
|
||||
|
||||
} else if ( currObjNode.nodeName === "mesh" ) {
|
||||
|
||||
var currMeshNode = currObjNode.firstElementChild;
|
||||
var mesh = { "vertices": [], "normals": [], "volumes": [], "color": currColor };
|
||||
|
||||
while ( currMeshNode ) {
|
||||
|
||||
if ( currMeshNode.nodeName === "vertices" ) {
|
||||
|
||||
var loadedVertices = loadMeshVertices( currMeshNode );
|
||||
|
||||
mesh.normals = mesh.normals.concat( loadedVertices.normals );
|
||||
mesh.vertices = mesh.vertices.concat( loadedVertices.vertices );
|
||||
|
||||
} else if ( currMeshNode.nodeName === "volume" ) {
|
||||
|
||||
mesh.volumes.push( loadMeshVolume( currMeshNode ) );
|
||||
|
||||
}
|
||||
|
||||
currMeshNode = currMeshNode.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
loadedObject.meshes.push( mesh );
|
||||
|
||||
}
|
||||
|
||||
currObjNode = currObjNode.nextElementSibling;
|
||||
|
||||
}
|
||||
|
||||
return { 'id': objId, 'obj': loadedObject };
|
||||
|
||||
}
|
||||
|
||||
var xmlData = loadDocument( data );
|
||||
var amfName = "";
|
||||
var amfAuthor = "";
|
||||
var amfScale = loadDocumentScale( xmlData );
|
||||
var amfMaterials = {};
|
||||
var amfObjects = {};
|
||||
var children = xmlData.documentElement.children;
|
||||
|
||||
for ( var i = 0; i < children.length; i ++ ) {
|
||||
|
||||
var child = children[ i ];
|
||||
|
||||
if ( child.nodeName === 'metadata' ) {
|
||||
|
||||
if ( child.attributes[ 'type' ] !== undefined ) {
|
||||
|
||||
if ( child.attributes[ 'type' ].value === 'name' ) {
|
||||
|
||||
amfName = child.textContent;
|
||||
|
||||
} else if ( child.attributes[ 'type' ].value === 'author' ) {
|
||||
|
||||
amfAuthor = child.textContent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( child.nodeName === 'material' ) {
|
||||
|
||||
var loadedMaterial = loadMaterials( child );
|
||||
|
||||
amfMaterials[ loadedMaterial.id ] = loadedMaterial.material;
|
||||
|
||||
} else if ( child.nodeName === 'object' ) {
|
||||
|
||||
var loadedObject = loadObject( child );
|
||||
|
||||
amfObjects[ loadedObject.id ] = loadedObject.obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var sceneObject = new THREE.Group();
|
||||
var defaultMaterial = new THREE.MeshPhongMaterial( { color: 0xaaaaff, shading: THREE.FlatShading } );
|
||||
|
||||
sceneObject.name = amfName;
|
||||
sceneObject.userData.author = amfAuthor;
|
||||
sceneObject.userData.loader = "AMF";
|
||||
|
||||
for ( var id in amfObjects ) {
|
||||
|
||||
var part = amfObjects[ id ];
|
||||
var meshes = part.meshes;
|
||||
var newObject = new THREE.Group();
|
||||
newObject.name = part.name || '';
|
||||
|
||||
for ( var i = 0; i < meshes.length; i ++ ) {
|
||||
|
||||
var objDefaultMaterial = defaultMaterial;
|
||||
var mesh = meshes[ i ];
|
||||
var vertices = new THREE.BufferAttribute( new Float32Array( mesh.vertices ), 3 );
|
||||
var normals = null;
|
||||
|
||||
if ( mesh.normals.length ) {
|
||||
|
||||
normals = new THREE.BufferAttribute( new Float32Array( mesh.normals ), 3 );
|
||||
|
||||
}
|
||||
|
||||
if ( mesh.color ) {
|
||||
|
||||
var color = mesh.color;
|
||||
|
||||
objDefaultMaterial = defaultMaterial.clone();
|
||||
objDefaultMaterial.color = new THREE.Color( color.r, color.g, color.b );
|
||||
|
||||
if ( color.a !== 1.0 ) {
|
||||
|
||||
objDefaultMaterial.transparent = true;
|
||||
objDefaultMaterial.opacity = color.a;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var volumes = mesh.volumes;
|
||||
|
||||
for ( var j = 0; j < volumes.length; j ++ ) {
|
||||
|
||||
var volume = volumes[ j ];
|
||||
var newGeometry = new THREE.BufferGeometry();
|
||||
var indexes = new Uint32Array( volume.triangles );
|
||||
var material = objDefaultMaterial;
|
||||
|
||||
newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
|
||||
newGeometry.addAttribute( 'position', vertices.clone() );
|
||||
|
||||
if( normals ) {
|
||||
|
||||
newGeometry.addAttribute( 'normal', normals.clone() );
|
||||
|
||||
}
|
||||
|
||||
if ( amfMaterials[ volume.materialId ] !== undefined ) {
|
||||
|
||||
material = amfMaterials[ volume.materialId ];
|
||||
|
||||
}
|
||||
|
||||
newGeometry.scale( amfScale, amfScale, amfScale );
|
||||
newObject.add( new THREE.Mesh( newGeometry, material.clone() ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sceneObject.add( newObject );
|
||||
|
||||
}
|
||||
|
||||
return sceneObject;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
1237
node_modules/three/examples/js/loaders/AWDLoader.js
generated
vendored
Normal file
1237
node_modules/three/examples/js/loaders/AWDLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
318
node_modules/three/examples/js/loaders/AssimpJSONLoader.js
generated
vendored
Normal file
318
node_modules/three/examples/js/loaders/AssimpJSONLoader.js
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* @author Alexander Gessler / http://www.greentoken.de/
|
||||
* https://github.com/acgessler
|
||||
*
|
||||
* Loader for models imported with Open Asset Import Library (http://assimp.sf.net)
|
||||
* through assimp2json (https://github.com/acgessler/assimp2json).
|
||||
*
|
||||
* Supports any input format that assimp supports, including 3ds, obj, dae, blend,
|
||||
* fbx, x, ms3d, lwo (and many more).
|
||||
*
|
||||
* See webgl_loader_assimp2json example.
|
||||
*/
|
||||
|
||||
THREE.AssimpJSONLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.AssimpJSONLoader.prototype = {
|
||||
|
||||
constructor: THREE.AssimpJSONLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
this.texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : this.extractUrlBase( url );
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
var json = JSON.parse( text ), scene, metadata;
|
||||
|
||||
// Check __metadata__ meta header if present
|
||||
// This header is used to disambiguate between
|
||||
// different JSON-based file formats.
|
||||
metadata = json.__metadata__;
|
||||
if ( typeof metadata !== 'undefined' ) {
|
||||
|
||||
// Check if assimp2json at all
|
||||
if ( metadata.format !== 'assimp2json' ) {
|
||||
|
||||
onError( 'Not an assimp2json scene' );
|
||||
return;
|
||||
|
||||
}
|
||||
// Check major format version
|
||||
else if ( metadata.version < 100 && metadata.version >= 200 ) {
|
||||
|
||||
onError( 'Unsupported assimp2json file format version' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
scene = scope.parse( json );
|
||||
onLoad( scene );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
|
||||
},
|
||||
|
||||
setTexturePath: function ( value ) {
|
||||
|
||||
this.texturePath = value;
|
||||
|
||||
},
|
||||
|
||||
extractUrlBase: function ( url ) {
|
||||
|
||||
// from three/src/loaders/Loader.js
|
||||
var parts = url.split( '/' );
|
||||
parts.pop();
|
||||
return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
|
||||
|
||||
},
|
||||
|
||||
parse: function ( json ) {
|
||||
|
||||
var meshes = this.parseList ( json.meshes, this.parseMesh );
|
||||
var materials = this.parseList ( json.materials, this.parseMaterial );
|
||||
return this.parseObject( json, json.rootnode, meshes, materials );
|
||||
|
||||
},
|
||||
|
||||
parseList : function( json, handler ) {
|
||||
|
||||
var meshes = new Array( json.length );
|
||||
for ( var i = 0; i < json.length; ++ i ) {
|
||||
|
||||
meshes[ i ] = handler.call( this, json[ i ] );
|
||||
|
||||
}
|
||||
return meshes;
|
||||
|
||||
},
|
||||
|
||||
parseMesh : function( json ) {
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
var i, l, face;
|
||||
|
||||
var indices = [];
|
||||
|
||||
var vertices = json.vertices || [];
|
||||
var normals = json.normals || [];
|
||||
var uvs = json.texturecoords || [];
|
||||
var colors = json.colors || [];
|
||||
|
||||
uvs = uvs[ 0 ] || []; // only support for a single set of uvs
|
||||
|
||||
for ( i = 0, l = json.faces.length; i < l; i ++ ) {
|
||||
|
||||
face = json.faces[ i ];
|
||||
indices.push( face[ 0 ], face[ 1 ], face[ 2 ] );
|
||||
|
||||
}
|
||||
|
||||
geometry.setIndex( indices );
|
||||
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
|
||||
|
||||
if ( normals.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( uvs.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( colors.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
parseMaterial : function( json ) {
|
||||
|
||||
var mat = null;
|
||||
var scope = this;
|
||||
var i, prop, has_textures = [],
|
||||
|
||||
init_props = {
|
||||
shading : THREE.SmoothShading
|
||||
};
|
||||
|
||||
function toColor( value_arr ) {
|
||||
|
||||
var col = new THREE.Color();
|
||||
col.setRGB( value_arr[ 0 ], value_arr[ 1 ], value_arr[ 2 ] );
|
||||
return col;
|
||||
|
||||
}
|
||||
|
||||
function defaultTexture() {
|
||||
|
||||
var im = new Image();
|
||||
im.width = 1;
|
||||
im.height = 1;
|
||||
return new THREE.Texture( im );
|
||||
|
||||
}
|
||||
|
||||
for ( i in json.properties ) {
|
||||
|
||||
prop = json.properties[ i ];
|
||||
|
||||
if ( prop.key === '$tex.file' ) {
|
||||
|
||||
// prop.semantic gives the type of the texture
|
||||
// 1: diffuse
|
||||
// 2: specular mao
|
||||
// 5: height map (bumps)
|
||||
// 6: normal map
|
||||
// more values (i.e. emissive, environment) are known by assimp and may be relevant
|
||||
if ( prop.semantic === 1 || prop.semantic === 5 || prop.semantic === 6 || prop.semantic === 2 ) {
|
||||
|
||||
( function( semantic ) {
|
||||
|
||||
var loader = new THREE.TextureLoader( scope.manager ),
|
||||
keyname;
|
||||
|
||||
if ( semantic === 1 ) {
|
||||
|
||||
keyname = 'map';
|
||||
|
||||
} else if ( semantic === 5 ) {
|
||||
|
||||
keyname = 'bumpMap';
|
||||
|
||||
} else if ( semantic === 6 ) {
|
||||
|
||||
keyname = 'normalMap';
|
||||
|
||||
} else if ( semantic === 2 ) {
|
||||
|
||||
keyname = 'specularMap';
|
||||
|
||||
}
|
||||
|
||||
has_textures.push( keyname );
|
||||
|
||||
loader.setCrossOrigin( this.crossOrigin );
|
||||
var material_url = scope.texturePath + '/' + prop.value;
|
||||
material_url = material_url.replace( /\\/g, '/' );
|
||||
loader.load( material_url, function( tex ) {
|
||||
|
||||
if ( tex ) {
|
||||
|
||||
// TODO: read texture settings from assimp.
|
||||
// Wrapping is the default, though.
|
||||
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
|
||||
|
||||
mat[ keyname ] = tex;
|
||||
mat.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
} )( prop.semantic );
|
||||
|
||||
}
|
||||
|
||||
} else if ( prop.key === '?mat.name' ) {
|
||||
|
||||
init_props.name = prop.value;
|
||||
|
||||
} else if ( prop.key === '$clr.diffuse' ) {
|
||||
|
||||
init_props.color = toColor( prop.value );
|
||||
|
||||
} else if ( prop.key === '$clr.specular' ) {
|
||||
|
||||
init_props.specular = toColor( prop.value );
|
||||
|
||||
} else if ( prop.key === '$clr.emissive' ) {
|
||||
|
||||
init_props.emissive = toColor( prop.value );
|
||||
|
||||
} else if ( prop.key === '$mat.shadingm' ) {
|
||||
|
||||
// aiShadingMode_Flat
|
||||
if ( prop.value === 1 ) {
|
||||
|
||||
init_props.shading = THREE.FlatShading;
|
||||
|
||||
}
|
||||
|
||||
} else if ( prop.key === '$mat.shininess' ) {
|
||||
|
||||
init_props.shininess = prop.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// note: three.js does not like it when a texture is added after the geometry
|
||||
// has been rendered once, see http://stackoverflow.com/questions/16531759/.
|
||||
// for this reason we fill all slots upfront with default textures
|
||||
if ( has_textures.length ) {
|
||||
|
||||
for ( i = has_textures.length - 1; i >= 0; -- i ) {
|
||||
|
||||
init_props[ has_textures[ i ]] = defaultTexture();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mat = new THREE.MeshPhongMaterial( init_props );
|
||||
return mat;
|
||||
|
||||
},
|
||||
|
||||
parseObject : function( json, node, meshes, materials ) {
|
||||
|
||||
var obj = new THREE.Object3D(), i, idx;
|
||||
|
||||
obj.name = node.name || "";
|
||||
obj.matrix = new THREE.Matrix4().fromArray( node.transformation ).transpose();
|
||||
obj.matrix.decompose( obj.position, obj.quaternion, obj.scale );
|
||||
|
||||
for ( i = 0; node.meshes && i < node.meshes.length; ++ i ) {
|
||||
|
||||
idx = node.meshes[ i ];
|
||||
obj.add( new THREE.Mesh( meshes[ idx ], materials[ json.meshes[ idx ].materialindex ] ) );
|
||||
|
||||
}
|
||||
|
||||
for ( i = 0; node.children && i < node.children.length; ++ i ) {
|
||||
|
||||
obj.add( this.parseObject( json, node.children[ i ], meshes, materials ) );
|
||||
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
};
|
||||
2353
node_modules/three/examples/js/loaders/AssimpLoader.js
generated
vendored
Normal file
2353
node_modules/three/examples/js/loaders/AssimpLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
404
node_modules/three/examples/js/loaders/BVHLoader.js
generated
vendored
Normal file
404
node_modules/three/examples/js/loaders/BVHLoader.js
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
/**
|
||||
* @author herzig / http://github.com/herzig
|
||||
*
|
||||
* Description: reads BVH files and outputs a single THREE.Skeleton and an THREE.AnimationClip
|
||||
*
|
||||
* Currently only supports bvh files containing a single root.
|
||||
*
|
||||
*/
|
||||
|
||||
THREE.BVHLoader = function( manager ) {
|
||||
|
||||
this.animateBonePositions = true;
|
||||
this.animateBoneRotations = true;
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.BVHLoader.prototype = {
|
||||
|
||||
constructor: THREE.BVHLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function( buffer ) {
|
||||
|
||||
onLoad( scope.parse( buffer ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( buffer ) {
|
||||
|
||||
/*
|
||||
reads a string array (lines) from a BVH file
|
||||
and outputs a skeleton structure including motion data
|
||||
|
||||
returns thee root node:
|
||||
{ name: "", channels: [], children: [] }
|
||||
*/
|
||||
function readBvh( lines ) {
|
||||
|
||||
// read model structure
|
||||
if ( nextLine( lines ) !== "HIERARCHY" ) {
|
||||
|
||||
throw "HIERARCHY expected";
|
||||
|
||||
}
|
||||
|
||||
var list = []; // collects flat array of all bones
|
||||
var root = readNode( lines, nextLine( lines ), list );
|
||||
|
||||
// read motion data
|
||||
if ( nextLine( lines ) != "MOTION" ) {
|
||||
|
||||
throw "MOTION expected";
|
||||
|
||||
}
|
||||
|
||||
// number of frames
|
||||
var tokens = nextLine( lines ).split( /[\s]+/ );
|
||||
var numFrames = parseInt( tokens[ 1 ] );
|
||||
if ( isNaN( numFrames ) ) {
|
||||
|
||||
throw "Failed to read number of frames.";
|
||||
|
||||
}
|
||||
|
||||
// frame time
|
||||
tokens = nextLine( lines ).split( /[\s]+/ );
|
||||
var frameTime = parseFloat( tokens[ 2 ] );
|
||||
if ( isNaN( frameTime ) ) {
|
||||
|
||||
throw "Failed to read frame time.";
|
||||
|
||||
}
|
||||
|
||||
// read frame data line by line
|
||||
for ( var i = 0; i < numFrames; ++ i ) {
|
||||
|
||||
tokens = nextLine( lines ).split( /[\s]+/ );
|
||||
|
||||
readFrameData( tokens, i * frameTime, root, list );
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Recursively reads data from a single frame into the bone hierarchy.
|
||||
The passed bone hierarchy has to be structured in the same order as the BVH file.
|
||||
keyframe data is stored in bone.frames.
|
||||
|
||||
- data: splitted string array (frame values), values are shift()ed so
|
||||
this should be empty after parsing the whole hierarchy.
|
||||
- frameTime: playback time for this keyframe.
|
||||
- bone: the bone to read frame data from.
|
||||
*/
|
||||
function readFrameData( data, frameTime, bone ) {
|
||||
|
||||
// end sites have no motion data
|
||||
if ( bone.type === "ENDSITE" ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// add keyframe
|
||||
var keyframe = {
|
||||
time: frameTime,
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
rotation: new THREE.Quaternion()
|
||||
};
|
||||
|
||||
bone.frames.push( keyframe );
|
||||
|
||||
var quat = new THREE.Quaternion();
|
||||
|
||||
var vx = new THREE.Vector3( 1, 0, 0 );
|
||||
var vy = new THREE.Vector3( 0, 1, 0 );
|
||||
var vz = new THREE.Vector3( 0, 0, 1 );
|
||||
|
||||
// parse values for each channel in node
|
||||
for ( var i = 0; i < bone.channels.length; ++ i ) {
|
||||
|
||||
switch ( bone.channels[ i ] ) {
|
||||
|
||||
case "Xposition":
|
||||
keyframe.position.x = parseFloat( data.shift().trim() );
|
||||
break;
|
||||
case "Yposition":
|
||||
keyframe.position.y = parseFloat( data.shift().trim() );
|
||||
break;
|
||||
case "Zposition":
|
||||
keyframe.position.z = parseFloat( data.shift().trim() );
|
||||
break;
|
||||
case "Xrotation":
|
||||
quat.setFromAxisAngle( vx, parseFloat( data.shift().trim() ) * Math.PI / 180 );
|
||||
keyframe.rotation.multiply( quat );
|
||||
break;
|
||||
case "Yrotation":
|
||||
quat.setFromAxisAngle( vy, parseFloat( data.shift().trim() ) * Math.PI / 180 );
|
||||
keyframe.rotation.multiply( quat );
|
||||
break;
|
||||
case "Zrotation":
|
||||
quat.setFromAxisAngle( vz, parseFloat( data.shift().trim() ) * Math.PI / 180 );
|
||||
keyframe.rotation.multiply( quat );
|
||||
break;
|
||||
default:
|
||||
throw "invalid channel type";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// parse child nodes
|
||||
for ( var i = 0; i < bone.children.length; ++ i ) {
|
||||
|
||||
readFrameData( data, frameTime, bone.children[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Recursively parses the HIERACHY section of the BVH file
|
||||
|
||||
- lines: all lines of the file. lines are consumed as we go along.
|
||||
- firstline: line containing the node type and name e.g. "JOINT hip"
|
||||
- list: collects a flat list of nodes
|
||||
|
||||
returns: a BVH node including children
|
||||
*/
|
||||
function readNode( lines, firstline, list ) {
|
||||
|
||||
var node = { name: "", type: "", frames: [] };
|
||||
list.push( node );
|
||||
|
||||
// parse node type and name.
|
||||
var tokens = firstline.split( /[\s]+/ );
|
||||
|
||||
if ( tokens[ 0 ].toUpperCase() === "END" && tokens[ 1 ].toUpperCase() === "SITE" ) {
|
||||
|
||||
node.type = "ENDSITE";
|
||||
node.name = "ENDSITE"; // bvh end sites have no name
|
||||
|
||||
} else {
|
||||
|
||||
node.name = tokens[ 1 ];
|
||||
node.type = tokens[ 0 ].toUpperCase();
|
||||
|
||||
}
|
||||
|
||||
if ( nextLine( lines ) != "{" ) {
|
||||
|
||||
throw "Expected opening { after type & name";
|
||||
|
||||
}
|
||||
|
||||
// parse OFFSET
|
||||
tokens = nextLine( lines ).split( /[\s]+/ );
|
||||
|
||||
if ( tokens[ 0 ] !== "OFFSET" ) {
|
||||
|
||||
throw "Expected OFFSET, but got: " + tokens[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
if ( tokens.length != 4 ) {
|
||||
|
||||
throw "OFFSET: Invalid number of values";
|
||||
|
||||
}
|
||||
|
||||
var offset = {
|
||||
x: parseFloat( tokens[ 1 ] ),
|
||||
y: parseFloat( tokens[ 2 ] ),
|
||||
z: parseFloat( tokens[ 3 ] )
|
||||
};
|
||||
|
||||
if ( isNaN( offset.x ) || isNaN( offset.y ) || isNaN( offset.z ) ) {
|
||||
|
||||
throw "OFFSET: Invalid values";
|
||||
|
||||
}
|
||||
|
||||
node.offset = offset;
|
||||
|
||||
// parse CHANNELS definitions
|
||||
if ( node.type != "ENDSITE" ) {
|
||||
|
||||
tokens = nextLine( lines ).split( /[\s]+/ );
|
||||
|
||||
if ( tokens[ 0 ] != "CHANNELS" ) {
|
||||
|
||||
throw "Expected CHANNELS definition";
|
||||
|
||||
}
|
||||
|
||||
var numChannels = parseInt( tokens[ 1 ] );
|
||||
node.channels = tokens.splice( 2, numChannels );
|
||||
node.children = [];
|
||||
|
||||
}
|
||||
|
||||
// read children
|
||||
while ( true ) {
|
||||
|
||||
var line = nextLine( lines );
|
||||
|
||||
if ( line === "}" ) {
|
||||
|
||||
return node;
|
||||
|
||||
} else {
|
||||
|
||||
node.children.push( readNode( lines, line, list ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
recursively converts the internal bvh node structure to a THREE.Bone hierarchy
|
||||
|
||||
source: the bvh root node
|
||||
list: pass an empty array, collects a flat list of all converted THREE.Bones
|
||||
|
||||
returns the root THREE.Bone
|
||||
*/
|
||||
function toTHREEBone( source, list ) {
|
||||
|
||||
var bone = new THREE.Bone();
|
||||
list.push( bone );
|
||||
|
||||
bone.position.add( source.offset );
|
||||
bone.name = source.name;
|
||||
|
||||
if ( source.type != "ENDSITE" ) {
|
||||
|
||||
for ( var i = 0; i < source.children.length; ++ i ) {
|
||||
|
||||
bone.add( toTHREEBone( source.children[ i ], list ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return bone;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
builds a THREE.AnimationClip from the keyframe data saved in each bone.
|
||||
|
||||
bone: bvh root node
|
||||
|
||||
returns: a THREE.AnimationClip containing position and quaternion tracks
|
||||
*/
|
||||
function toTHREEAnimation( bones ) {
|
||||
|
||||
var tracks = [];
|
||||
|
||||
// create a position and quaternion animation track for each node
|
||||
for ( var i = 0; i < bones.length; ++ i ) {
|
||||
|
||||
var bone = bones[ i ];
|
||||
|
||||
if ( bone.type == "ENDSITE" )
|
||||
continue;
|
||||
|
||||
// track data
|
||||
var times = [];
|
||||
var positions = [];
|
||||
var rotations = [];
|
||||
|
||||
for ( var j = 0; j < bone.frames.length; ++ j ) {
|
||||
|
||||
var frame = bone.frames[ j ];
|
||||
|
||||
times.push( frame.time );
|
||||
|
||||
// the animation system animates the position property,
|
||||
// so we have to add the joint offset to all values
|
||||
positions.push( frame.position.x + bone.offset.x );
|
||||
positions.push( frame.position.y + bone.offset.y );
|
||||
positions.push( frame.position.z + bone.offset.z );
|
||||
|
||||
rotations.push( frame.rotation.x );
|
||||
rotations.push( frame.rotation.y );
|
||||
rotations.push( frame.rotation.z );
|
||||
rotations.push( frame.rotation.w );
|
||||
|
||||
}
|
||||
|
||||
if ( scope.animateBonePositions ) {
|
||||
|
||||
tracks.push( new THREE.VectorKeyframeTrack(
|
||||
".bones[" + bone.name + "].position", times, positions ) );
|
||||
|
||||
}
|
||||
|
||||
if ( scope.animateBoneRotations ) {
|
||||
|
||||
tracks.push( new THREE.QuaternionKeyframeTrack(
|
||||
".bones[" + bone.name + "].quaternion", times, rotations ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new THREE.AnimationClip( "animation", - 1, tracks );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
returns the next non-empty line in lines
|
||||
*/
|
||||
function nextLine( lines ) {
|
||||
|
||||
var line;
|
||||
// skip empty lines
|
||||
while ( ( line = lines.shift().trim() ).length === 0 ) { }
|
||||
return line;
|
||||
|
||||
}
|
||||
|
||||
var scope = this;
|
||||
|
||||
// convert buffer to ASCII string
|
||||
var text = "";
|
||||
var raw = new Uint8Array( buffer );
|
||||
for ( var i = 0; i < raw.length; ++ i ) {
|
||||
|
||||
text += String.fromCharCode( raw[ i ] );
|
||||
|
||||
}
|
||||
|
||||
var lines = text.split( /[\r\n]+/g );
|
||||
|
||||
var bones = readBvh( lines );
|
||||
|
||||
var threeBones = [];
|
||||
toTHREEBone( bones[ 0 ], threeBones );
|
||||
|
||||
var threeClip = toTHREEAnimation( bones );
|
||||
|
||||
return {
|
||||
skeleton: new THREE.Skeleton( threeBones ),
|
||||
clip: threeClip
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
248
node_modules/three/examples/js/loaders/BabylonLoader.js
generated
vendored
Normal file
248
node_modules/three/examples/js/loaders/BabylonLoader.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.BabylonLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.BabylonLoader.prototype = {
|
||||
|
||||
constructor: THREE.BabylonLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( JSON.parse( text ) ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( json ) {
|
||||
|
||||
var materials = this.parseMaterials( json );
|
||||
var scene = this.parseObjects( json, materials );
|
||||
|
||||
return scene;
|
||||
|
||||
},
|
||||
|
||||
parseMaterials: function ( json ) {
|
||||
|
||||
var materials = {};
|
||||
|
||||
for ( var i = 0, l = json.materials.length; i < l; i ++ ) {
|
||||
|
||||
var data = json.materials[ i ];
|
||||
|
||||
var material = new THREE.MeshPhongMaterial();
|
||||
material.name = data.name;
|
||||
material.color.fromArray( data.diffuse );
|
||||
material.emissive.fromArray( data.emissive );
|
||||
material.specular.fromArray( data.specular );
|
||||
material.shininess = data.specularPower;
|
||||
material.opacity = data.alpha;
|
||||
|
||||
materials[ data.id ] = material;
|
||||
|
||||
}
|
||||
|
||||
if ( json.multiMaterials ) {
|
||||
|
||||
for ( var i = 0, l = json.multiMaterials.length; i < l; i ++ ) {
|
||||
|
||||
var data = json.multiMaterials[ i ];
|
||||
|
||||
console.warn( 'THREE.BabylonLoader: Multi materials not yet supported.' );
|
||||
|
||||
materials[ data.id ] = new THREE.MeshPhongMaterial();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return materials;
|
||||
|
||||
},
|
||||
|
||||
parseGeometry: function ( json ) {
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
// indices
|
||||
|
||||
var indices = new Uint16Array( json.indices );
|
||||
|
||||
geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
|
||||
|
||||
// positions
|
||||
|
||||
var positions = new Float32Array( json.positions );
|
||||
|
||||
for ( var j = 2, jl = positions.length; j < jl; j += 3 ) {
|
||||
|
||||
positions[ j ] = - positions[ j ];
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
|
||||
|
||||
// normals
|
||||
|
||||
if ( json.normals ) {
|
||||
|
||||
var normals = new Float32Array( json.normals );
|
||||
|
||||
for ( var j = 2, jl = normals.length; j < jl; j += 3 ) {
|
||||
|
||||
normals[ j ] = - normals[ j ];
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
// uvs
|
||||
|
||||
if ( json.uvs ) {
|
||||
|
||||
var uvs = new Float32Array( json.uvs );
|
||||
|
||||
geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
// offsets
|
||||
|
||||
var subMeshes = json.subMeshes;
|
||||
|
||||
if ( subMeshes ) {
|
||||
|
||||
for ( var j = 0, jl = subMeshes.length; j < jl; j ++ ) {
|
||||
|
||||
var subMesh = subMeshes[ j ];
|
||||
|
||||
geometry.addGroup( subMesh.indexStart, subMesh.indexCount );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
parseObjects: function ( json, materials ) {
|
||||
|
||||
var objects = {};
|
||||
var scene = new THREE.Scene();
|
||||
|
||||
var cameras = json.cameras;
|
||||
|
||||
for ( var i = 0, l = cameras.length; i < l; i ++ ) {
|
||||
|
||||
var data = cameras[ i ];
|
||||
|
||||
var camera = new THREE.PerspectiveCamera( ( data.fov / Math.PI ) * 180, 1.33, data.minZ, data.maxZ );
|
||||
|
||||
camera.name = data.name;
|
||||
camera.position.fromArray( data.position );
|
||||
if ( data.rotation ) camera.rotation.fromArray( data.rotation );
|
||||
|
||||
objects[ data.id ] = camera;
|
||||
|
||||
}
|
||||
|
||||
var lights = json.lights;
|
||||
|
||||
for ( var i = 0, l = lights.length; i < l; i ++ ) {
|
||||
|
||||
var data = lights[ i ];
|
||||
|
||||
var light;
|
||||
|
||||
switch ( data.type ) {
|
||||
|
||||
case 0:
|
||||
light = new THREE.PointLight();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
light = new THREE.DirectionalLight();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
light = new THREE.SpotLight();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
light = new THREE.HemisphereLight();
|
||||
break;
|
||||
}
|
||||
|
||||
light.name = data.name;
|
||||
if ( data.position ) light.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
|
||||
light.color.fromArray( data.diffuse );
|
||||
if ( data.groundColor ) light.groundColor.fromArray( data.groundColor );
|
||||
if ( data.intensity ) light.intensity = data.intensity;
|
||||
|
||||
objects[ data.id ] = light;
|
||||
|
||||
scene.add( light );
|
||||
|
||||
}
|
||||
|
||||
var meshes = json.meshes;
|
||||
|
||||
for ( var i = 0, l = meshes.length; i < l; i ++ ) {
|
||||
|
||||
var data = meshes[ i ];
|
||||
|
||||
var object;
|
||||
|
||||
if ( data.indices ) {
|
||||
|
||||
var geometry = this.parseGeometry( data );
|
||||
|
||||
object = new THREE.Mesh( geometry, materials[ data.materialId ] );
|
||||
|
||||
} else {
|
||||
|
||||
object = new THREE.Group();
|
||||
|
||||
}
|
||||
|
||||
object.name = data.name;
|
||||
object.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] );
|
||||
object.rotation.fromArray( data.rotation );
|
||||
if ( data.rotationQuaternion ) object.quaternion.fromArray( data.rotationQuaternion );
|
||||
object.scale.fromArray( data.scaling );
|
||||
// object.visible = data.isVisible;
|
||||
|
||||
if ( data.parentId ) {
|
||||
|
||||
objects[ data.parentId ].add( object );
|
||||
|
||||
} else {
|
||||
|
||||
scene.add( object );
|
||||
|
||||
}
|
||||
|
||||
objects[ data.id ] = object;
|
||||
|
||||
}
|
||||
|
||||
return scene;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
698
node_modules/three/examples/js/loaders/BinaryLoader.js
generated
vendored
Normal file
698
node_modules/three/examples/js/loaders/BinaryLoader.js
generated
vendored
Normal file
@@ -0,0 +1,698 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.BinaryLoader = function ( manager ) {
|
||||
|
||||
if ( typeof manager === 'boolean' ) {
|
||||
|
||||
console.warn( 'THREE.BinaryLoader: showStatus parameter has been removed from constructor.' );
|
||||
manager = undefined;
|
||||
|
||||
}
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.BinaryLoader.prototype = {
|
||||
|
||||
constructor: THREE.BinaryLoader,
|
||||
|
||||
// Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
|
||||
// - binary models consist of two files: JS and BIN
|
||||
// - parameters
|
||||
// - url (required)
|
||||
// - callback (required)
|
||||
// - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
|
||||
// - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
// todo: unify load API to for easier SceneLoader use
|
||||
|
||||
var texturePath = this.texturePath || THREE.Loader.prototype.extractUrlBase( url );
|
||||
var binaryPath = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url );
|
||||
|
||||
// #1 load JS part via web worker
|
||||
|
||||
var scope = this;
|
||||
|
||||
var jsonloader = new THREE.FileLoader( this.manager );
|
||||
jsonloader.load( url, function ( data ) {
|
||||
|
||||
var json = JSON.parse( data );
|
||||
|
||||
var bufferUrl = binaryPath + json.buffers;
|
||||
|
||||
var bufferLoader = new THREE.FileLoader( scope.manager );
|
||||
bufferLoader.setResponseType( 'arraybuffer' );
|
||||
bufferLoader.load( bufferUrl, function ( bufData ) {
|
||||
|
||||
// IEWEBGL needs this ???
|
||||
//buffer = ( new Uint8Array( xhr.responseBody ) ).buffer;
|
||||
|
||||
//// iOS and other XMLHttpRequest level 1 ???
|
||||
|
||||
scope.parse( bufData, onLoad, texturePath, json.materials );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
setBinaryPath: function ( value ) {
|
||||
|
||||
this.binaryPath = value;
|
||||
|
||||
},
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
|
||||
},
|
||||
|
||||
setTexturePath: function ( value ) {
|
||||
|
||||
this.texturePath = value;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data, callback, texturePath, jsonMaterials ) {
|
||||
|
||||
var Model = function ( texturePath ) {
|
||||
|
||||
var scope = this,
|
||||
currentOffset = 0,
|
||||
md,
|
||||
normals = [],
|
||||
uvs = [],
|
||||
start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
|
||||
start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
|
||||
tri_size, quad_size,
|
||||
len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
|
||||
len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
|
||||
|
||||
|
||||
THREE.Geometry.call( this );
|
||||
|
||||
md = parseMetaData( data, currentOffset );
|
||||
|
||||
currentOffset += md.header_bytes;
|
||||
/*
|
||||
md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
|
||||
md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
|
||||
md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
|
||||
md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
|
||||
*/
|
||||
// buffers sizes
|
||||
|
||||
tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes;
|
||||
quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
|
||||
|
||||
len_tri_flat = md.ntri_flat * ( tri_size );
|
||||
len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 );
|
||||
len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 );
|
||||
len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
|
||||
|
||||
len_quad_flat = md.nquad_flat * ( quad_size );
|
||||
len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 );
|
||||
len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 );
|
||||
len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
|
||||
|
||||
// read buffers
|
||||
|
||||
currentOffset += init_vertices( currentOffset );
|
||||
|
||||
currentOffset += init_normals( currentOffset );
|
||||
currentOffset += handlePadding( md.nnormals * 3 );
|
||||
|
||||
currentOffset += init_uvs( currentOffset );
|
||||
|
||||
start_tri_flat = currentOffset;
|
||||
start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 );
|
||||
start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 );
|
||||
start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
|
||||
|
||||
start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 );
|
||||
start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 );
|
||||
start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 );
|
||||
start_quad_smooth_uv = start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 );
|
||||
|
||||
// have to first process faces with uvs
|
||||
// so that face and uv indices match
|
||||
|
||||
init_triangles_flat_uv( start_tri_flat_uv );
|
||||
init_triangles_smooth_uv( start_tri_smooth_uv );
|
||||
|
||||
init_quads_flat_uv( start_quad_flat_uv );
|
||||
init_quads_smooth_uv( start_quad_smooth_uv );
|
||||
|
||||
// now we can process untextured faces
|
||||
|
||||
init_triangles_flat( start_tri_flat );
|
||||
init_triangles_smooth( start_tri_smooth );
|
||||
|
||||
init_quads_flat( start_quad_flat );
|
||||
init_quads_smooth( start_quad_smooth );
|
||||
|
||||
this.computeFaceNormals();
|
||||
|
||||
function handlePadding( n ) {
|
||||
|
||||
return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
|
||||
|
||||
}
|
||||
|
||||
function parseMetaData( data, offset ) {
|
||||
|
||||
var metaData = {
|
||||
|
||||
'signature' : parseString( data, offset, 12 ),
|
||||
'header_bytes' : parseUChar8( data, offset + 12 ),
|
||||
|
||||
'vertex_coordinate_bytes' : parseUChar8( data, offset + 13 ),
|
||||
'normal_coordinate_bytes' : parseUChar8( data, offset + 14 ),
|
||||
'uv_coordinate_bytes' : parseUChar8( data, offset + 15 ),
|
||||
|
||||
'vertex_index_bytes' : parseUChar8( data, offset + 16 ),
|
||||
'normal_index_bytes' : parseUChar8( data, offset + 17 ),
|
||||
'uv_index_bytes' : parseUChar8( data, offset + 18 ),
|
||||
'material_index_bytes' : parseUChar8( data, offset + 19 ),
|
||||
|
||||
'nvertices' : parseUInt32( data, offset + 20 ),
|
||||
'nnormals' : parseUInt32( data, offset + 20 + 4 * 1 ),
|
||||
'nuvs' : parseUInt32( data, offset + 20 + 4 * 2 ),
|
||||
|
||||
'ntri_flat' : parseUInt32( data, offset + 20 + 4 * 3 ),
|
||||
'ntri_smooth' : parseUInt32( data, offset + 20 + 4 * 4 ),
|
||||
'ntri_flat_uv' : parseUInt32( data, offset + 20 + 4 * 5 ),
|
||||
'ntri_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 6 ),
|
||||
|
||||
'nquad_flat' : parseUInt32( data, offset + 20 + 4 * 7 ),
|
||||
'nquad_smooth' : parseUInt32( data, offset + 20 + 4 * 8 ),
|
||||
'nquad_flat_uv' : parseUInt32( data, offset + 20 + 4 * 9 ),
|
||||
'nquad_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 10 )
|
||||
|
||||
};
|
||||
/*
|
||||
console.log( "signature: " + metaData.signature );
|
||||
|
||||
console.log( "header_bytes: " + metaData.header_bytes );
|
||||
console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
|
||||
console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
|
||||
console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
|
||||
|
||||
console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
|
||||
console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
|
||||
console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
|
||||
console.log( "material_index_bytes: " + metaData.material_index_bytes );
|
||||
|
||||
console.log( "nvertices: " + metaData.nvertices );
|
||||
console.log( "nnormals: " + metaData.nnormals );
|
||||
console.log( "nuvs: " + metaData.nuvs );
|
||||
|
||||
console.log( "ntri_flat: " + metaData.ntri_flat );
|
||||
console.log( "ntri_smooth: " + metaData.ntri_smooth );
|
||||
console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
|
||||
console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
|
||||
|
||||
console.log( "nquad_flat: " + metaData.nquad_flat );
|
||||
console.log( "nquad_smooth: " + metaData.nquad_smooth );
|
||||
console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
|
||||
console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
|
||||
|
||||
var total = metaData.header_bytes
|
||||
+ metaData.nvertices * metaData.vertex_coordinate_bytes * 3
|
||||
+ metaData.nnormals * metaData.normal_coordinate_bytes * 3
|
||||
+ metaData.nuvs * metaData.uv_coordinate_bytes * 2
|
||||
+ metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
|
||||
+ metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
|
||||
+ metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
|
||||
+ metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
|
||||
+ metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
|
||||
+ metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
|
||||
+ metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
|
||||
+ metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
|
||||
console.log( "total bytes: " + total );
|
||||
*/
|
||||
|
||||
return metaData;
|
||||
|
||||
}
|
||||
|
||||
function parseString( data, offset, length ) {
|
||||
|
||||
var charArray = new Uint8Array( data, offset, length );
|
||||
|
||||
var text = "";
|
||||
|
||||
for ( var i = 0; i < length; i ++ ) {
|
||||
|
||||
text += String.fromCharCode( charArray[ offset + i ] );
|
||||
|
||||
}
|
||||
|
||||
return text;
|
||||
|
||||
}
|
||||
|
||||
function parseUChar8( data, offset ) {
|
||||
|
||||
var charArray = new Uint8Array( data, offset, 1 );
|
||||
|
||||
return charArray[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
function parseUInt32( data, offset ) {
|
||||
|
||||
var intArray = new Uint32Array( data, offset, 1 );
|
||||
|
||||
return intArray[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
function init_vertices( start ) {
|
||||
|
||||
var nElements = md.nvertices;
|
||||
|
||||
var coordArray = new Float32Array( data, start, nElements * 3 );
|
||||
|
||||
var i, x, y, z;
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
x = coordArray[ i * 3 ];
|
||||
y = coordArray[ i * 3 + 1 ];
|
||||
z = coordArray[ i * 3 + 2 ];
|
||||
|
||||
scope.vertices.push( new THREE.Vector3( x, y, z ) );
|
||||
|
||||
}
|
||||
|
||||
return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
function init_normals( start ) {
|
||||
|
||||
var nElements = md.nnormals;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var normalArray = new Int8Array( data, start, nElements * 3 );
|
||||
|
||||
var i, x, y, z;
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
x = normalArray[ i * 3 ];
|
||||
y = normalArray[ i * 3 + 1 ];
|
||||
z = normalArray[ i * 3 + 2 ];
|
||||
|
||||
normals.push( x / 127, y / 127, z / 127 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
function init_uvs( start ) {
|
||||
|
||||
var nElements = md.nuvs;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var uvArray = new Float32Array( data, start, nElements * 2 );
|
||||
|
||||
var i, u, v;
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
u = uvArray[ i * 2 ];
|
||||
v = uvArray[ i * 2 + 1 ];
|
||||
|
||||
uvs.push( u, v );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
function init_uvs3( nElements, offset ) {
|
||||
|
||||
var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
|
||||
|
||||
var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
uva = uvIndexBuffer[ i * 3 ];
|
||||
uvb = uvIndexBuffer[ i * 3 + 1 ];
|
||||
uvc = uvIndexBuffer[ i * 3 + 2 ];
|
||||
|
||||
u1 = uvs[ uva * 2 ];
|
||||
v1 = uvs[ uva * 2 + 1 ];
|
||||
|
||||
u2 = uvs[ uvb * 2 ];
|
||||
v2 = uvs[ uvb * 2 + 1 ];
|
||||
|
||||
u3 = uvs[ uvc * 2 ];
|
||||
v3 = uvs[ uvc * 2 + 1 ];
|
||||
|
||||
scope.faceVertexUvs[ 0 ].push( [
|
||||
new THREE.Vector2( u1, v1 ),
|
||||
new THREE.Vector2( u2, v2 ),
|
||||
new THREE.Vector2( u3, v3 )
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_uvs4( nElements, offset ) {
|
||||
|
||||
var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
|
||||
|
||||
var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
uva = uvIndexBuffer[ i * 4 ];
|
||||
uvb = uvIndexBuffer[ i * 4 + 1 ];
|
||||
uvc = uvIndexBuffer[ i * 4 + 2 ];
|
||||
uvd = uvIndexBuffer[ i * 4 + 3 ];
|
||||
|
||||
u1 = uvs[ uva * 2 ];
|
||||
v1 = uvs[ uva * 2 + 1 ];
|
||||
|
||||
u2 = uvs[ uvb * 2 ];
|
||||
v2 = uvs[ uvb * 2 + 1 ];
|
||||
|
||||
u3 = uvs[ uvc * 2 ];
|
||||
v3 = uvs[ uvc * 2 + 1 ];
|
||||
|
||||
u4 = uvs[ uvd * 2 ];
|
||||
v4 = uvs[ uvd * 2 + 1 ];
|
||||
|
||||
scope.faceVertexUvs[ 0 ].push( [
|
||||
new THREE.Vector2( u1, v1 ),
|
||||
new THREE.Vector2( u2, v2 ),
|
||||
new THREE.Vector2( u4, v4 )
|
||||
] );
|
||||
|
||||
scope.faceVertexUvs[ 0 ].push( [
|
||||
new THREE.Vector2( u2, v2 ),
|
||||
new THREE.Vector2( u3, v3 ),
|
||||
new THREE.Vector2( u4, v4 )
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
|
||||
|
||||
var i, a, b, c, m;
|
||||
|
||||
var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
|
||||
var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
a = vertexIndexBuffer[ i * 3 ];
|
||||
b = vertexIndexBuffer[ i * 3 + 1 ];
|
||||
c = vertexIndexBuffer[ i * 3 + 2 ];
|
||||
|
||||
m = materialIndexBuffer[ i ];
|
||||
|
||||
scope.faces.push( new THREE.Face3( a, b, c, null, null, m ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
|
||||
|
||||
var i, a, b, c, d, m;
|
||||
|
||||
var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
|
||||
var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
a = vertexIndexBuffer[ i * 4 ];
|
||||
b = vertexIndexBuffer[ i * 4 + 1 ];
|
||||
c = vertexIndexBuffer[ i * 4 + 2 ];
|
||||
d = vertexIndexBuffer[ i * 4 + 3 ];
|
||||
|
||||
m = materialIndexBuffer[ i ];
|
||||
|
||||
scope.faces.push( new THREE.Face3( a, b, d, null, null, m ) );
|
||||
scope.faces.push( new THREE.Face3( b, c, d, null, null, m ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
|
||||
|
||||
var i, a, b, c, m;
|
||||
var na, nb, nc;
|
||||
|
||||
var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
|
||||
var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
|
||||
var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
a = vertexIndexBuffer[ i * 3 ];
|
||||
b = vertexIndexBuffer[ i * 3 + 1 ];
|
||||
c = vertexIndexBuffer[ i * 3 + 2 ];
|
||||
|
||||
na = normalIndexBuffer[ i * 3 ];
|
||||
nb = normalIndexBuffer[ i * 3 + 1 ];
|
||||
nc = normalIndexBuffer[ i * 3 + 2 ];
|
||||
|
||||
m = materialIndexBuffer[ i ];
|
||||
|
||||
var nax = normals[ na * 3 ],
|
||||
nay = normals[ na * 3 + 1 ],
|
||||
naz = normals[ na * 3 + 2 ],
|
||||
|
||||
nbx = normals[ nb * 3 ],
|
||||
nby = normals[ nb * 3 + 1 ],
|
||||
nbz = normals[ nb * 3 + 2 ],
|
||||
|
||||
ncx = normals[ nc * 3 ],
|
||||
ncy = normals[ nc * 3 + 1 ],
|
||||
ncz = normals[ nc * 3 + 2 ];
|
||||
|
||||
scope.faces.push( new THREE.Face3( a, b, c, [
|
||||
new THREE.Vector3( nax, nay, naz ),
|
||||
new THREE.Vector3( nbx, nby, nbz ),
|
||||
new THREE.Vector3( ncx, ncy, ncz )
|
||||
], null, m ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
|
||||
|
||||
var i, a, b, c, d, m;
|
||||
var na, nb, nc, nd;
|
||||
|
||||
var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
|
||||
var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
|
||||
var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
|
||||
|
||||
for ( i = 0; i < nElements; i ++ ) {
|
||||
|
||||
a = vertexIndexBuffer[ i * 4 ];
|
||||
b = vertexIndexBuffer[ i * 4 + 1 ];
|
||||
c = vertexIndexBuffer[ i * 4 + 2 ];
|
||||
d = vertexIndexBuffer[ i * 4 + 3 ];
|
||||
|
||||
na = normalIndexBuffer[ i * 4 ];
|
||||
nb = normalIndexBuffer[ i * 4 + 1 ];
|
||||
nc = normalIndexBuffer[ i * 4 + 2 ];
|
||||
nd = normalIndexBuffer[ i * 4 + 3 ];
|
||||
|
||||
m = materialIndexBuffer[ i ];
|
||||
|
||||
var nax = normals[ na * 3 ],
|
||||
nay = normals[ na * 3 + 1 ],
|
||||
naz = normals[ na * 3 + 2 ],
|
||||
|
||||
nbx = normals[ nb * 3 ],
|
||||
nby = normals[ nb * 3 + 1 ],
|
||||
nbz = normals[ nb * 3 + 2 ],
|
||||
|
||||
ncx = normals[ nc * 3 ],
|
||||
ncy = normals[ nc * 3 + 1 ],
|
||||
ncz = normals[ nc * 3 + 2 ],
|
||||
|
||||
ndx = normals[ nd * 3 ],
|
||||
ndy = normals[ nd * 3 + 1 ],
|
||||
ndz = normals[ nd * 3 + 2 ];
|
||||
|
||||
scope.faces.push( new THREE.Face3( a, b, d, [
|
||||
new THREE.Vector3( nax, nay, naz ),
|
||||
new THREE.Vector3( nbx, nby, nbz ),
|
||||
new THREE.Vector3( ndx, ndy, ndz )
|
||||
], null, m ) );
|
||||
|
||||
scope.faces.push( new THREE.Face3( b, c, d, [
|
||||
new THREE.Vector3( nbx, nby, nbz ),
|
||||
new THREE.Vector3( ncx, ncy, ncz ),
|
||||
new THREE.Vector3( ndx, ndy, ndz )
|
||||
], null, m ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_triangles_flat( start ) {
|
||||
|
||||
var nElements = md.ntri_flat;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
init_faces3_flat( nElements, start, offsetMaterials );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_triangles_flat_uv( start ) {
|
||||
|
||||
var nElements = md.ntri_flat_uv;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
|
||||
init_faces3_flat( nElements, start, offsetMaterials );
|
||||
init_uvs3( nElements, offsetUvs );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_triangles_smooth( start ) {
|
||||
|
||||
var nElements = md.ntri_smooth;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
|
||||
init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_triangles_smooth_uv( start ) {
|
||||
|
||||
var nElements = md.ntri_smooth_uv;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
|
||||
|
||||
init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
|
||||
init_uvs3( nElements, offsetUvs );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_quads_flat( start ) {
|
||||
|
||||
var nElements = md.nquad_flat;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
init_faces4_flat( nElements, start, offsetMaterials );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_quads_flat_uv( start ) {
|
||||
|
||||
var nElements = md.nquad_flat_uv;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
|
||||
init_faces4_flat( nElements, start, offsetMaterials );
|
||||
init_uvs4( nElements, offsetUvs );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_quads_smooth( start ) {
|
||||
|
||||
var nElements = md.nquad_smooth;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
|
||||
init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init_quads_smooth_uv( start ) {
|
||||
|
||||
var nElements = md.nquad_smooth_uv;
|
||||
|
||||
if ( nElements ) {
|
||||
|
||||
var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
|
||||
|
||||
init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
|
||||
init_uvs4( nElements, offsetUvs );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Model.prototype = Object.create( THREE.Geometry.prototype );
|
||||
Model.prototype.constructor = Model;
|
||||
|
||||
var geometry = new Model( texturePath );
|
||||
var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
|
||||
|
||||
callback( geometry, materials );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
5545
node_modules/three/examples/js/loaders/ColladaLoader.js
generated
vendored
Normal file
5545
node_modules/three/examples/js/loaders/ColladaLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1594
node_modules/three/examples/js/loaders/ColladaLoader2.js
generated
vendored
Normal file
1594
node_modules/three/examples/js/loaders/ColladaLoader2.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
269
node_modules/three/examples/js/loaders/DDSLoader.js
generated
vendored
Normal file
269
node_modules/three/examples/js/loaders/DDSLoader.js
generated
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.DDSLoader = function () {
|
||||
|
||||
this._parser = THREE.DDSLoader.parse;
|
||||
|
||||
};
|
||||
|
||||
THREE.DDSLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype );
|
||||
THREE.DDSLoader.prototype.constructor = THREE.DDSLoader;
|
||||
|
||||
THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
|
||||
|
||||
var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
|
||||
|
||||
// Adapted from @toji's DDS utils
|
||||
// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
|
||||
|
||||
// All values and structures referenced from:
|
||||
// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
|
||||
|
||||
var DDS_MAGIC = 0x20534444;
|
||||
|
||||
var DDSD_CAPS = 0x1,
|
||||
DDSD_HEIGHT = 0x2,
|
||||
DDSD_WIDTH = 0x4,
|
||||
DDSD_PITCH = 0x8,
|
||||
DDSD_PIXELFORMAT = 0x1000,
|
||||
DDSD_MIPMAPCOUNT = 0x20000,
|
||||
DDSD_LINEARSIZE = 0x80000,
|
||||
DDSD_DEPTH = 0x800000;
|
||||
|
||||
var DDSCAPS_COMPLEX = 0x8,
|
||||
DDSCAPS_MIPMAP = 0x400000,
|
||||
DDSCAPS_TEXTURE = 0x1000;
|
||||
|
||||
var DDSCAPS2_CUBEMAP = 0x200,
|
||||
DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
|
||||
DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
|
||||
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
|
||||
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
|
||||
DDSCAPS2_VOLUME = 0x200000;
|
||||
|
||||
var DDPF_ALPHAPIXELS = 0x1,
|
||||
DDPF_ALPHA = 0x2,
|
||||
DDPF_FOURCC = 0x4,
|
||||
DDPF_RGB = 0x40,
|
||||
DDPF_YUV = 0x200,
|
||||
DDPF_LUMINANCE = 0x20000;
|
||||
|
||||
function fourCCToInt32( value ) {
|
||||
|
||||
return value.charCodeAt( 0 ) +
|
||||
( value.charCodeAt( 1 ) << 8 ) +
|
||||
( value.charCodeAt( 2 ) << 16 ) +
|
||||
( value.charCodeAt( 3 ) << 24 );
|
||||
|
||||
}
|
||||
|
||||
function int32ToFourCC( value ) {
|
||||
|
||||
return String.fromCharCode(
|
||||
value & 0xff,
|
||||
( value >> 8 ) & 0xff,
|
||||
( value >> 16 ) & 0xff,
|
||||
( value >> 24 ) & 0xff
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function loadARGBMip( buffer, dataOffset, width, height ) {
|
||||
|
||||
var dataLength = width * height * 4;
|
||||
var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
|
||||
var byteArray = new Uint8Array( dataLength );
|
||||
var dst = 0;
|
||||
var src = 0;
|
||||
for ( var y = 0; y < height; y ++ ) {
|
||||
|
||||
for ( var x = 0; x < width; x ++ ) {
|
||||
|
||||
var b = srcBuffer[ src ]; src ++;
|
||||
var g = srcBuffer[ src ]; src ++;
|
||||
var r = srcBuffer[ src ]; src ++;
|
||||
var a = srcBuffer[ src ]; src ++;
|
||||
byteArray[ dst ] = r; dst ++; //r
|
||||
byteArray[ dst ] = g; dst ++; //g
|
||||
byteArray[ dst ] = b; dst ++; //b
|
||||
byteArray[ dst ] = a; dst ++; //a
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return byteArray;
|
||||
|
||||
}
|
||||
|
||||
var FOURCC_DXT1 = fourCCToInt32( "DXT1" );
|
||||
var FOURCC_DXT3 = fourCCToInt32( "DXT3" );
|
||||
var FOURCC_DXT5 = fourCCToInt32( "DXT5" );
|
||||
var FOURCC_ETC1 = fourCCToInt32( "ETC1" );
|
||||
|
||||
var headerLengthInt = 31; // The header length in 32 bit ints
|
||||
|
||||
// Offsets into the header array
|
||||
|
||||
var off_magic = 0;
|
||||
|
||||
var off_size = 1;
|
||||
var off_flags = 2;
|
||||
var off_height = 3;
|
||||
var off_width = 4;
|
||||
|
||||
var off_mipmapCount = 7;
|
||||
|
||||
var off_pfFlags = 20;
|
||||
var off_pfFourCC = 21;
|
||||
var off_RGBBitCount = 22;
|
||||
var off_RBitMask = 23;
|
||||
var off_GBitMask = 24;
|
||||
var off_BBitMask = 25;
|
||||
var off_ABitMask = 26;
|
||||
|
||||
var off_caps = 27;
|
||||
var off_caps2 = 28;
|
||||
var off_caps3 = 29;
|
||||
var off_caps4 = 30;
|
||||
|
||||
// Parse header
|
||||
|
||||
var header = new Int32Array( buffer, 0, headerLengthInt );
|
||||
|
||||
if ( header[ off_magic ] !== DDS_MAGIC ) {
|
||||
|
||||
console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' );
|
||||
return dds;
|
||||
|
||||
}
|
||||
|
||||
if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
|
||||
|
||||
console.error( 'THREE.DDSLoader.parse: Unsupported format, must contain a FourCC code.' );
|
||||
return dds;
|
||||
|
||||
}
|
||||
|
||||
var blockBytes;
|
||||
|
||||
var fourCC = header[ off_pfFourCC ];
|
||||
|
||||
var isRGBAUncompressed = false;
|
||||
|
||||
switch ( fourCC ) {
|
||||
|
||||
case FOURCC_DXT1:
|
||||
|
||||
blockBytes = 8;
|
||||
dds.format = THREE.RGB_S3TC_DXT1_Format;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT3:
|
||||
|
||||
blockBytes = 16;
|
||||
dds.format = THREE.RGBA_S3TC_DXT3_Format;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT5:
|
||||
|
||||
blockBytes = 16;
|
||||
dds.format = THREE.RGBA_S3TC_DXT5_Format;
|
||||
break;
|
||||
|
||||
case FOURCC_ETC1:
|
||||
|
||||
blockBytes = 8;
|
||||
dds.format = THREE.RGB_ETC1_Format;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if ( header[ off_RGBBitCount ] === 32
|
||||
&& header[ off_RBitMask ] & 0xff0000
|
||||
&& header[ off_GBitMask ] & 0xff00
|
||||
&& header[ off_BBitMask ] & 0xff
|
||||
&& header[ off_ABitMask ] & 0xff000000 ) {
|
||||
|
||||
isRGBAUncompressed = true;
|
||||
blockBytes = 64;
|
||||
dds.format = THREE.RGBAFormat;
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) );
|
||||
return dds;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
dds.mipmapCount = 1;
|
||||
|
||||
if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
|
||||
|
||||
dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
|
||||
|
||||
}
|
||||
|
||||
var caps2 = header[ off_caps2 ];
|
||||
dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
|
||||
if ( dds.isCubemap && (
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
|
||||
! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
|
||||
) ) {
|
||||
|
||||
console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
|
||||
return dds;
|
||||
|
||||
}
|
||||
|
||||
dds.width = header[ off_width ];
|
||||
dds.height = header[ off_height ];
|
||||
|
||||
var dataOffset = header[ off_size ] + 4;
|
||||
|
||||
// Extract mipmaps buffers
|
||||
|
||||
var faces = dds.isCubemap ? 6 : 1;
|
||||
|
||||
for ( var face = 0; face < faces; face ++ ) {
|
||||
|
||||
var width = dds.width;
|
||||
var height = dds.height;
|
||||
|
||||
for ( var i = 0; i < dds.mipmapCount; i ++ ) {
|
||||
|
||||
if ( isRGBAUncompressed ) {
|
||||
|
||||
var byteArray = loadARGBMip( buffer, dataOffset, width, height );
|
||||
var dataLength = byteArray.length;
|
||||
|
||||
} else {
|
||||
|
||||
var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
|
||||
var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
|
||||
|
||||
}
|
||||
|
||||
var mipmap = { "data": byteArray, "width": width, "height": height };
|
||||
dds.mipmaps.push( mipmap );
|
||||
|
||||
dataOffset += dataLength;
|
||||
|
||||
width = Math.max( width >> 1, 1 );
|
||||
height = Math.max( height >> 1, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return dds;
|
||||
|
||||
};
|
||||
3241
node_modules/three/examples/js/loaders/FBXLoader.js
generated
vendored
Normal file
3241
node_modules/three/examples/js/loaders/FBXLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3860
node_modules/three/examples/js/loaders/FBXLoader2.js
generated
vendored
Normal file
3860
node_modules/three/examples/js/loaders/FBXLoader2.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2150
node_modules/three/examples/js/loaders/GLTFLoader.js
generated
vendored
Normal file
2150
node_modules/three/examples/js/loaders/GLTFLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
186
node_modules/three/examples/js/loaders/HDRCubeTextureLoader.js
generated
vendored
Normal file
186
node_modules/three/examples/js/loaders/HDRCubeTextureLoader.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @author Prashant Sharma / spidersharma03
|
||||
* @author Ben Houston / http://clara.io / bhouston
|
||||
*/
|
||||
|
||||
THREE.HDRCubeTextureLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
// override in sub classes
|
||||
this.hdrLoader = new THREE.RGBELoader();
|
||||
|
||||
};
|
||||
|
||||
THREE.HDRCubeTextureLoader.prototype.load = function ( type, urls, onLoad, onProgress, onError ) {
|
||||
|
||||
var RGBEByteToRGBFloat = function ( sourceArray, sourceOffset, destArray, destOffset ) {
|
||||
|
||||
var e = sourceArray[ sourceOffset + 3 ];
|
||||
var scale = Math.pow( 2.0, e - 128.0 ) / 255.0;
|
||||
|
||||
destArray[ destOffset + 0 ] = sourceArray[ sourceOffset + 0 ] * scale;
|
||||
destArray[ destOffset + 1 ] = sourceArray[ sourceOffset + 1 ] * scale;
|
||||
destArray[ destOffset + 2 ] = sourceArray[ sourceOffset + 2 ] * scale;
|
||||
|
||||
};
|
||||
|
||||
var RGBEByteToRGBHalf = ( function () {
|
||||
|
||||
// Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
|
||||
|
||||
var floatView = new Float32Array( 1 );
|
||||
var int32View = new Int32Array( floatView.buffer );
|
||||
|
||||
/* This method is faster than the OpenEXR implementation (very often
|
||||
* used, eg. in Ogre), with the additional benefit of rounding, inspired
|
||||
* by James Tursa?s half-precision code. */
|
||||
function toHalf( val ) {
|
||||
|
||||
floatView[ 0 ] = val;
|
||||
var x = int32View[ 0 ];
|
||||
|
||||
var bits = ( x >> 16 ) & 0x8000; /* Get the sign */
|
||||
var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */
|
||||
var e = ( x >> 23 ) & 0xff; /* Using int is faster here */
|
||||
|
||||
/* If zero, or denormal, or exponent underflows too much for a denormal
|
||||
* half, return signed zero. */
|
||||
if ( e < 103 ) return bits;
|
||||
|
||||
/* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
|
||||
if ( e > 142 ) {
|
||||
|
||||
bits |= 0x7c00;
|
||||
/* If exponent was 0xff and one mantissa bit was set, it means NaN,
|
||||
* not Inf, so make sure we set one mantissa bit too. */
|
||||
bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff );
|
||||
return bits;
|
||||
|
||||
}
|
||||
|
||||
/* If exponent underflows but not too much, return a denormal */
|
||||
if ( e < 113 ) {
|
||||
|
||||
m |= 0x0800;
|
||||
/* Extra rounding may overflow and set mantissa to 0 and exponent
|
||||
* to 1, which is OK. */
|
||||
bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 );
|
||||
return bits;
|
||||
|
||||
}
|
||||
|
||||
bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 );
|
||||
/* Extra rounding. An overflow will set mantissa to 0 and increment
|
||||
* the exponent, which is OK. */
|
||||
bits += m & 1;
|
||||
return bits;
|
||||
|
||||
}
|
||||
|
||||
return function ( sourceArray, sourceOffset, destArray, destOffset ) {
|
||||
|
||||
var e = sourceArray[ sourceOffset + 3 ];
|
||||
var scale = Math.pow( 2.0, e - 128.0 ) / 255.0;
|
||||
|
||||
destArray[ destOffset + 0 ] = toHalf( sourceArray[ sourceOffset + 0 ] * scale );
|
||||
destArray[ destOffset + 1 ] = toHalf( sourceArray[ sourceOffset + 1 ] * scale );
|
||||
destArray[ destOffset + 2 ] = toHalf( sourceArray[ sourceOffset + 2 ] * scale );
|
||||
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
//
|
||||
|
||||
var texture = new THREE.CubeTexture();
|
||||
|
||||
texture.type = type;
|
||||
texture.encoding = ( type === THREE.UnsignedByteType ) ? THREE.RGBEEncoding : THREE.LinearEncoding;
|
||||
texture.format = ( type === THREE.UnsignedByteType ) ? THREE.RGBAFormat : THREE.RGBFormat;
|
||||
texture.minFilter = ( texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
|
||||
texture.magFilter = ( texture.encoding === THREE.RGBEEncoding ) ? THREE.NearestFilter : THREE.LinearFilter;
|
||||
texture.generateMipmaps = ( texture.encoding !== THREE.RGBEEncoding );
|
||||
texture.anisotropy = 0;
|
||||
|
||||
var scope = this.hdrLoader;
|
||||
|
||||
var loaded = 0;
|
||||
|
||||
function loadHDRData( i, onLoad, onProgress, onError ) {
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( urls[ i ], function ( buffer ) {
|
||||
|
||||
loaded ++;
|
||||
|
||||
var texData = scope._parser( buffer );
|
||||
|
||||
if ( ! texData ) return;
|
||||
|
||||
if ( type === THREE.FloatType ) {
|
||||
|
||||
var numElements = ( texData.data.length / 4 ) * 3;
|
||||
var floatdata = new Float32Array( numElements );
|
||||
|
||||
for ( var j = 0; j < numElements; j ++ ) {
|
||||
|
||||
RGBEByteToRGBFloat( texData.data, j * 4, floatdata, j * 3 );
|
||||
|
||||
}
|
||||
|
||||
texData.data = floatdata;
|
||||
|
||||
} else if ( type === THREE.HalfFloatType ) {
|
||||
|
||||
var numElements = ( texData.data.length / 4 ) * 3;
|
||||
var halfdata = new Uint16Array( numElements );
|
||||
|
||||
for ( var j = 0; j < numElements; j ++ ) {
|
||||
|
||||
RGBEByteToRGBHalf( texData.data, j * 4, halfdata, j * 3 );
|
||||
|
||||
}
|
||||
|
||||
texData.data = halfdata;
|
||||
|
||||
}
|
||||
|
||||
if ( undefined !== texData.image ) {
|
||||
|
||||
texture[ i ].images = texData.image;
|
||||
|
||||
} else if ( undefined !== texData.data ) {
|
||||
|
||||
var dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height );
|
||||
dataTexture.format = texture.format;
|
||||
dataTexture.type = texture.type;
|
||||
dataTexture.encoding = texture.encoding;
|
||||
dataTexture.minFilter = texture.minFilter;
|
||||
dataTexture.magFilter = texture.magFilter;
|
||||
dataTexture.generateMipmaps = texture.generateMipmaps;
|
||||
|
||||
texture.images[ i ] = dataTexture;
|
||||
|
||||
}
|
||||
|
||||
if ( loaded === 6 ) {
|
||||
|
||||
texture.needsUpdate = true;
|
||||
if ( onLoad ) onLoad( texture );
|
||||
|
||||
}
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < urls.length; i ++ ) {
|
||||
|
||||
loadHDRData( i, onLoad, onProgress, onError );
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
};
|
||||
91
node_modules/three/examples/js/loaders/KMZLoader.js
generated
vendored
Normal file
91
node_modules/three/examples/js/loaders/KMZLoader.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.KMZLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.KMZLoader.prototype = {
|
||||
|
||||
constructor: THREE.KMZLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
var zip = new JSZip( data );
|
||||
|
||||
// console.log( zip );
|
||||
|
||||
// var xml = new DOMParser().parseFromString( zip.file( 'doc.kml' ).asText(), 'application/xml' );
|
||||
|
||||
function loadImage( image ) {
|
||||
|
||||
var path = decodeURI( image.init_from );
|
||||
|
||||
// Hack to support relative paths
|
||||
path = path.replace( '../', '' );
|
||||
|
||||
var regex = new RegExp( path + '$' );
|
||||
var files = zip.file( regex );
|
||||
|
||||
// console.log( image, files );
|
||||
|
||||
if ( files.length ) {
|
||||
|
||||
var file = files[ 0 ];
|
||||
var blob = new Blob( [ file.asArrayBuffer() ], { type: 'application/octet-binary' } );
|
||||
image.build.src = URL.createObjectURL( blob );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// load collada
|
||||
|
||||
var files = zip.file( /dae$/i );
|
||||
|
||||
if ( files.length ) {
|
||||
|
||||
var file = files[ 0 ];
|
||||
|
||||
var collada = new THREE.ColladaLoader().parse( file.asText() );
|
||||
|
||||
// fix images
|
||||
|
||||
var images = collada.library.images;
|
||||
|
||||
for ( var name in images ) {
|
||||
|
||||
loadImage( images[ name ] );
|
||||
|
||||
}
|
||||
|
||||
return collada;
|
||||
|
||||
}
|
||||
|
||||
console.error( 'KMZLoader: Couldn\'t find .dae file.' );
|
||||
|
||||
return {
|
||||
scene: new THREE.Group()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
311
node_modules/three/examples/js/loaders/MD2Loader.js
generated
vendored
Normal file
311
node_modules/three/examples/js/loaders/MD2Loader.js
generated
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.MD2Loader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.MD2Loader.prototype = {
|
||||
|
||||
constructor: THREE.MD2Loader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( buffer ) {
|
||||
|
||||
onLoad( scope.parse( buffer ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: ( function () {
|
||||
|
||||
var normals = [
|
||||
[ -0.525731, 0.000000, 0.850651 ], [ -0.442863, 0.238856, 0.864188 ],
|
||||
[ -0.295242, 0.000000, 0.955423 ], [ -0.309017, 0.500000, 0.809017 ],
|
||||
[ -0.162460, 0.262866, 0.951056 ], [ 0.000000, 0.000000, 1.000000 ],
|
||||
[ 0.000000, 0.850651, 0.525731 ], [ -0.147621, 0.716567, 0.681718 ],
|
||||
[ 0.147621, 0.716567, 0.681718 ], [ 0.000000, 0.525731, 0.850651 ],
|
||||
[ 0.309017, 0.500000, 0.809017 ], [ 0.525731, 0.000000, 0.850651 ],
|
||||
[ 0.295242, 0.000000, 0.955423 ], [ 0.442863, 0.238856, 0.864188 ],
|
||||
[ 0.162460, 0.262866, 0.951056 ], [ -0.681718, 0.147621, 0.716567 ],
|
||||
[ -0.809017, 0.309017, 0.500000 ], [ -0.587785, 0.425325, 0.688191 ],
|
||||
[ -0.850651, 0.525731, 0.000000 ], [ -0.864188, 0.442863, 0.238856 ],
|
||||
[ -0.716567, 0.681718, 0.147621 ], [ -0.688191, 0.587785, 0.425325 ],
|
||||
[ -0.500000, 0.809017, 0.309017 ], [ -0.238856, 0.864188, 0.442863 ],
|
||||
[ -0.425325, 0.688191, 0.587785 ], [ -0.716567, 0.681718, -0.147621 ],
|
||||
[ -0.500000, 0.809017, -0.309017 ], [ -0.525731, 0.850651, 0.000000 ],
|
||||
[ 0.000000, 0.850651, -0.525731 ], [ -0.238856, 0.864188, -0.442863 ],
|
||||
[ 0.000000, 0.955423, -0.295242 ], [ -0.262866, 0.951056, -0.162460 ],
|
||||
[ 0.000000, 1.000000, 0.000000 ], [ 0.000000, 0.955423, 0.295242 ],
|
||||
[ -0.262866, 0.951056, 0.162460 ], [ 0.238856, 0.864188, 0.442863 ],
|
||||
[ 0.262866, 0.951056, 0.162460 ], [ 0.500000, 0.809017, 0.309017 ],
|
||||
[ 0.238856, 0.864188, -0.442863 ], [ 0.262866, 0.951056, -0.162460 ],
|
||||
[ 0.500000, 0.809017, -0.309017 ], [ 0.850651, 0.525731, 0.000000 ],
|
||||
[ 0.716567, 0.681718, 0.147621 ], [ 0.716567, 0.681718, -0.147621 ],
|
||||
[ 0.525731, 0.850651, 0.000000 ], [ 0.425325, 0.688191, 0.587785 ],
|
||||
[ 0.864188, 0.442863, 0.238856 ], [ 0.688191, 0.587785, 0.425325 ],
|
||||
[ 0.809017, 0.309017, 0.500000 ], [ 0.681718, 0.147621, 0.716567 ],
|
||||
[ 0.587785, 0.425325, 0.688191 ], [ 0.955423, 0.295242, 0.000000 ],
|
||||
[ 1.000000, 0.000000, 0.000000 ], [ 0.951056, 0.162460, 0.262866 ],
|
||||
[ 0.850651, -0.525731, 0.000000 ], [ 0.955423, -0.295242, 0.000000 ],
|
||||
[ 0.864188, -0.442863, 0.238856 ], [ 0.951056, -0.162460, 0.262866 ],
|
||||
[ 0.809017, -0.309017, 0.500000 ], [ 0.681718, -0.147621, 0.716567 ],
|
||||
[ 0.850651, 0.000000, 0.525731 ], [ 0.864188, 0.442863, -0.238856 ],
|
||||
[ 0.809017, 0.309017, -0.500000 ], [ 0.951056, 0.162460, -0.262866 ],
|
||||
[ 0.525731, 0.000000, -0.850651 ], [ 0.681718, 0.147621, -0.716567 ],
|
||||
[ 0.681718, -0.147621, -0.716567 ], [ 0.850651, 0.000000, -0.525731 ],
|
||||
[ 0.809017, -0.309017, -0.500000 ], [ 0.864188, -0.442863, -0.238856 ],
|
||||
[ 0.951056, -0.162460, -0.262866 ], [ 0.147621, 0.716567, -0.681718 ],
|
||||
[ 0.309017, 0.500000, -0.809017 ], [ 0.425325, 0.688191, -0.587785 ],
|
||||
[ 0.442863, 0.238856, -0.864188 ], [ 0.587785, 0.425325, -0.688191 ],
|
||||
[ 0.688191, 0.587785, -0.425325 ], [ -0.147621, 0.716567, -0.681718 ],
|
||||
[ -0.309017, 0.500000, -0.809017 ], [ 0.000000, 0.525731, -0.850651 ],
|
||||
[ -0.525731, 0.000000, -0.850651 ], [ -0.442863, 0.238856, -0.864188 ],
|
||||
[ -0.295242, 0.000000, -0.955423 ], [ -0.162460, 0.262866, -0.951056 ],
|
||||
[ 0.000000, 0.000000, -1.000000 ], [ 0.295242, 0.000000, -0.955423 ],
|
||||
[ 0.162460, 0.262866, -0.951056 ], [ -0.442863, -0.238856, -0.864188 ],
|
||||
[ -0.309017, -0.500000, -0.809017 ], [ -0.162460, -0.262866, -0.951056 ],
|
||||
[ 0.000000, -0.850651, -0.525731 ], [ -0.147621, -0.716567, -0.681718 ],
|
||||
[ 0.147621, -0.716567, -0.681718 ], [ 0.000000, -0.525731, -0.850651 ],
|
||||
[ 0.309017, -0.500000, -0.809017 ], [ 0.442863, -0.238856, -0.864188 ],
|
||||
[ 0.162460, -0.262866, -0.951056 ], [ 0.238856, -0.864188, -0.442863 ],
|
||||
[ 0.500000, -0.809017, -0.309017 ], [ 0.425325, -0.688191, -0.587785 ],
|
||||
[ 0.716567, -0.681718, -0.147621 ], [ 0.688191, -0.587785, -0.425325 ],
|
||||
[ 0.587785, -0.425325, -0.688191 ], [ 0.000000, -0.955423, -0.295242 ],
|
||||
[ 0.000000, -1.000000, 0.000000 ], [ 0.262866, -0.951056, -0.162460 ],
|
||||
[ 0.000000, -0.850651, 0.525731 ], [ 0.000000, -0.955423, 0.295242 ],
|
||||
[ 0.238856, -0.864188, 0.442863 ], [ 0.262866, -0.951056, 0.162460 ],
|
||||
[ 0.500000, -0.809017, 0.309017 ], [ 0.716567, -0.681718, 0.147621 ],
|
||||
[ 0.525731, -0.850651, 0.000000 ], [ -0.238856, -0.864188, -0.442863 ],
|
||||
[ -0.500000, -0.809017, -0.309017 ], [ -0.262866, -0.951056, -0.162460 ],
|
||||
[ -0.850651, -0.525731, 0.000000 ], [ -0.716567, -0.681718, -0.147621 ],
|
||||
[ -0.716567, -0.681718, 0.147621 ], [ -0.525731, -0.850651, 0.000000 ],
|
||||
[ -0.500000, -0.809017, 0.309017 ], [ -0.238856, -0.864188, 0.442863 ],
|
||||
[ -0.262866, -0.951056, 0.162460 ], [ -0.864188, -0.442863, 0.238856 ],
|
||||
[ -0.809017, -0.309017, 0.500000 ], [ -0.688191, -0.587785, 0.425325 ],
|
||||
[ -0.681718, -0.147621, 0.716567 ], [ -0.442863, -0.238856, 0.864188 ],
|
||||
[ -0.587785, -0.425325, 0.688191 ], [ -0.309017, -0.500000, 0.809017 ],
|
||||
[ -0.147621, -0.716567, 0.681718 ], [ -0.425325, -0.688191, 0.587785 ],
|
||||
[ -0.162460, -0.262866, 0.951056 ], [ 0.442863, -0.238856, 0.864188 ],
|
||||
[ 0.162460, -0.262866, 0.951056 ], [ 0.309017, -0.500000, 0.809017 ],
|
||||
[ 0.147621, -0.716567, 0.681718 ], [ 0.000000, -0.525731, 0.850651 ],
|
||||
[ 0.425325, -0.688191, 0.587785 ], [ 0.587785, -0.425325, 0.688191 ],
|
||||
[ 0.688191, -0.587785, 0.425325 ], [ -0.955423, 0.295242, 0.000000 ],
|
||||
[ -0.951056, 0.162460, 0.262866 ], [ -1.000000, 0.000000, 0.000000 ],
|
||||
[ -0.850651, 0.000000, 0.525731 ], [ -0.955423, -0.295242, 0.000000 ],
|
||||
[ -0.951056, -0.162460, 0.262866 ], [ -0.864188, 0.442863, -0.238856 ],
|
||||
[ -0.951056, 0.162460, -0.262866 ], [ -0.809017, 0.309017, -0.500000 ],
|
||||
[ -0.864188, -0.442863, -0.238856 ], [ -0.951056, -0.162460, -0.262866 ],
|
||||
[ -0.809017, -0.309017, -0.500000 ], [ -0.681718, 0.147621, -0.716567 ],
|
||||
[ -0.681718, -0.147621, -0.716567 ], [ -0.850651, 0.000000, -0.525731 ],
|
||||
[ -0.688191, 0.587785, -0.425325 ], [ -0.587785, 0.425325, -0.688191 ],
|
||||
[ -0.425325, 0.688191, -0.587785 ], [ -0.425325, -0.688191, -0.587785 ],
|
||||
[ -0.587785, -0.425325, -0.688191 ], [ -0.688191, -0.587785, -0.425325 ]
|
||||
];
|
||||
|
||||
return function ( buffer ) {
|
||||
|
||||
console.time( 'MD2Loader' );
|
||||
|
||||
var data = new DataView( buffer );
|
||||
|
||||
// http://tfc.duke.free.fr/coding/md2-specs-en.html
|
||||
|
||||
var header = {};
|
||||
var headerNames = [
|
||||
'ident', 'version',
|
||||
'skinwidth', 'skinheight',
|
||||
'framesize',
|
||||
'num_skins', 'num_vertices', 'num_st', 'num_tris', 'num_glcmds', 'num_frames',
|
||||
'offset_skins', 'offset_st', 'offset_tris', 'offset_frames', 'offset_glcmds', 'offset_end'
|
||||
];
|
||||
|
||||
for ( var i = 0; i < headerNames.length; i ++ ) {
|
||||
|
||||
header[ headerNames[ i ] ] = data.getInt32( i * 4, true );
|
||||
|
||||
}
|
||||
|
||||
if ( header.ident !== 844121161 || header.version !== 8 ) {
|
||||
|
||||
console.error( 'Not a valid MD2 file' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( header.offset_end !== data.byteLength ) {
|
||||
|
||||
console.error( 'Corrupted MD2 file' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var geometry = new THREE.Geometry();
|
||||
|
||||
// uvs
|
||||
|
||||
var uvs = [];
|
||||
var offset = header.offset_st;
|
||||
|
||||
for ( var i = 0, l = header.num_st; i < l; i ++ ) {
|
||||
|
||||
var u = data.getInt16( offset + 0, true );
|
||||
var v = data.getInt16( offset + 2, true );
|
||||
|
||||
uvs.push( new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) ) );
|
||||
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
|
||||
// triangles
|
||||
|
||||
var offset = header.offset_tris;
|
||||
|
||||
for ( var i = 0, l = header.num_tris; i < l; i ++ ) {
|
||||
|
||||
var a = data.getUint16( offset + 0, true );
|
||||
var b = data.getUint16( offset + 2, true );
|
||||
var c = data.getUint16( offset + 4, true );
|
||||
|
||||
geometry.faces.push( new THREE.Face3( a, b, c ) );
|
||||
|
||||
geometry.faceVertexUvs[ 0 ].push( [
|
||||
uvs[ data.getUint16( offset + 6, true ) ],
|
||||
uvs[ data.getUint16( offset + 8, true ) ],
|
||||
uvs[ data.getUint16( offset + 10, true ) ]
|
||||
] );
|
||||
|
||||
offset += 12;
|
||||
|
||||
}
|
||||
|
||||
// frames
|
||||
|
||||
var translation = new THREE.Vector3();
|
||||
var scale = new THREE.Vector3();
|
||||
var string = [];
|
||||
|
||||
var offset = header.offset_frames;
|
||||
|
||||
for ( var i = 0, l = header.num_frames; i < l; i ++ ) {
|
||||
|
||||
scale.set(
|
||||
data.getFloat32( offset + 0, true ),
|
||||
data.getFloat32( offset + 4, true ),
|
||||
data.getFloat32( offset + 8, true )
|
||||
);
|
||||
|
||||
translation.set(
|
||||
data.getFloat32( offset + 12, true ),
|
||||
data.getFloat32( offset + 16, true ),
|
||||
data.getFloat32( offset + 20, true )
|
||||
);
|
||||
|
||||
offset += 24;
|
||||
|
||||
for ( var j = 0; j < 16; j ++ ) {
|
||||
|
||||
var character = data.getUint8( offset + j, true );
|
||||
if ( character === 0 ) break;
|
||||
|
||||
string[ j ] = character;
|
||||
|
||||
}
|
||||
|
||||
var frame = {
|
||||
name: String.fromCharCode.apply( null, string ),
|
||||
vertices: [],
|
||||
normals: []
|
||||
};
|
||||
|
||||
offset += 16;
|
||||
|
||||
for ( var j = 0; j < header.num_vertices; j ++ ) {
|
||||
|
||||
var x = data.getUint8( offset ++, true );
|
||||
var y = data.getUint8( offset ++, true );
|
||||
var z = data.getUint8( offset ++, true );
|
||||
var n = normals[ data.getUint8( offset ++, true ) ];
|
||||
|
||||
var vertex = new THREE.Vector3(
|
||||
x * scale.x + translation.x,
|
||||
z * scale.z + translation.z,
|
||||
y * scale.y + translation.y
|
||||
);
|
||||
|
||||
var normal = new THREE.Vector3( n[ 0 ], n[ 2 ], n[ 1 ] );
|
||||
|
||||
frame.vertices.push( vertex );
|
||||
frame.normals.push( normal );
|
||||
|
||||
}
|
||||
|
||||
geometry.morphTargets.push( frame );
|
||||
|
||||
}
|
||||
|
||||
// Static
|
||||
|
||||
geometry.vertices = geometry.morphTargets[ 0 ].vertices;
|
||||
|
||||
var morphTarget = geometry.morphTargets[ 0 ];
|
||||
|
||||
for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
|
||||
|
||||
var face = geometry.faces[ j ];
|
||||
|
||||
face.vertexNormals = [
|
||||
morphTarget.normals[ face.a ],
|
||||
morphTarget.normals[ face.b ],
|
||||
morphTarget.normals[ face.c ]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Convert to geometry.morphNormals
|
||||
|
||||
for ( var i = 0, l = geometry.morphTargets.length; i < l; i ++ ) {
|
||||
|
||||
var morphTarget = geometry.morphTargets[ i ];
|
||||
var vertexNormals = [];
|
||||
|
||||
for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
|
||||
|
||||
var face = geometry.faces[ j ];
|
||||
|
||||
vertexNormals.push( {
|
||||
a: morphTarget.normals[ face.a ],
|
||||
b: morphTarget.normals[ face.b ],
|
||||
c: morphTarget.normals[ face.c ]
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
geometry.morphNormals.push( { vertexNormals: vertexNormals } );
|
||||
|
||||
}
|
||||
|
||||
geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
|
||||
|
||||
console.timeEnd( 'MD2Loader' );
|
||||
|
||||
return geometry;
|
||||
|
||||
};
|
||||
|
||||
} )()
|
||||
|
||||
};
|
||||
2737
node_modules/three/examples/js/loaders/MMDLoader.js
generated
vendored
Normal file
2737
node_modules/three/examples/js/loaders/MMDLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
540
node_modules/three/examples/js/loaders/MTLLoader.js
generated
vendored
Normal file
540
node_modules/three/examples/js/loaders/MTLLoader.js
generated
vendored
Normal file
@@ -0,0 +1,540 @@
|
||||
/**
|
||||
* Loads a Wavefront .mtl file specifying materials
|
||||
*
|
||||
* @author angelxuanchang
|
||||
*/
|
||||
|
||||
THREE.MTLLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.MTLLoader.prototype = {
|
||||
|
||||
constructor: THREE.MTLLoader,
|
||||
|
||||
/**
|
||||
* Loads and parses a MTL asset from a URL.
|
||||
*
|
||||
* @param {String} url - URL to the MTL file.
|
||||
* @param {Function} [onLoad] - Callback invoked with the loaded object.
|
||||
* @param {Function} [onProgress] - Callback for download progress.
|
||||
* @param {Function} [onError] - Callback for download errors.
|
||||
*
|
||||
* @see setPath setTexturePath
|
||||
*
|
||||
* @note In order for relative texture references to resolve correctly
|
||||
* you must call setPath and/or setTexturePath explicitly prior to load.
|
||||
*/
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setPath( this.path );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set base path for resolving references.
|
||||
* If set this path will be prepended to each loaded and found reference.
|
||||
*
|
||||
* @see setTexturePath
|
||||
* @param {String} path
|
||||
*
|
||||
* @example
|
||||
* mtlLoader.setPath( 'assets/obj/' );
|
||||
* mtlLoader.load( 'my.mtl', ... );
|
||||
*/
|
||||
setPath: function ( path ) {
|
||||
|
||||
this.path = path;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set base path for resolving texture references.
|
||||
* If set this path will be prepended found texture reference.
|
||||
* If not set and setPath is, it will be used as texture base path.
|
||||
*
|
||||
* @see setPath
|
||||
* @param {String} path
|
||||
*
|
||||
* @example
|
||||
* mtlLoader.setPath( 'assets/obj/' );
|
||||
* mtlLoader.setTexturePath( 'assets/textures/' );
|
||||
* mtlLoader.load( 'my.mtl', ... );
|
||||
*/
|
||||
setTexturePath: function ( path ) {
|
||||
|
||||
this.texturePath = path;
|
||||
|
||||
},
|
||||
|
||||
setBaseUrl: function ( path ) {
|
||||
|
||||
console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' );
|
||||
|
||||
this.setTexturePath( path );
|
||||
|
||||
},
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
|
||||
},
|
||||
|
||||
setMaterialOptions: function ( value ) {
|
||||
|
||||
this.materialOptions = value;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a MTL file.
|
||||
*
|
||||
* @param {String} text - Content of MTL file
|
||||
* @return {THREE.MTLLoader.MaterialCreator}
|
||||
*
|
||||
* @see setPath setTexturePath
|
||||
*
|
||||
* @note In order for relative texture references to resolve correctly
|
||||
* you must call setPath and/or setTexturePath explicitly prior to parse.
|
||||
*/
|
||||
parse: function ( text ) {
|
||||
|
||||
var lines = text.split( '\n' );
|
||||
var info = {};
|
||||
var delimiter_pattern = /\s+/;
|
||||
var materialsInfo = {};
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
var line = lines[ i ];
|
||||
line = line.trim();
|
||||
|
||||
if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
|
||||
|
||||
// Blank line or comment ignore
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
var pos = line.indexOf( ' ' );
|
||||
|
||||
var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
|
||||
key = key.toLowerCase();
|
||||
|
||||
var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : '';
|
||||
value = value.trim();
|
||||
|
||||
if ( key === 'newmtl' ) {
|
||||
|
||||
// New material
|
||||
|
||||
info = { name: value };
|
||||
materialsInfo[ value ] = info;
|
||||
|
||||
} else if ( info ) {
|
||||
|
||||
if ( key === 'ka' || key === 'kd' || key === 'ks' ) {
|
||||
|
||||
var ss = value.split( delimiter_pattern, 3 );
|
||||
info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
|
||||
|
||||
} else {
|
||||
|
||||
info[ key ] = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions );
|
||||
materialCreator.setCrossOrigin( this.crossOrigin );
|
||||
materialCreator.setManager( this.manager );
|
||||
materialCreator.setMaterials( materialsInfo );
|
||||
return materialCreator;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new THREE-MTLLoader.MaterialCreator
|
||||
* @param baseUrl - Url relative to which textures are loaded
|
||||
* @param options - Set of options on how to construct the materials
|
||||
* side: Which side to apply the material
|
||||
* THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
|
||||
* wrap: What type of wrapping to apply for textures
|
||||
* THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
|
||||
* normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
|
||||
* Default: false, assumed to be already normalized
|
||||
* ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
|
||||
* Default: false
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) {
|
||||
|
||||
this.baseUrl = baseUrl || '';
|
||||
this.options = options;
|
||||
this.materialsInfo = {};
|
||||
this.materials = {};
|
||||
this.materialsArray = [];
|
||||
this.nameLookup = {};
|
||||
|
||||
this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
|
||||
this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
|
||||
|
||||
};
|
||||
|
||||
THREE.MTLLoader.MaterialCreator.prototype = {
|
||||
|
||||
constructor: THREE.MTLLoader.MaterialCreator,
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
|
||||
},
|
||||
|
||||
setManager: function ( value ) {
|
||||
|
||||
this.manager = value;
|
||||
|
||||
},
|
||||
|
||||
setMaterials: function ( materialsInfo ) {
|
||||
|
||||
this.materialsInfo = this.convert( materialsInfo );
|
||||
this.materials = {};
|
||||
this.materialsArray = [];
|
||||
this.nameLookup = {};
|
||||
|
||||
},
|
||||
|
||||
convert: function ( materialsInfo ) {
|
||||
|
||||
if ( ! this.options ) return materialsInfo;
|
||||
|
||||
var converted = {};
|
||||
|
||||
for ( var mn in materialsInfo ) {
|
||||
|
||||
// Convert materials info into normalized form based on options
|
||||
|
||||
var mat = materialsInfo[ mn ];
|
||||
|
||||
var covmat = {};
|
||||
|
||||
converted[ mn ] = covmat;
|
||||
|
||||
for ( var prop in mat ) {
|
||||
|
||||
var save = true;
|
||||
var value = mat[ prop ];
|
||||
var lprop = prop.toLowerCase();
|
||||
|
||||
switch ( lprop ) {
|
||||
|
||||
case 'kd':
|
||||
case 'ka':
|
||||
case 'ks':
|
||||
|
||||
// Diffuse color (color under white light) using RGB values
|
||||
|
||||
if ( this.options && this.options.normalizeRGB ) {
|
||||
|
||||
value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
|
||||
|
||||
}
|
||||
|
||||
if ( this.options && this.options.ignoreZeroRGBs ) {
|
||||
|
||||
if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
|
||||
|
||||
// ignore
|
||||
|
||||
save = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( save ) {
|
||||
|
||||
covmat[ lprop ] = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return converted;
|
||||
|
||||
},
|
||||
|
||||
preload: function () {
|
||||
|
||||
for ( var mn in this.materialsInfo ) {
|
||||
|
||||
this.create( mn );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getIndex: function ( materialName ) {
|
||||
|
||||
return this.nameLookup[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
getAsArray: function () {
|
||||
|
||||
var index = 0;
|
||||
|
||||
for ( var mn in this.materialsInfo ) {
|
||||
|
||||
this.materialsArray[ index ] = this.create( mn );
|
||||
this.nameLookup[ mn ] = index;
|
||||
index ++;
|
||||
|
||||
}
|
||||
|
||||
return this.materialsArray;
|
||||
|
||||
},
|
||||
|
||||
create: function ( materialName ) {
|
||||
|
||||
if ( this.materials[ materialName ] === undefined ) {
|
||||
|
||||
this.createMaterial_( materialName );
|
||||
|
||||
}
|
||||
|
||||
return this.materials[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
createMaterial_: function ( materialName ) {
|
||||
|
||||
// Create material
|
||||
|
||||
var scope = this;
|
||||
var mat = this.materialsInfo[ materialName ];
|
||||
var params = {
|
||||
|
||||
name: materialName,
|
||||
side: this.side
|
||||
|
||||
};
|
||||
|
||||
function resolveURL( baseUrl, url ) {
|
||||
|
||||
if ( typeof url !== 'string' || url === '' )
|
||||
return '';
|
||||
|
||||
// Absolute URL
|
||||
if ( /^https?:\/\//i.test( url ) ) return url;
|
||||
|
||||
return baseUrl + url;
|
||||
|
||||
}
|
||||
|
||||
function setMapForType( mapType, value ) {
|
||||
|
||||
if ( params[ mapType ] ) return; // Keep the first encountered texture
|
||||
|
||||
var texParams = scope.getTextureParams( value, params );
|
||||
var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) );
|
||||
|
||||
map.repeat.copy( texParams.scale );
|
||||
map.offset.copy( texParams.offset );
|
||||
|
||||
map.wrapS = scope.wrap;
|
||||
map.wrapT = scope.wrap;
|
||||
|
||||
params[ mapType ] = map;
|
||||
|
||||
}
|
||||
|
||||
for ( var prop in mat ) {
|
||||
|
||||
var value = mat[ prop ];
|
||||
|
||||
if ( value === '' ) continue;
|
||||
|
||||
switch ( prop.toLowerCase() ) {
|
||||
|
||||
// Ns is material specular exponent
|
||||
|
||||
case 'kd':
|
||||
|
||||
// Diffuse color (color under white light) using RGB values
|
||||
|
||||
params.color = new THREE.Color().fromArray( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'ks':
|
||||
|
||||
// Specular color (color when light is reflected from shiny surface) using RGB values
|
||||
params.specular = new THREE.Color().fromArray( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_kd':
|
||||
|
||||
// Diffuse texture map
|
||||
|
||||
setMapForType( "map", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_ks':
|
||||
|
||||
// Specular map
|
||||
|
||||
setMapForType( "specularMap", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_bump':
|
||||
case 'bump':
|
||||
|
||||
// Bump texture map
|
||||
|
||||
setMapForType( "bumpMap", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'ns':
|
||||
|
||||
// The specular exponent (defines the focus of the specular highlight)
|
||||
// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
|
||||
|
||||
params.shininess = parseFloat( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
|
||||
if ( value < 1 ) {
|
||||
|
||||
params.opacity = value;
|
||||
params.transparent = true;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'Tr':
|
||||
|
||||
if ( value > 0 ) {
|
||||
|
||||
params.opacity = 1 - value;
|
||||
params.transparent = true;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
|
||||
return this.materials[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
getTextureParams: function ( value, matParams ) {
|
||||
|
||||
var texParams = {
|
||||
|
||||
scale: new THREE.Vector2( 1, 1 ),
|
||||
offset: new THREE.Vector2( 0, 0 )
|
||||
|
||||
};
|
||||
|
||||
var items = value.split( /\s+/ );
|
||||
var pos;
|
||||
|
||||
pos = items.indexOf( '-bm' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
matParams.bumpScale = parseFloat( items[ pos + 1 ] );
|
||||
items.splice( pos, 2 );
|
||||
|
||||
}
|
||||
|
||||
pos = items.indexOf( '-s' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
|
||||
items.splice( pos, 4 ); // we expect 3 parameters here!
|
||||
|
||||
}
|
||||
|
||||
pos = items.indexOf( '-o' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
|
||||
items.splice( pos, 4 ); // we expect 3 parameters here!
|
||||
|
||||
}
|
||||
|
||||
texParams.url = items.join( ' ' ).trim();
|
||||
return texParams;
|
||||
|
||||
},
|
||||
|
||||
loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
|
||||
|
||||
var texture;
|
||||
var loader = THREE.Loader.Handlers.get( url );
|
||||
var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
|
||||
|
||||
if ( loader === null ) {
|
||||
|
||||
loader = new THREE.TextureLoader( manager );
|
||||
|
||||
}
|
||||
|
||||
if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
|
||||
texture = loader.load( url, onLoad, onProgress, onError );
|
||||
|
||||
if ( mapping !== undefined ) texture.mapping = mapping;
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
596
node_modules/three/examples/js/loaders/NRRDLoader.js
generated
vendored
Normal file
596
node_modules/three/examples/js/loaders/NRRDLoader.js
generated
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
THREE.NRRDLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
|
||||
};
|
||||
|
||||
THREE.NRRDLoader.prototype = {
|
||||
|
||||
constructor: THREE.NRRDLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( data ) {
|
||||
|
||||
onLoad( scope.parse( data ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
// this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X
|
||||
|
||||
var _data = data;
|
||||
|
||||
var _dataPointer = 0;
|
||||
|
||||
var _nativeLittleEndian = new Int8Array( new Int16Array( [ 1 ] ).buffer )[ 0 ] > 0;
|
||||
|
||||
var _littleEndian = true;
|
||||
|
||||
var headerObject = {};
|
||||
|
||||
function scan( type, chunks ) {
|
||||
|
||||
if ( chunks === undefined || chunks === null ) {
|
||||
|
||||
chunks = 1;
|
||||
|
||||
}
|
||||
|
||||
var _chunkSize = 1;
|
||||
var _array_type = Uint8Array;
|
||||
|
||||
switch ( type ) {
|
||||
|
||||
// 1 byte data types
|
||||
case 'uchar':
|
||||
break;
|
||||
case 'schar':
|
||||
_array_type = Int8Array;
|
||||
break;
|
||||
// 2 byte data types
|
||||
case 'ushort':
|
||||
_array_type = Uint16Array;
|
||||
_chunkSize = 2;
|
||||
break;
|
||||
case 'sshort':
|
||||
_array_type = Int16Array;
|
||||
_chunkSize = 2;
|
||||
break;
|
||||
// 4 byte data types
|
||||
case 'uint':
|
||||
_array_type = Uint32Array;
|
||||
_chunkSize = 4;
|
||||
break;
|
||||
case 'sint':
|
||||
_array_type = Int32Array;
|
||||
_chunkSize = 4;
|
||||
break;
|
||||
case 'float':
|
||||
_array_type = Float32Array;
|
||||
_chunkSize = 4;
|
||||
break;
|
||||
case 'complex':
|
||||
_array_type = Float64Array;
|
||||
_chunkSize = 8;
|
||||
break;
|
||||
case 'double':
|
||||
_array_type = Float64Array;
|
||||
_chunkSize = 8;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// increase the data pointer in-place
|
||||
var _bytes = new _array_type( _data.slice( _dataPointer,
|
||||
_dataPointer += chunks * _chunkSize ) );
|
||||
|
||||
// if required, flip the endianness of the bytes
|
||||
if ( _nativeLittleEndian != _littleEndian ) {
|
||||
|
||||
// we need to flip here since the format doesn't match the native endianness
|
||||
_bytes = flipEndianness( _bytes, _chunkSize );
|
||||
|
||||
}
|
||||
|
||||
if ( chunks == 1 ) {
|
||||
|
||||
// if only one chunk was requested, just return one value
|
||||
return _bytes[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
// return the byte array
|
||||
return _bytes;
|
||||
|
||||
}
|
||||
|
||||
//Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js.
|
||||
|
||||
function flipEndianness( array, chunkSize ) {
|
||||
|
||||
var u8 = new Uint8Array( array.buffer, array.byteOffset, array.byteLength );
|
||||
for ( var i = 0; i < array.byteLength; i += chunkSize ) {
|
||||
|
||||
for ( var j = i + chunkSize - 1, k = i; j > k; j --, k ++ ) {
|
||||
|
||||
var tmp = u8[ k ];
|
||||
u8[ k ] = u8[ j ];
|
||||
u8[ j ] = tmp;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return array;
|
||||
|
||||
}
|
||||
|
||||
//parse the header
|
||||
function parseHeader( header ) {
|
||||
|
||||
var data, field, fn, i, l, lines, m, _i, _len;
|
||||
lines = header.split( /\r?\n/ );
|
||||
for ( _i = 0, _len = lines.length; _i < _len; _i ++ ) {
|
||||
|
||||
l = lines[ _i ];
|
||||
if ( l.match( /NRRD\d+/ ) ) {
|
||||
|
||||
headerObject.isNrrd = true;
|
||||
|
||||
} else if ( l.match( /^#/ ) ) {
|
||||
} else if ( m = l.match( /(.*):(.*)/ ) ) {
|
||||
|
||||
field = m[ 1 ].trim();
|
||||
data = m[ 2 ].trim();
|
||||
fn = THREE.NRRDLoader.prototype.fieldFunctions[ field ];
|
||||
if ( fn ) {
|
||||
|
||||
fn.call( headerObject, data );
|
||||
|
||||
} else {
|
||||
|
||||
headerObject[ field ] = data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if ( ! headerObject.isNrrd ) {
|
||||
|
||||
throw new Error( 'Not an NRRD file' );
|
||||
|
||||
}
|
||||
if ( headerObject.encoding === 'bz2' || headerObject.encoding === 'bzip2' ) {
|
||||
|
||||
throw new Error( 'Bzip is not supported' );
|
||||
|
||||
}
|
||||
if ( ! headerObject.vectors ) {
|
||||
|
||||
//if no space direction is set, let's use the identity
|
||||
headerObject.vectors = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ];
|
||||
//apply spacing if defined
|
||||
if ( headerObject.spacings ) {
|
||||
|
||||
for ( i = 0; i <= 2; i ++ ) {
|
||||
|
||||
if ( ! isNaN( headerObject.spacings[ i ] ) ) {
|
||||
|
||||
headerObject.vectors[ i ].multiplyScalar( headerObject.spacings[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//parse the data when registred as one of this type : 'text', 'ascii', 'txt'
|
||||
function parseDataAsText( data, start, end ) {
|
||||
|
||||
var number = '';
|
||||
start = start || 0;
|
||||
end = end || data.length;
|
||||
var value;
|
||||
//length of the result is the product of the sizes
|
||||
var lengthOfTheResult = headerObject.sizes.reduce( function ( previous, current ) {
|
||||
|
||||
return previous * current;
|
||||
|
||||
}, 1 );
|
||||
|
||||
var base = 10;
|
||||
if ( headerObject.encoding === 'hex' ) {
|
||||
|
||||
base = 16;
|
||||
|
||||
}
|
||||
|
||||
var result = new headerObject.__array( lengthOfTheResult );
|
||||
var resultIndex = 0;
|
||||
var parsingFunction = parseInt;
|
||||
if ( headerObject.__array === Float32Array || headerObject.__array === Float64Array ) {
|
||||
|
||||
parsingFunction = parseFloat;
|
||||
|
||||
}
|
||||
for ( var i = start; i < end; i ++ ) {
|
||||
|
||||
value = data[ i ];
|
||||
//if value is not a space
|
||||
if ( ( value < 9 || value > 13 ) && value !== 32 ) {
|
||||
|
||||
number += String.fromCharCode( value );
|
||||
|
||||
} else {
|
||||
|
||||
if ( number !== '' ) {
|
||||
|
||||
result[ resultIndex ] = parsingFunction( number, base );
|
||||
resultIndex ++;
|
||||
|
||||
}
|
||||
number = '';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if ( number !== '' ) {
|
||||
|
||||
result[ resultIndex ] = parsingFunction( number, base );
|
||||
resultIndex ++;
|
||||
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
var _bytes = scan( 'uchar', data.byteLength );
|
||||
var _length = _bytes.length;
|
||||
var _header = null;
|
||||
var _data_start = 0;
|
||||
var i;
|
||||
for ( i = 1; i < _length; i ++ ) {
|
||||
|
||||
if ( _bytes[ i - 1 ] == 10 && _bytes[ i ] == 10 ) {
|
||||
|
||||
// we found two line breaks in a row
|
||||
// now we know what the header is
|
||||
_header = this.parseChars( _bytes, 0, i - 2 );
|
||||
// this is were the data starts
|
||||
_data_start = i + 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// parse the header
|
||||
parseHeader( _header );
|
||||
|
||||
var _data = _bytes.subarray( _data_start ); // the data without header
|
||||
if ( headerObject.encoding === 'gzip' || headerObject.encoding === 'gz' ) {
|
||||
|
||||
// we need to decompress the datastream
|
||||
// here we start the unzipping and get a typed Uint8Array back
|
||||
var inflate = new Zlib.Gunzip( new Uint8Array( _data ) );
|
||||
_data = inflate.decompress();
|
||||
|
||||
} else if ( headerObject.encoding === 'ascii' || headerObject.encoding === 'text' || headerObject.encoding === 'txt' || headerObject.encoding === 'hex' ) {
|
||||
|
||||
_data = parseDataAsText( _data );
|
||||
|
||||
} else if ( headerObject.encoding === 'raw' ) {
|
||||
|
||||
//we need to copy the array to create a new array buffer, else we retrieve the original arraybuffer with the header
|
||||
var _copy = new Uint8Array( _data.length );
|
||||
|
||||
for ( var i = 0; i < _data.length; i ++ ) {
|
||||
|
||||
_copy[ i ] = _data[ i ];
|
||||
|
||||
}
|
||||
|
||||
_data = _copy;
|
||||
|
||||
}
|
||||
// .. let's use the underlying array buffer
|
||||
_data = _data.buffer;
|
||||
|
||||
var volume = new THREE.Volume();
|
||||
volume.header = headerObject;
|
||||
//
|
||||
// parse the (unzipped) data to a datastream of the correct type
|
||||
//
|
||||
volume.data = new headerObject.__array( _data );
|
||||
// get the min and max intensities
|
||||
var min_max = volume.computeMinMax();
|
||||
var min = min_max[ 0 ];
|
||||
var max = min_max[ 1 ];
|
||||
// attach the scalar range to the volume
|
||||
volume.windowLow = min;
|
||||
volume.windowHigh = max;
|
||||
|
||||
// get the image dimensions
|
||||
volume.dimensions = [ headerObject.sizes[ 0 ], headerObject.sizes[ 1 ], headerObject.sizes[ 2 ] ];
|
||||
volume.xLength = volume.dimensions[ 0 ];
|
||||
volume.yLength = volume.dimensions[ 1 ];
|
||||
volume.zLength = volume.dimensions[ 2 ];
|
||||
// spacing
|
||||
var spacingX = ( new THREE.Vector3( headerObject.vectors[ 0 ][ 0 ], headerObject.vectors[ 0 ][ 1 ],
|
||||
headerObject.vectors[ 0 ][ 2 ] ) ).length();
|
||||
var spacingY = ( new THREE.Vector3( headerObject.vectors[ 1 ][ 0 ], headerObject.vectors[ 1 ][ 1 ],
|
||||
headerObject.vectors[ 1 ][ 2 ] ) ).length();
|
||||
var spacingZ = ( new THREE.Vector3( headerObject.vectors[ 2 ][ 0 ], headerObject.vectors[ 2 ][ 1 ],
|
||||
headerObject.vectors[ 2 ][ 2 ] ) ).length();
|
||||
volume.spacing = [ spacingX, spacingY, spacingZ ];
|
||||
|
||||
|
||||
// Create IJKtoRAS matrix
|
||||
volume.matrix = new THREE.Matrix4();
|
||||
|
||||
var _spaceX = 1;
|
||||
var _spaceY = 1;
|
||||
var _spaceZ = 1;
|
||||
|
||||
if ( headerObject.space == "left-posterior-superior" ) {
|
||||
|
||||
_spaceX = - 1;
|
||||
_spaceY = - 1;
|
||||
|
||||
} else if ( headerObject.space === 'left-anterior-superior' ) {
|
||||
|
||||
_spaceX = - 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( ! headerObject.vectors ) {
|
||||
|
||||
volume.matrix.set( _spaceX, 0, 0, 0,
|
||||
0, _spaceY, 0, 0,
|
||||
0, 0, _spaceZ, 0,
|
||||
0, 0, 0, 1 );
|
||||
|
||||
} else {
|
||||
|
||||
var v = headerObject.vectors;
|
||||
var origin = headerObject.space_origin;
|
||||
|
||||
if ( ! origin ) {
|
||||
|
||||
origin = [ 0, 0, 0 ];
|
||||
|
||||
}
|
||||
|
||||
volume.matrix.set( _spaceX * v[ 0 ][ 0 ], _spaceX * v[ 1 ][ 0 ], _spaceX * v[ 2 ][ 0 ], 0,
|
||||
_spaceY * v[ 0 ][ 1 ], _spaceY * v[ 1 ][ 1 ], _spaceY * v[ 2 ][ 1 ], 0,
|
||||
_spaceZ * v[ 0 ][ 2 ], _spaceZ * v[ 1 ][ 2 ], _spaceZ * v[ 2 ][ 2 ], 0,
|
||||
0, 0, 0, 1 );
|
||||
|
||||
}
|
||||
|
||||
volume.inverseMatrix = new THREE.Matrix4();
|
||||
volume.inverseMatrix.getInverse( volume.matrix );
|
||||
volume.RASDimensions = ( new THREE.Vector3( volume.xLength, volume.yLength, volume.zLength ) ).applyMatrix4( volume.matrix ).round().toArray().map( Math.abs );
|
||||
|
||||
// .. and set the default threshold
|
||||
// only if the threshold was not already set
|
||||
if ( volume.lowerThreshold === - Infinity ) {
|
||||
|
||||
volume.lowerThreshold = min;
|
||||
|
||||
}
|
||||
if ( volume.upperThreshold === Infinity ) {
|
||||
|
||||
volume.upperThreshold = max;
|
||||
|
||||
}
|
||||
|
||||
return volume;
|
||||
|
||||
},
|
||||
|
||||
parseChars: function ( array, start, end ) {
|
||||
|
||||
// without borders, use the whole array
|
||||
if ( start === undefined ) {
|
||||
|
||||
start = 0;
|
||||
|
||||
}
|
||||
if ( end === undefined ) {
|
||||
|
||||
end = array.length;
|
||||
|
||||
}
|
||||
|
||||
var output = '';
|
||||
// create and append the chars
|
||||
var i = 0;
|
||||
for ( i = start; i < end; ++ i ) {
|
||||
|
||||
output += String.fromCharCode( array[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
},
|
||||
|
||||
fieldFunctions: {
|
||||
|
||||
type: function ( data ) {
|
||||
|
||||
switch ( data ) {
|
||||
|
||||
case 'uchar':
|
||||
case 'unsigned char':
|
||||
case 'uint8':
|
||||
case 'uint8_t':
|
||||
this.__array = Uint8Array;
|
||||
break;
|
||||
case 'signed char':
|
||||
case 'int8':
|
||||
case 'int8_t':
|
||||
this.__array = Int8Array;
|
||||
break;
|
||||
case 'short':
|
||||
case 'short int':
|
||||
case 'signed short':
|
||||
case 'signed short int':
|
||||
case 'int16':
|
||||
case 'int16_t':
|
||||
this.__array = Int16Array;
|
||||
break;
|
||||
case 'ushort':
|
||||
case 'unsigned short':
|
||||
case 'unsigned short int':
|
||||
case 'uint16':
|
||||
case 'uint16_t':
|
||||
this.__array = Uint16Array;
|
||||
break;
|
||||
case 'int':
|
||||
case 'signed int':
|
||||
case 'int32':
|
||||
case 'int32_t':
|
||||
this.__array = Int32Array;
|
||||
break;
|
||||
case 'uint':
|
||||
case 'unsigned int':
|
||||
case 'uint32':
|
||||
case 'uint32_t':
|
||||
this.__array = Uint32Array;
|
||||
break;
|
||||
case 'float':
|
||||
this.__array = Float32Array;
|
||||
break;
|
||||
case 'double':
|
||||
this.__array = Float64Array;
|
||||
break;
|
||||
default:
|
||||
throw new Error( 'Unsupported NRRD data type: ' + data );
|
||||
|
||||
}
|
||||
|
||||
return this.type = data;
|
||||
|
||||
},
|
||||
|
||||
endian: function ( data ) {
|
||||
|
||||
return this.endian = data;
|
||||
|
||||
},
|
||||
|
||||
encoding: function ( data ) {
|
||||
|
||||
return this.encoding = data;
|
||||
|
||||
},
|
||||
|
||||
dimension: function ( data ) {
|
||||
|
||||
return this.dim = parseInt( data, 10 );
|
||||
|
||||
},
|
||||
|
||||
sizes: function ( data ) {
|
||||
|
||||
var i;
|
||||
return this.sizes = ( function () {
|
||||
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = data.split( /\s+/ );
|
||||
_results = [];
|
||||
for ( _i = 0, _len = _ref.length; _i < _len; _i ++ ) {
|
||||
|
||||
i = _ref[ _i ];
|
||||
_results.push( parseInt( i, 10 ) );
|
||||
|
||||
}
|
||||
return _results;
|
||||
|
||||
} )();
|
||||
|
||||
},
|
||||
|
||||
space: function ( data ) {
|
||||
|
||||
return this.space = data;
|
||||
|
||||
},
|
||||
|
||||
'space origin': function ( data ) {
|
||||
|
||||
return this.space_origin = data.split( "(" )[ 1 ].split( ")" )[ 0 ].split( "," );
|
||||
|
||||
},
|
||||
|
||||
'space directions': function ( data ) {
|
||||
|
||||
var f, parts, v;
|
||||
parts = data.match( /\(.*?\)/g );
|
||||
return this.vectors = ( function () {
|
||||
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for ( _i = 0, _len = parts.length; _i < _len; _i ++ ) {
|
||||
|
||||
v = parts[ _i ];
|
||||
_results.push( ( function () {
|
||||
|
||||
var _j, _len2, _ref, _results2;
|
||||
_ref = v.slice( 1, - 1 ).split( /,/ );
|
||||
_results2 = [];
|
||||
for ( _j = 0, _len2 = _ref.length; _j < _len2; _j ++ ) {
|
||||
|
||||
f = _ref[ _j ];
|
||||
_results2.push( parseFloat( f ) );
|
||||
|
||||
}
|
||||
return _results2;
|
||||
|
||||
} )() );
|
||||
|
||||
}
|
||||
return _results;
|
||||
|
||||
} )();
|
||||
|
||||
},
|
||||
|
||||
spacings: function ( data ) {
|
||||
|
||||
var f, parts;
|
||||
parts = data.split( /\s+/ );
|
||||
return this.spacings = ( function () {
|
||||
|
||||
var _i, _len, _results = [];
|
||||
|
||||
for ( _i = 0, _len = parts.length; _i < _len; _i ++ ) {
|
||||
|
||||
f = parts[ _i ];
|
||||
_results.push( parseFloat( f ) );
|
||||
|
||||
}
|
||||
return _results;
|
||||
|
||||
} )();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
743
node_modules/three/examples/js/loaders/OBJLoader.js
generated
vendored
Normal file
743
node_modules/three/examples/js/loaders/OBJLoader.js
generated
vendored
Normal file
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.OBJLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
this.materials = null;
|
||||
|
||||
this.regexp = {
|
||||
// v float float float
|
||||
vertex_pattern : /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,
|
||||
// vn float float float
|
||||
normal_pattern : /^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,
|
||||
// vt float float
|
||||
uv_pattern : /^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,
|
||||
// f vertex vertex vertex
|
||||
face_vertex : /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/,
|
||||
// f vertex/uv vertex/uv vertex/uv
|
||||
face_vertex_uv : /^f\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+))?/,
|
||||
// f vertex/uv/normal vertex/uv/normal vertex/uv/normal
|
||||
face_vertex_uv_normal : /^f\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+)\/(-?\d+))?/,
|
||||
// f vertex//normal vertex//normal vertex//normal
|
||||
face_vertex_normal : /^f\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)(?:\s+(-?\d+)\/\/(-?\d+))?/,
|
||||
// o object_name | g group_name
|
||||
object_pattern : /^[og]\s*(.+)?/,
|
||||
// s boolean
|
||||
smoothing_pattern : /^s\s+(\d+|on|off)/,
|
||||
// mtllib file_reference
|
||||
material_library_pattern : /^mtllib /,
|
||||
// usemtl material_name
|
||||
material_use_pattern : /^usemtl /
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
THREE.OBJLoader.prototype = {
|
||||
|
||||
constructor: THREE.OBJLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setPath( this.path );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
setPath: function ( value ) {
|
||||
|
||||
this.path = value;
|
||||
|
||||
},
|
||||
|
||||
setMaterials: function ( materials ) {
|
||||
|
||||
this.materials = materials;
|
||||
|
||||
},
|
||||
|
||||
_createParserState : function () {
|
||||
|
||||
var state = {
|
||||
objects : [],
|
||||
object : {},
|
||||
|
||||
vertices : [],
|
||||
normals : [],
|
||||
uvs : [],
|
||||
|
||||
materialLibraries : [],
|
||||
|
||||
startObject: function ( name, fromDeclaration ) {
|
||||
|
||||
// If the current object (initial from reset) is not from a g/o declaration in the parsed
|
||||
// file. We need to use it for the first parsed g/o to keep things in sync.
|
||||
if ( this.object && this.object.fromDeclaration === false ) {
|
||||
|
||||
this.object.name = name;
|
||||
this.object.fromDeclaration = ( fromDeclaration !== false );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
|
||||
|
||||
if ( this.object && typeof this.object._finalize === 'function' ) {
|
||||
|
||||
this.object._finalize( true );
|
||||
|
||||
}
|
||||
|
||||
this.object = {
|
||||
name : name || '',
|
||||
fromDeclaration : ( fromDeclaration !== false ),
|
||||
|
||||
geometry : {
|
||||
vertices : [],
|
||||
normals : [],
|
||||
uvs : []
|
||||
},
|
||||
materials : [],
|
||||
smooth : true,
|
||||
|
||||
startMaterial : function( name, libraries ) {
|
||||
|
||||
var previous = this._finalize( false );
|
||||
|
||||
// New usemtl declaration overwrites an inherited material, except if faces were declared
|
||||
// after the material, then it must be preserved for proper MultiMaterial continuation.
|
||||
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
|
||||
|
||||
this.materials.splice( previous.index, 1 );
|
||||
|
||||
}
|
||||
|
||||
var material = {
|
||||
index : this.materials.length,
|
||||
name : name || '',
|
||||
mtllib : ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
|
||||
smooth : ( previous !== undefined ? previous.smooth : this.smooth ),
|
||||
groupStart : ( previous !== undefined ? previous.groupEnd : 0 ),
|
||||
groupEnd : -1,
|
||||
groupCount : -1,
|
||||
inherited : false,
|
||||
|
||||
clone : function( index ) {
|
||||
var cloned = {
|
||||
index : ( typeof index === 'number' ? index : this.index ),
|
||||
name : this.name,
|
||||
mtllib : this.mtllib,
|
||||
smooth : this.smooth,
|
||||
groupStart : 0,
|
||||
groupEnd : -1,
|
||||
groupCount : -1,
|
||||
inherited : false
|
||||
};
|
||||
cloned.clone = this.clone.bind(cloned);
|
||||
return cloned;
|
||||
}
|
||||
};
|
||||
|
||||
this.materials.push( material );
|
||||
|
||||
return material;
|
||||
|
||||
},
|
||||
|
||||
currentMaterial : function() {
|
||||
|
||||
if ( this.materials.length > 0 ) {
|
||||
return this.materials[ this.materials.length - 1 ];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
},
|
||||
|
||||
_finalize : function( end ) {
|
||||
|
||||
var lastMultiMaterial = this.currentMaterial();
|
||||
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === -1 ) {
|
||||
|
||||
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
|
||||
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
|
||||
lastMultiMaterial.inherited = false;
|
||||
|
||||
}
|
||||
|
||||
// Ignore objects tail materials if no face declarations followed them before a new o/g started.
|
||||
if ( end && this.materials.length > 1 ) {
|
||||
|
||||
for ( var mi = this.materials.length - 1; mi >= 0; mi-- ) {
|
||||
if ( this.materials[mi].groupCount <= 0 ) {
|
||||
this.materials.splice( mi, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Guarantee at least one empty material, this makes the creation later more straight forward.
|
||||
if ( end && this.materials.length === 0 ) {
|
||||
|
||||
this.materials.push({
|
||||
name : '',
|
||||
smooth : this.smooth
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return lastMultiMaterial;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Inherit previous objects material.
|
||||
// Spec tells us that a declared material must be set to all objects until a new material is declared.
|
||||
// If a usemtl declaration is encountered while this new object is being parsed, it will
|
||||
// overwrite the inherited material. Exception being that there was already face declarations
|
||||
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
|
||||
|
||||
if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === "function" ) {
|
||||
|
||||
var declared = previousMaterial.clone( 0 );
|
||||
declared.inherited = true;
|
||||
this.object.materials.push( declared );
|
||||
|
||||
}
|
||||
|
||||
this.objects.push( this.object );
|
||||
|
||||
},
|
||||
|
||||
finalize : function() {
|
||||
|
||||
if ( this.object && typeof this.object._finalize === 'function' ) {
|
||||
|
||||
this.object._finalize( true );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
parseVertexIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
|
||||
|
||||
},
|
||||
|
||||
parseNormalIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
|
||||
|
||||
},
|
||||
|
||||
parseUVIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;
|
||||
|
||||
},
|
||||
|
||||
addVertex: function ( a, b, c ) {
|
||||
|
||||
var src = this.vertices;
|
||||
var dst = this.object.geometry.vertices;
|
||||
|
||||
dst.push( src[ a + 0 ] );
|
||||
dst.push( src[ a + 1 ] );
|
||||
dst.push( src[ a + 2 ] );
|
||||
dst.push( src[ b + 0 ] );
|
||||
dst.push( src[ b + 1 ] );
|
||||
dst.push( src[ b + 2 ] );
|
||||
dst.push( src[ c + 0 ] );
|
||||
dst.push( src[ c + 1 ] );
|
||||
dst.push( src[ c + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addVertexLine: function ( a ) {
|
||||
|
||||
var src = this.vertices;
|
||||
var dst = this.object.geometry.vertices;
|
||||
|
||||
dst.push( src[ a + 0 ] );
|
||||
dst.push( src[ a + 1 ] );
|
||||
dst.push( src[ a + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addNormal : function ( a, b, c ) {
|
||||
|
||||
var src = this.normals;
|
||||
var dst = this.object.geometry.normals;
|
||||
|
||||
dst.push( src[ a + 0 ] );
|
||||
dst.push( src[ a + 1 ] );
|
||||
dst.push( src[ a + 2 ] );
|
||||
dst.push( src[ b + 0 ] );
|
||||
dst.push( src[ b + 1 ] );
|
||||
dst.push( src[ b + 2 ] );
|
||||
dst.push( src[ c + 0 ] );
|
||||
dst.push( src[ c + 1 ] );
|
||||
dst.push( src[ c + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addUV: function ( a, b, c ) {
|
||||
|
||||
var src = this.uvs;
|
||||
var dst = this.object.geometry.uvs;
|
||||
|
||||
dst.push( src[ a + 0 ] );
|
||||
dst.push( src[ a + 1 ] );
|
||||
dst.push( src[ b + 0 ] );
|
||||
dst.push( src[ b + 1 ] );
|
||||
dst.push( src[ c + 0 ] );
|
||||
dst.push( src[ c + 1 ] );
|
||||
|
||||
},
|
||||
|
||||
addUVLine: function ( a ) {
|
||||
|
||||
var src = this.uvs;
|
||||
var dst = this.object.geometry.uvs;
|
||||
|
||||
dst.push( src[ a + 0 ] );
|
||||
dst.push( src[ a + 1 ] );
|
||||
|
||||
},
|
||||
|
||||
addFace: function ( a, b, c, d, ua, ub, uc, ud, na, nb, nc, nd ) {
|
||||
|
||||
var vLen = this.vertices.length;
|
||||
|
||||
var ia = this.parseVertexIndex( a, vLen );
|
||||
var ib = this.parseVertexIndex( b, vLen );
|
||||
var ic = this.parseVertexIndex( c, vLen );
|
||||
var id;
|
||||
|
||||
if ( d === undefined ) {
|
||||
|
||||
this.addVertex( ia, ib, ic );
|
||||
|
||||
} else {
|
||||
|
||||
id = this.parseVertexIndex( d, vLen );
|
||||
|
||||
this.addVertex( ia, ib, id );
|
||||
this.addVertex( ib, ic, id );
|
||||
|
||||
}
|
||||
|
||||
if ( ua !== undefined ) {
|
||||
|
||||
var uvLen = this.uvs.length;
|
||||
|
||||
ia = this.parseUVIndex( ua, uvLen );
|
||||
ib = this.parseUVIndex( ub, uvLen );
|
||||
ic = this.parseUVIndex( uc, uvLen );
|
||||
|
||||
if ( d === undefined ) {
|
||||
|
||||
this.addUV( ia, ib, ic );
|
||||
|
||||
} else {
|
||||
|
||||
id = this.parseUVIndex( ud, uvLen );
|
||||
|
||||
this.addUV( ia, ib, id );
|
||||
this.addUV( ib, ic, id );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( na !== undefined ) {
|
||||
|
||||
// Normals are many times the same. If so, skip function call and parseInt.
|
||||
var nLen = this.normals.length;
|
||||
ia = this.parseNormalIndex( na, nLen );
|
||||
|
||||
ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
|
||||
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
|
||||
|
||||
if ( d === undefined ) {
|
||||
|
||||
this.addNormal( ia, ib, ic );
|
||||
|
||||
} else {
|
||||
|
||||
id = this.parseNormalIndex( nd, nLen );
|
||||
|
||||
this.addNormal( ia, ib, id );
|
||||
this.addNormal( ib, ic, id );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
addLineGeometry: function ( vertices, uvs ) {
|
||||
|
||||
this.object.geometry.type = 'Line';
|
||||
|
||||
var vLen = this.vertices.length;
|
||||
var uvLen = this.uvs.length;
|
||||
|
||||
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
|
||||
|
||||
this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
|
||||
|
||||
}
|
||||
|
||||
for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {
|
||||
|
||||
this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
state.startObject( '', false );
|
||||
|
||||
return state;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( text ) {
|
||||
|
||||
console.time( 'OBJLoader' );
|
||||
|
||||
var state = this._createParserState();
|
||||
|
||||
if ( text.indexOf( '\r\n' ) !== - 1 ) {
|
||||
|
||||
// This is faster than String.split with regex that splits on both
|
||||
text = text.replace( /\r\n/g, '\n' );
|
||||
|
||||
}
|
||||
|
||||
if ( text.indexOf( '\\\n' ) !== - 1) {
|
||||
|
||||
// join lines separated by a line continuation character (\)
|
||||
text = text.replace( /\\\n/g, '' );
|
||||
|
||||
}
|
||||
|
||||
var lines = text.split( '\n' );
|
||||
var line = '', lineFirstChar = '', lineSecondChar = '';
|
||||
var lineLength = 0;
|
||||
var result = [];
|
||||
|
||||
// Faster to just trim left side of the line. Use if available.
|
||||
var trimLeft = ( typeof ''.trimLeft === 'function' );
|
||||
|
||||
for ( var i = 0, l = lines.length; i < l; i ++ ) {
|
||||
|
||||
line = lines[ i ];
|
||||
|
||||
line = trimLeft ? line.trimLeft() : line.trim();
|
||||
|
||||
lineLength = line.length;
|
||||
|
||||
if ( lineLength === 0 ) continue;
|
||||
|
||||
lineFirstChar = line.charAt( 0 );
|
||||
|
||||
// @todo invoke passed in handler if any
|
||||
if ( lineFirstChar === '#' ) continue;
|
||||
|
||||
if ( lineFirstChar === 'v' ) {
|
||||
|
||||
lineSecondChar = line.charAt( 1 );
|
||||
|
||||
if ( lineSecondChar === ' ' && ( result = this.regexp.vertex_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// 0 1 2 3
|
||||
// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
|
||||
|
||||
state.vertices.push(
|
||||
parseFloat( result[ 1 ] ),
|
||||
parseFloat( result[ 2 ] ),
|
||||
parseFloat( result[ 3 ] )
|
||||
);
|
||||
|
||||
} else if ( lineSecondChar === 'n' && ( result = this.regexp.normal_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// 0 1 2 3
|
||||
// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
|
||||
|
||||
state.normals.push(
|
||||
parseFloat( result[ 1 ] ),
|
||||
parseFloat( result[ 2 ] ),
|
||||
parseFloat( result[ 3 ] )
|
||||
);
|
||||
|
||||
} else if ( lineSecondChar === 't' && ( result = this.regexp.uv_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// 0 1 2
|
||||
// ["vt 0.1 0.2", "0.1", "0.2"]
|
||||
|
||||
state.uvs.push(
|
||||
parseFloat( result[ 1 ] ),
|
||||
parseFloat( result[ 2 ] )
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( "Unexpected vertex/normal/uv line: '" + line + "'" );
|
||||
|
||||
}
|
||||
|
||||
} else if ( lineFirstChar === "f" ) {
|
||||
|
||||
if ( ( result = this.regexp.face_vertex_uv_normal.exec( line ) ) !== null ) {
|
||||
|
||||
// f vertex/uv/normal vertex/uv/normal vertex/uv/normal
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
// ["f 1/1/1 2/2/2 3/3/3", "1", "1", "1", "2", "2", "2", "3", "3", "3", undefined, undefined, undefined]
|
||||
|
||||
state.addFace(
|
||||
result[ 1 ], result[ 4 ], result[ 7 ], result[ 10 ],
|
||||
result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
|
||||
result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
|
||||
);
|
||||
|
||||
} else if ( ( result = this.regexp.face_vertex_uv.exec( line ) ) !== null ) {
|
||||
|
||||
// f vertex/uv vertex/uv vertex/uv
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// ["f 1/1 2/2 3/3", "1", "1", "2", "2", "3", "3", undefined, undefined]
|
||||
|
||||
state.addFace(
|
||||
result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ],
|
||||
result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ]
|
||||
);
|
||||
|
||||
} else if ( ( result = this.regexp.face_vertex_normal.exec( line ) ) !== null ) {
|
||||
|
||||
// f vertex//normal vertex//normal vertex//normal
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// ["f 1//1 2//2 3//3", "1", "1", "2", "2", "3", "3", undefined, undefined]
|
||||
|
||||
state.addFace(
|
||||
result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ],
|
||||
undefined, undefined, undefined, undefined,
|
||||
result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ]
|
||||
);
|
||||
|
||||
} else if ( ( result = this.regexp.face_vertex.exec( line ) ) !== null ) {
|
||||
|
||||
// f vertex vertex vertex
|
||||
// 0 1 2 3 4
|
||||
// ["f 1 2 3", "1", "2", "3", undefined]
|
||||
|
||||
state.addFace(
|
||||
result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( "Unexpected face line: '" + line + "'" );
|
||||
|
||||
}
|
||||
|
||||
} else if ( lineFirstChar === "l" ) {
|
||||
|
||||
var lineParts = line.substring( 1 ).trim().split( " " );
|
||||
var lineVertices = [], lineUVs = [];
|
||||
|
||||
if ( line.indexOf( "/" ) === - 1 ) {
|
||||
|
||||
lineVertices = lineParts;
|
||||
|
||||
} else {
|
||||
|
||||
for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) {
|
||||
|
||||
var parts = lineParts[ li ].split( "/" );
|
||||
|
||||
if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] );
|
||||
if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
state.addLineGeometry( lineVertices, lineUVs );
|
||||
|
||||
} else if ( ( result = this.regexp.object_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// o object_name
|
||||
// or
|
||||
// g group_name
|
||||
|
||||
// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
||||
// var name = result[ 0 ].substr( 1 ).trim();
|
||||
var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
|
||||
|
||||
state.startObject( name );
|
||||
|
||||
} else if ( this.regexp.material_use_pattern.test( line ) ) {
|
||||
|
||||
// material
|
||||
|
||||
state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
|
||||
|
||||
} else if ( this.regexp.material_library_pattern.test( line ) ) {
|
||||
|
||||
// mtl file
|
||||
|
||||
state.materialLibraries.push( line.substring( 7 ).trim() );
|
||||
|
||||
} else if ( ( result = this.regexp.smoothing_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// smooth shading
|
||||
|
||||
// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
|
||||
// but does not define a usemtl for each face set.
|
||||
// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
|
||||
// This requires some care to not create extra material on each smooth value for "normal" obj files.
|
||||
// where explicit usemtl defines geometry groups.
|
||||
// Example asset: examples/models/obj/cerberus/Cerberus.obj
|
||||
|
||||
var value = result[ 1 ].trim().toLowerCase();
|
||||
state.object.smooth = ( value === '1' || value === 'on' );
|
||||
|
||||
var material = state.object.currentMaterial();
|
||||
if ( material ) {
|
||||
|
||||
material.smooth = state.object.smooth;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Handle null terminated files without exception
|
||||
if ( line === '\0' ) continue;
|
||||
|
||||
throw new Error( "Unexpected line: '" + line + "'" );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.finalize();
|
||||
|
||||
var container = new THREE.Group();
|
||||
container.materialLibraries = [].concat( state.materialLibraries );
|
||||
|
||||
for ( var i = 0, l = state.objects.length; i < l; i ++ ) {
|
||||
|
||||
var object = state.objects[ i ];
|
||||
var geometry = object.geometry;
|
||||
var materials = object.materials;
|
||||
var isLine = ( geometry.type === 'Line' );
|
||||
|
||||
// Skip o/g line declarations that did not follow with any faces
|
||||
if ( geometry.vertices.length === 0 ) continue;
|
||||
|
||||
var buffergeometry = new THREE.BufferGeometry();
|
||||
|
||||
buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
|
||||
|
||||
if ( geometry.normals.length > 0 ) {
|
||||
|
||||
buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
|
||||
|
||||
} else {
|
||||
|
||||
buffergeometry.computeVertexNormals();
|
||||
|
||||
}
|
||||
|
||||
if ( geometry.uvs.length > 0 ) {
|
||||
|
||||
buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
|
||||
|
||||
}
|
||||
|
||||
// Create materials
|
||||
|
||||
var createdMaterials = [];
|
||||
|
||||
for ( var mi = 0, miLen = materials.length; mi < miLen ; mi++ ) {
|
||||
|
||||
var sourceMaterial = materials[mi];
|
||||
var material = undefined;
|
||||
|
||||
if ( this.materials !== null ) {
|
||||
|
||||
material = this.materials.create( sourceMaterial.name );
|
||||
|
||||
// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
|
||||
if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
|
||||
|
||||
var materialLine = new THREE.LineBasicMaterial();
|
||||
materialLine.copy( material );
|
||||
material = materialLine;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! material ) {
|
||||
|
||||
material = ( ! isLine ? new THREE.MeshPhongMaterial() : new THREE.LineBasicMaterial() );
|
||||
material.name = sourceMaterial.name;
|
||||
|
||||
}
|
||||
|
||||
material.shading = sourceMaterial.smooth ? THREE.SmoothShading : THREE.FlatShading;
|
||||
|
||||
createdMaterials.push(material);
|
||||
|
||||
}
|
||||
|
||||
// Create mesh
|
||||
|
||||
var mesh;
|
||||
|
||||
if ( createdMaterials.length > 1 ) {
|
||||
|
||||
for ( var mi = 0, miLen = materials.length; mi < miLen ; mi++ ) {
|
||||
|
||||
var sourceMaterial = materials[mi];
|
||||
buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );
|
||||
|
||||
}
|
||||
|
||||
var multiMaterial = new THREE.MultiMaterial( createdMaterials );
|
||||
mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, multiMaterial ) : new THREE.LineSegments( buffergeometry, multiMaterial ) );
|
||||
|
||||
} else {
|
||||
|
||||
mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ) : new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ) );
|
||||
}
|
||||
|
||||
mesh.name = object.name;
|
||||
|
||||
container.add( mesh );
|
||||
|
||||
}
|
||||
|
||||
console.timeEnd( 'OBJLoader' );
|
||||
|
||||
return container;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
250
node_modules/three/examples/js/loaders/PCDLoader.js
generated
vendored
Normal file
250
node_modules/three/examples/js/loaders/PCDLoader.js
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* @author Filipe Caixeta / http://filipecaixeta.com.br
|
||||
*
|
||||
* Description: A THREE loader for PCD ascii and binary files.
|
||||
*
|
||||
* Limitations: Compressed binary files are not supported.
|
||||
*
|
||||
*/
|
||||
|
||||
THREE.PCDLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
this.littleEndian = true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
THREE.PCDLoader.prototype = {
|
||||
|
||||
constructor: THREE.PCDLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( data ) {
|
||||
|
||||
onLoad( scope.parse( data, url ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
binarryToStr: function ( data ) {
|
||||
|
||||
var text = "";
|
||||
var charArray = new Uint8Array( data );
|
||||
for ( var i = 0; i < data.byteLength; i ++ ) {
|
||||
|
||||
text += String.fromCharCode( charArray[ i ] );
|
||||
|
||||
}
|
||||
return text;
|
||||
|
||||
},
|
||||
|
||||
parseHeader: function ( data ) {
|
||||
|
||||
var PCDheader = {};
|
||||
var result1 = data.search( /[\r\n]DATA\s(\S*)\s/i );
|
||||
var result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.substr( result1 - 1 ) );
|
||||
PCDheader.data = result2[ 1 ];
|
||||
PCDheader.headerLen = result2[ 0 ].length + result1;
|
||||
PCDheader.str = data.substr( 0, PCDheader.headerLen );
|
||||
// Remove comments
|
||||
PCDheader.str = PCDheader.str.replace( /\#.*/gi, "" );
|
||||
PCDheader.version = /VERSION (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.version != null )
|
||||
PCDheader.version = parseFloat( PCDheader.version[ 1 ] );
|
||||
PCDheader.fields = /FIELDS (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.fields != null )
|
||||
PCDheader.fields = PCDheader.fields[ 1 ].split( " " );
|
||||
PCDheader.size = /SIZE (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.size != null )
|
||||
PCDheader.size = PCDheader.size[ 1 ].split( " " ).map( function ( x ) {
|
||||
|
||||
return parseInt( x, 10 );
|
||||
|
||||
} );
|
||||
PCDheader.type = /TYPE (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.type != null )
|
||||
PCDheader.type = PCDheader.type[ 1 ].split( " " );
|
||||
PCDheader.count = /COUNT (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.count != null )
|
||||
PCDheader.count = PCDheader.count[ 1 ].split( " " ).map( function ( x ) {
|
||||
|
||||
return parseInt( x, 10 );
|
||||
|
||||
} );
|
||||
PCDheader.width = /WIDTH (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.width != null )
|
||||
PCDheader.width = parseInt( PCDheader.width[ 1 ] );
|
||||
PCDheader.height = /HEIGHT (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.height != null )
|
||||
PCDheader.height = parseInt( PCDheader.height[ 1 ] );
|
||||
PCDheader.viewpoint = /VIEWPOINT (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.viewpoint != null )
|
||||
PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];
|
||||
PCDheader.points = /POINTS (.*)/i.exec( PCDheader.str );
|
||||
if ( PCDheader.points != null )
|
||||
PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );
|
||||
if ( PCDheader.points == null )
|
||||
PCDheader.points = PCDheader.width * PCDheader.height;
|
||||
|
||||
if ( PCDheader.count == null ) {
|
||||
|
||||
PCDheader.count = [];
|
||||
for ( var i = 0; i < PCDheader.fields; i ++ )
|
||||
PCDheader.count.push( 1 );
|
||||
|
||||
}
|
||||
|
||||
PCDheader.offset = {};
|
||||
var sizeSum = 0;
|
||||
for ( var i = 0; i < PCDheader.fields.length; i ++ ) {
|
||||
|
||||
if ( PCDheader.data == "ascii" ) {
|
||||
|
||||
PCDheader.offset[ PCDheader.fields[ i ] ] = i;
|
||||
|
||||
} else {
|
||||
|
||||
PCDheader.offset[ PCDheader.fields[ i ] ] = sizeSum;
|
||||
sizeSum += PCDheader.size[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// For binary only
|
||||
PCDheader.rowSize = sizeSum;
|
||||
|
||||
return PCDheader;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data, url ) {
|
||||
|
||||
var textData = this.binarryToStr( data );
|
||||
|
||||
// Parse the header
|
||||
// Header is always ascii format
|
||||
var PCDheader = this.parseHeader( textData );
|
||||
|
||||
// Parse the data
|
||||
var position = false;
|
||||
if ( PCDheader.offset.x != undefined )
|
||||
position = new Float32Array( PCDheader.points * 3 );
|
||||
var color = false;
|
||||
if ( PCDheader.offset.rgb != undefined )
|
||||
color = new Float32Array( PCDheader.points * 3 );
|
||||
var normal = false;
|
||||
if ( PCDheader.offset.normal_x != undefined )
|
||||
normal = new Float32Array( PCDheader.points * 3 );
|
||||
|
||||
if ( PCDheader.data == "ascii" ) {
|
||||
|
||||
var offset = PCDheader.offset;
|
||||
var pcdData = textData.substr( PCDheader.headerLen );
|
||||
var lines = pcdData.split( '\n' );
|
||||
var i3 = 0;
|
||||
for ( var i = 0; i < lines.length; i ++, i3 += 3 ) {
|
||||
|
||||
var line = lines[ i ].split( " " );
|
||||
if ( offset.x != undefined ) {
|
||||
|
||||
position[ i3 + 0 ] = parseFloat( line[ offset.x ] );
|
||||
position[ i3 + 1 ] = parseFloat( line[ offset.y ] );
|
||||
position[ i3 + 2 ] = parseFloat( line[ offset.z ] );
|
||||
|
||||
}
|
||||
if ( offset.rgb != undefined ) {
|
||||
|
||||
var c = new Float32Array( [ parseFloat( line[ offset.rgb ] ) ] );
|
||||
var dataview = new DataView( c.buffer, 0 );
|
||||
color[ i3 + 0 ] = dataview.getUint8( 0 ) / 255.0;
|
||||
color[ i3 + 1 ] = dataview.getUint8( 1 ) / 255.0;
|
||||
color[ i3 + 2 ] = dataview.getUint8( 2 ) / 255.0;
|
||||
|
||||
}
|
||||
if ( offset.normal_x != undefined ) {
|
||||
|
||||
normal[ i3 + 0 ] = parseFloat( line[ offset.normal_x ] );
|
||||
normal[ i3 + 1 ] = parseFloat( line[ offset.normal_y ] );
|
||||
normal[ i3 + 2 ] = parseFloat( line[ offset.normal_z ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( PCDheader.data == "binary_compressed" ) {
|
||||
|
||||
console.error( 'THREE.PCDLoader: binary_compressed files are not supported' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( PCDheader.data == "binary" ) {
|
||||
|
||||
var row = 0;
|
||||
var dataview = new DataView( data, PCDheader.headerLen );
|
||||
var i = 0;
|
||||
var offset = PCDheader.offset;
|
||||
for ( var i3 = 0; i < PCDheader.points; i3 += 3, row += PCDheader.rowSize, i ++ ) {
|
||||
|
||||
if ( offset.x != undefined ) {
|
||||
|
||||
position[ i3 + 0 ] = dataview.getFloat32( row + offset.x, this.littleEndian );
|
||||
position[ i3 + 1 ] = dataview.getFloat32( row + offset.y, this.littleEndian );
|
||||
position[ i3 + 2 ] = dataview.getFloat32( row + offset.z, this.littleEndian );
|
||||
|
||||
}
|
||||
if ( offset.rgb != undefined ) {
|
||||
|
||||
color[ i3 + 0 ] = dataview.getUint8( row + offset.rgb + 0 ) / 255.0;
|
||||
color[ i3 + 1 ] = dataview.getUint8( row + offset.rgb + 1 ) / 255.0;
|
||||
color[ i3 + 2 ] = dataview.getUint8( row + offset.rgb + 2 ) / 255.0;
|
||||
|
||||
}
|
||||
if ( offset.normal_x != undefined ) {
|
||||
|
||||
normal[ i3 + 0 ] = dataview.getFloat32( row + offset.normal_x, this.littleEndian );
|
||||
normal[ i3 + 1 ] = dataview.getFloat32( row + offset.normal_y, this.littleEndian );
|
||||
normal[ i3 + 2 ] = dataview.getFloat32( row + offset.normal_z, this.littleEndian );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
if ( position != false )
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( position, 3 ) );
|
||||
if ( color != false )
|
||||
geometry.addAttribute( 'color', new THREE.BufferAttribute( color, 3 ) );
|
||||
if ( normal != false )
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normal, 3 ) );
|
||||
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
var material = new THREE.PointsMaterial( { size: 0.005, vertexColors: ! ( color == false ) } );
|
||||
if ( color == false )
|
||||
material.color.setHex( Math.random() * 0xffffff );
|
||||
|
||||
var mesh = new THREE.Points( geometry, material );
|
||||
var name = url.split( '' ).reverse().join( '' );
|
||||
name = /([^\/]*)/.exec( name );
|
||||
name = name[ 1 ].split( '' ).reverse().join( '' );
|
||||
mesh.name = name;
|
||||
mesh.PCDheader = PCDheader;
|
||||
|
||||
return mesh;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
187
node_modules/three/examples/js/loaders/PDBLoader.js
generated
vendored
Normal file
187
node_modules/three/examples/js/loaders/PDBLoader.js
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author Mugen87 / https://github.com/Mugen87
|
||||
*/
|
||||
|
||||
THREE.PDBLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.PDBLoader.prototype = {
|
||||
|
||||
constructor: THREE.PDBLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
var json = scope.parsePDB( text );
|
||||
scope.createModel( json, onLoad );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
// Based on CanvasMol PDB parser
|
||||
|
||||
parsePDB: function ( text ) {
|
||||
|
||||
function trim( text ) {
|
||||
|
||||
return text.replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' );
|
||||
|
||||
}
|
||||
|
||||
function capitalize( text ) {
|
||||
|
||||
return text.charAt( 0 ).toUpperCase() + text.substr( 1 ).toLowerCase();
|
||||
|
||||
}
|
||||
|
||||
function hash( s, e ) {
|
||||
|
||||
return "s" + Math.min( s, e ) + "e" + Math.max( s, e );
|
||||
|
||||
}
|
||||
|
||||
function parseBond( start, length ) {
|
||||
|
||||
var eatom = parseInt( lines[ i ].substr( start, length ) );
|
||||
|
||||
if ( eatom ) {
|
||||
|
||||
var h = hash( satom, eatom );
|
||||
|
||||
if ( bhash[ h ] === undefined ) {
|
||||
|
||||
bonds.push( [ satom - 1, eatom - 1, 1 ] );
|
||||
bhash[ h ] = bonds.length - 1;
|
||||
|
||||
} else {
|
||||
|
||||
// doesn't really work as almost all PDBs
|
||||
// have just normal bonds appearing multiple
|
||||
// times instead of being double/triple bonds
|
||||
// bonds[bhash[h]][2] += 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var CPK = { "h": [ 255, 255, 255 ], "he": [ 217, 255, 255 ], "li": [ 204, 128, 255 ], "be": [ 194, 255, 0 ], "b": [ 255, 181, 181 ], "c": [ 144, 144, 144 ], "n": [ 48, 80, 248 ], "o": [ 255, 13, 13 ], "f": [ 144, 224, 80 ], "ne": [ 179, 227, 245 ], "na": [ 171, 92, 242 ], "mg": [ 138, 255, 0 ], "al": [ 191, 166, 166 ], "si": [ 240, 200, 160 ], "p": [ 255, 128, 0 ], "s": [ 255, 255, 48 ], "cl": [ 31, 240, 31 ], "ar": [ 128, 209, 227 ], "k": [ 143, 64, 212 ], "ca": [ 61, 255, 0 ], "sc": [ 230, 230, 230 ], "ti": [ 191, 194, 199 ], "v": [ 166, 166, 171 ], "cr": [ 138, 153, 199 ], "mn": [ 156, 122, 199 ], "fe": [ 224, 102, 51 ], "co": [ 240, 144, 160 ], "ni": [ 80, 208, 80 ], "cu": [ 200, 128, 51 ], "zn": [ 125, 128, 176 ], "ga": [ 194, 143, 143 ], "ge": [ 102, 143, 143 ], "as": [ 189, 128, 227 ], "se": [ 255, 161, 0 ], "br": [ 166, 41, 41 ], "kr": [ 92, 184, 209 ], "rb": [ 112, 46, 176 ], "sr": [ 0, 255, 0 ], "y": [ 148, 255, 255 ], "zr": [ 148, 224, 224 ], "nb": [ 115, 194, 201 ], "mo": [ 84, 181, 181 ], "tc": [ 59, 158, 158 ], "ru": [ 36, 143, 143 ], "rh": [ 10, 125, 140 ], "pd": [ 0, 105, 133 ], "ag": [ 192, 192, 192 ], "cd": [ 255, 217, 143 ], "in": [ 166, 117, 115 ], "sn": [ 102, 128, 128 ], "sb": [ 158, 99, 181 ], "te": [ 212, 122, 0 ], "i": [ 148, 0, 148 ], "xe": [ 66, 158, 176 ], "cs": [ 87, 23, 143 ], "ba": [ 0, 201, 0 ], "la": [ 112, 212, 255 ], "ce": [ 255, 255, 199 ], "pr": [ 217, 255, 199 ], "nd": [ 199, 255, 199 ], "pm": [ 163, 255, 199 ], "sm": [ 143, 255, 199 ], "eu": [ 97, 255, 199 ], "gd": [ 69, 255, 199 ], "tb": [ 48, 255, 199 ], "dy": [ 31, 255, 199 ], "ho": [ 0, 255, 156 ], "er": [ 0, 230, 117 ], "tm": [ 0, 212, 82 ], "yb": [ 0, 191, 56 ], "lu": [ 0, 171, 36 ], "hf": [ 77, 194, 255 ], "ta": [ 77, 166, 255 ], "w": [ 33, 148, 214 ], "re": [ 38, 125, 171 ], "os": [ 38, 102, 150 ], "ir": [ 23, 84, 135 ], "pt": [ 208, 208, 224 ], "au": [ 255, 209, 35 ], "hg": [ 184, 184, 208 ], "tl": [ 166, 84, 77 ], "pb": [ 87, 89, 97 ], "bi": [ 158, 79, 181 ], "po": [ 171, 92, 0 ], "at": [ 117, 79, 69 ], "rn": [ 66, 130, 150 ], "fr": [ 66, 0, 102 ], "ra": [ 0, 125, 0 ], "ac": [ 112, 171, 250 ], "th": [ 0, 186, 255 ], "pa": [ 0, 161, 255 ], "u": [ 0, 143, 255 ], "np": [ 0, 128, 255 ], "pu": [ 0, 107, 255 ], "am": [ 84, 92, 242 ], "cm": [ 120, 92, 227 ], "bk": [ 138, 79, 227 ], "cf": [ 161, 54, 212 ], "es": [ 179, 31, 212 ], "fm": [ 179, 31, 186 ], "md": [ 179, 13, 166 ], "no": [ 189, 13, 135 ], "lr": [ 199, 0, 102 ], "rf": [ 204, 0, 89 ], "db": [ 209, 0, 79 ], "sg": [ 217, 0, 69 ], "bh": [ 224, 0, 56 ], "hs": [ 230, 0, 46 ], "mt": [ 235, 0, 38 ],
|
||||
"ds": [ 235, 0, 38 ], "rg": [ 235, 0, 38 ], "cn": [ 235, 0, 38 ], "uut": [ 235, 0, 38 ], "uuq": [ 235, 0, 38 ], "uup": [ 235, 0, 38 ], "uuh": [ 235, 0, 38 ], "uus": [ 235, 0, 38 ], "uuo": [ 235, 0, 38 ] };
|
||||
|
||||
|
||||
var atoms = [];
|
||||
var bonds = [];
|
||||
var histogram = {};
|
||||
|
||||
var bhash = {};
|
||||
|
||||
var lines = text.split( "\n" );
|
||||
|
||||
var x, y, z, e;
|
||||
|
||||
for ( var i = 0, l = lines.length; i < l; ++ i ) {
|
||||
|
||||
if ( lines[ i ].substr( 0, 4 ) == "ATOM" || lines[ i ].substr( 0, 6 ) == "HETATM" ) {
|
||||
|
||||
x = parseFloat( lines[ i ].substr( 30, 7 ) );
|
||||
y = parseFloat( lines[ i ].substr( 38, 7 ) );
|
||||
z = parseFloat( lines[ i ].substr( 46, 7 ) );
|
||||
|
||||
e = trim( lines[ i ].substr( 76, 2 ) ).toLowerCase();
|
||||
|
||||
if ( e === "" ) e = trim( lines[ i ].substr( 12, 2 ) ).toLowerCase();
|
||||
atoms.push( [ x, y, z, CPK[ e ], capitalize( e ) ] );
|
||||
|
||||
if ( histogram[ e ] === undefined ) histogram[ e ] = 1;
|
||||
else histogram[ e ] += 1;
|
||||
|
||||
} else if ( lines[ i ].substr( 0, 6 ) == "CONECT" ) {
|
||||
|
||||
var satom = parseInt( lines[ i ].substr( 6, 5 ) );
|
||||
|
||||
parseBond( 11, 5 );
|
||||
parseBond( 16, 5 );
|
||||
parseBond( 21, 5 );
|
||||
parseBond( 26, 5 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return { "ok": true, "atoms": atoms, "bonds": bonds, "histogram": histogram };
|
||||
|
||||
},
|
||||
|
||||
createModel: function ( json, callback ) {
|
||||
|
||||
var geometryAtoms = new THREE.BufferGeometry();
|
||||
var geometryBonds = new THREE.BufferGeometry();
|
||||
|
||||
var i, l;
|
||||
|
||||
var verticesAtoms = [];
|
||||
var colors = [];
|
||||
var verticesBonds = [];
|
||||
|
||||
geometryAtoms.elements = [];
|
||||
|
||||
var atoms = json.atoms;
|
||||
var bonds = json.bonds;
|
||||
|
||||
for ( i = 0, l = atoms.length; i < l; i ++ ) {
|
||||
|
||||
var atom = atoms[ i ];
|
||||
|
||||
var x = atom[ 0 ];
|
||||
var y = atom[ 1 ];
|
||||
var z = atom[ 2 ];
|
||||
|
||||
verticesAtoms.push( x, y, z );
|
||||
|
||||
var r = atom[ 3 ][ 0 ] / 255;
|
||||
var g = atom[ 3 ][ 1 ] / 255;
|
||||
var b = atom[ 3 ][ 2 ] / 255;
|
||||
|
||||
colors.push( r, g, b );
|
||||
|
||||
geometryAtoms.elements.push( atom[ 4 ] );
|
||||
|
||||
}
|
||||
|
||||
for ( i = 0, l = bonds.length; i < l; i ++ ) {
|
||||
|
||||
var bond = bonds[ i ];
|
||||
|
||||
var start = bond[ 0 ];
|
||||
var end = bond[ 1 ];
|
||||
|
||||
verticesBonds.push( verticesAtoms[ ( start * 3 ) + 0 ] );
|
||||
verticesBonds.push( verticesAtoms[ ( start * 3 ) + 1 ] );
|
||||
verticesBonds.push( verticesAtoms[ ( start * 3 ) + 2 ] );
|
||||
|
||||
verticesBonds.push( verticesAtoms[ ( end * 3 ) + 0 ] );
|
||||
verticesBonds.push( verticesAtoms[ ( end * 3 ) + 1 ] );
|
||||
verticesBonds.push( verticesAtoms[ ( end * 3 ) + 2 ] );
|
||||
|
||||
}
|
||||
|
||||
geometryAtoms.addAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) );
|
||||
geometryAtoms.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
geometryBonds.addAttribute( 'position', new THREE.Float32BufferAttribute( verticesBonds, 3 ) );
|
||||
|
||||
callback( geometryAtoms, geometryBonds, json );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
501
node_modules/three/examples/js/loaders/PLYLoader.js
generated
vendored
Normal file
501
node_modules/three/examples/js/loaders/PLYLoader.js
generated
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
/**
|
||||
* @author Wei Meng / http://about.me/menway
|
||||
*
|
||||
* Description: A THREE loader for PLY ASCII files (known as the Polygon
|
||||
* File Format or the Stanford Triangle Format).
|
||||
*
|
||||
* Limitations: ASCII decoding assumes file is UTF-8.
|
||||
*
|
||||
* Usage:
|
||||
* var loader = new THREE.PLYLoader();
|
||||
* loader.load('./models/ply/ascii/dolphins.ply', function (geometry) {
|
||||
*
|
||||
* scene.add( new THREE.Mesh( geometry ) );
|
||||
*
|
||||
* } );
|
||||
*
|
||||
* If the PLY file uses non standard property names, they can be mapped while
|
||||
* loading. For example, the following maps the properties
|
||||
* “diffuse_(red|green|blue)” in the file to standard color names.
|
||||
*
|
||||
* loader.setPropertyNameMapping( {
|
||||
* diffuse_red: 'red',
|
||||
* diffuse_green: 'green',
|
||||
* diffuse_blue: 'blue'
|
||||
* } );
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
THREE.PLYLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
this.propertyNameMapping = {};
|
||||
|
||||
};
|
||||
|
||||
THREE.PLYLoader.prototype = {
|
||||
|
||||
constructor: THREE.PLYLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
setPropertyNameMapping: function ( mapping ) {
|
||||
|
||||
this.propertyNameMapping = mapping;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
function isASCII( data ) {
|
||||
|
||||
var header = parseHeader( bin2str( data ) );
|
||||
return header.format === 'ascii';
|
||||
|
||||
}
|
||||
|
||||
function bin2str( buf ) {
|
||||
|
||||
var array_buffer = new Uint8Array( buf );
|
||||
var str = '';
|
||||
|
||||
for ( var i = 0; i < buf.byteLength; i ++ ) {
|
||||
|
||||
str += String.fromCharCode( array_buffer[ i ] ); // implicitly assumes little-endian
|
||||
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
|
||||
function parseHeader( data ) {
|
||||
|
||||
var patternHeader = /ply([\s\S]*)end_header\s/;
|
||||
var headerText = '';
|
||||
var headerLength = 0;
|
||||
var result = patternHeader.exec( data );
|
||||
|
||||
if ( result !== null ) {
|
||||
|
||||
headerText = result [ 1 ];
|
||||
headerLength = result[ 0 ].length;
|
||||
|
||||
}
|
||||
|
||||
var header = {
|
||||
comments: [],
|
||||
elements: [],
|
||||
headerLength: headerLength
|
||||
};
|
||||
|
||||
var lines = headerText.split( '\n' );
|
||||
var currentElement;
|
||||
var lineType, lineValues;
|
||||
|
||||
function make_ply_element_property( propertValues, propertyNameMapping ) {
|
||||
|
||||
var property = { type: propertValues[ 0 ] };
|
||||
|
||||
if ( property.type === 'list' ) {
|
||||
|
||||
property.name = propertValues[ 3 ];
|
||||
property.countType = propertValues[ 1 ];
|
||||
property.itemType = propertValues[ 2 ];
|
||||
|
||||
} else {
|
||||
|
||||
property.name = propertValues[ 1 ];
|
||||
|
||||
}
|
||||
|
||||
if ( property.name in propertyNameMapping ) {
|
||||
|
||||
property.name = propertyNameMapping[ property.name ];
|
||||
|
||||
}
|
||||
|
||||
return property;
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
var line = lines[ i ];
|
||||
line = line.trim();
|
||||
|
||||
if ( line === '' ) continue;
|
||||
|
||||
lineValues = line.split( /\s+/ );
|
||||
lineType = lineValues.shift();
|
||||
line = lineValues.join( ' ' );
|
||||
|
||||
switch ( lineType ) {
|
||||
|
||||
case 'format':
|
||||
|
||||
header.format = lineValues[ 0 ];
|
||||
header.version = lineValues[ 1 ];
|
||||
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
|
||||
header.comments.push( line );
|
||||
|
||||
break;
|
||||
|
||||
case 'element':
|
||||
|
||||
if ( currentElement !== undefined ) {
|
||||
|
||||
header.elements.push( currentElement );
|
||||
|
||||
}
|
||||
|
||||
currentElement = {};
|
||||
currentElement.name = lineValues[ 0 ];
|
||||
currentElement.count = parseInt( lineValues[ 1 ] );
|
||||
currentElement.properties = [];
|
||||
|
||||
break;
|
||||
|
||||
case 'property':
|
||||
|
||||
currentElement.properties.push( make_ply_element_property( lineValues, scope.propertyNameMapping ) );
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
console.log( 'unhandled', lineType, lineValues );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( currentElement !== undefined ) {
|
||||
|
||||
header.elements.push( currentElement );
|
||||
|
||||
}
|
||||
|
||||
return header;
|
||||
|
||||
}
|
||||
|
||||
function parseASCIINumber( n, type ) {
|
||||
|
||||
switch ( type ) {
|
||||
|
||||
case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint':
|
||||
case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32':
|
||||
|
||||
return parseInt( n );
|
||||
|
||||
case 'float': case 'double': case 'float32': case 'float64':
|
||||
|
||||
return parseFloat( n );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function parseASCIIElement( properties, line ) {
|
||||
|
||||
var values = line.split( /\s+/ );
|
||||
|
||||
var element = {};
|
||||
|
||||
for ( var i = 0; i < properties.length; i ++ ) {
|
||||
|
||||
if ( properties[ i ].type === 'list' ) {
|
||||
|
||||
var list = [];
|
||||
var n = parseASCIINumber( values.shift(), properties[ i ].countType );
|
||||
|
||||
for ( var j = 0; j < n; j ++ ) {
|
||||
|
||||
list.push( parseASCIINumber( values.shift(), properties[ i ].itemType ) );
|
||||
|
||||
}
|
||||
|
||||
element[ properties[ i ].name ] = list;
|
||||
|
||||
} else {
|
||||
|
||||
element[ properties[ i ].name ] = parseASCIINumber( values.shift(), properties[ i ].type );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
function parseASCII( data ) {
|
||||
|
||||
// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
|
||||
|
||||
var buffer = {
|
||||
indices : [],
|
||||
vertices : [],
|
||||
normals : [],
|
||||
uvs : [],
|
||||
colors : []
|
||||
};
|
||||
|
||||
var result;
|
||||
|
||||
var header = parseHeader( data );
|
||||
|
||||
var patternBody = /end_header\s([\s\S]*)$/;
|
||||
var body = '';
|
||||
if ( ( result = patternBody.exec( data ) ) !== null ) {
|
||||
|
||||
body = result [ 1 ];
|
||||
|
||||
}
|
||||
|
||||
var lines = body.split( '\n' );
|
||||
var currentElement = 0;
|
||||
var currentElementCount = 0;
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
var line = lines[ i ];
|
||||
line = line.trim();
|
||||
if ( line === '' ) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if ( currentElementCount >= header.elements[ currentElement ].count ) {
|
||||
|
||||
currentElement ++;
|
||||
currentElementCount = 0;
|
||||
|
||||
}
|
||||
|
||||
var element = parseASCIIElement( header.elements[ currentElement ].properties, line );
|
||||
|
||||
handleElement( buffer, header.elements[ currentElement ].name, element );
|
||||
|
||||
currentElementCount ++;
|
||||
|
||||
}
|
||||
|
||||
return postProcess( buffer );
|
||||
|
||||
}
|
||||
|
||||
function postProcess( buffer ) {
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
// mandatory buffer data
|
||||
|
||||
if ( buffer.indices.length > 0 ) {
|
||||
|
||||
geometry.setIndex( buffer.indices );
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) );
|
||||
|
||||
// optional buffer data
|
||||
|
||||
if ( buffer.normals.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( buffer.normals, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( buffer.uvs.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( buffer.colors.length > 0 ) {
|
||||
|
||||
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( buffer.colors, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
return geometry;
|
||||
|
||||
}
|
||||
|
||||
function handleElement( buffer, elementName, element ) {
|
||||
|
||||
if ( elementName === 'vertex' ) {
|
||||
|
||||
buffer.vertices.push( element.x, element.y, element.z );
|
||||
|
||||
if ( 'nx' in element && 'ny' in element && 'nz' in element ) {
|
||||
|
||||
buffer.normals.push( element.nx, element.ny, element.nz );
|
||||
|
||||
}
|
||||
|
||||
if ( 's' in element && 't' in element ) {
|
||||
|
||||
buffer.uvs.push( element.s, element.t );
|
||||
|
||||
}
|
||||
|
||||
if ( 'red' in element && 'green' in element && 'blue' in element ) {
|
||||
|
||||
buffer.colors.push( element.red / 255.0, element.green / 255.0, element.blue / 255.0 );
|
||||
|
||||
}
|
||||
|
||||
} else if ( elementName === 'face' ) {
|
||||
|
||||
var vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338
|
||||
|
||||
if ( vertex_indices.length === 3 ) {
|
||||
|
||||
buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] );
|
||||
|
||||
} else if ( vertex_indices.length === 4 ) {
|
||||
|
||||
buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 3 ] );
|
||||
buffer.indices.push( vertex_indices[ 1 ], vertex_indices[ 2 ], vertex_indices[ 3 ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function binaryRead( dataview, at, type, little_endian ) {
|
||||
|
||||
switch ( type ) {
|
||||
|
||||
// corespondences for non-specific length types here match rply:
|
||||
case 'int8': case 'char': return [ dataview.getInt8( at ), 1 ];
|
||||
case 'uint8': case 'uchar': return [ dataview.getUint8( at ), 1 ];
|
||||
case 'int16': case 'short': return [ dataview.getInt16( at, little_endian ), 2 ];
|
||||
case 'uint16': case 'ushort': return [ dataview.getUint16( at, little_endian ), 2 ];
|
||||
case 'int32': case 'int': return [ dataview.getInt32( at, little_endian ), 4 ];
|
||||
case 'uint32': case 'uint': return [ dataview.getUint32( at, little_endian ), 4 ];
|
||||
case 'float32': case 'float': return [ dataview.getFloat32( at, little_endian ), 4 ];
|
||||
case 'float64': case 'double': return [ dataview.getFloat64( at, little_endian ), 8 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function binaryReadElement( dataview, at, properties, little_endian ) {
|
||||
|
||||
var element = {};
|
||||
var result, read = 0;
|
||||
|
||||
for ( var i = 0; i < properties.length; i ++ ) {
|
||||
|
||||
if ( properties[ i ].type === 'list' ) {
|
||||
|
||||
var list = [];
|
||||
|
||||
result = binaryRead( dataview, at + read, properties[ i ].countType, little_endian );
|
||||
var n = result[ 0 ];
|
||||
read += result[ 1 ];
|
||||
|
||||
for ( var j = 0; j < n; j ++ ) {
|
||||
|
||||
result = binaryRead( dataview, at + read, properties[ i ].itemType, little_endian );
|
||||
list.push( result[ 0 ] );
|
||||
read += result[ 1 ];
|
||||
|
||||
}
|
||||
|
||||
element[ properties[ i ].name ] = list;
|
||||
|
||||
} else {
|
||||
|
||||
result = binaryRead( dataview, at + read, properties[ i ].type, little_endian );
|
||||
element[ properties[ i ].name ] = result[ 0 ];
|
||||
read += result[ 1 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return [ element, read ];
|
||||
|
||||
}
|
||||
|
||||
function parseBinary( data ) {
|
||||
|
||||
var buffer = {
|
||||
indices : [],
|
||||
vertices : [],
|
||||
normals : [],
|
||||
uvs : [],
|
||||
colors : []
|
||||
};
|
||||
|
||||
var header = parseHeader( bin2str( data ) );
|
||||
var little_endian = ( header.format === 'binary_little_endian' );
|
||||
var body = new DataView( data, header.headerLength );
|
||||
var result, loc = 0;
|
||||
|
||||
for ( var currentElement = 0; currentElement < header.elements.length; currentElement ++ ) {
|
||||
|
||||
for ( var currentElementCount = 0; currentElementCount < header.elements[ currentElement ].count; currentElementCount ++ ) {
|
||||
|
||||
result = binaryReadElement( body, loc, header.elements[ currentElement ].properties, little_endian );
|
||||
loc += result[ 1 ];
|
||||
var element = result[ 0 ];
|
||||
|
||||
handleElement( buffer, header.elements[ currentElement ].name, element );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return postProcess( buffer );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var geometry;
|
||||
var scope = this;
|
||||
|
||||
if ( data instanceof ArrayBuffer ) {
|
||||
|
||||
geometry = isASCII( data ) ? parseASCII( bin2str( data ) ) : parseBinary( data );
|
||||
|
||||
} else {
|
||||
|
||||
geometry = parseASCII( data );
|
||||
|
||||
}
|
||||
|
||||
return geometry;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
269
node_modules/three/examples/js/loaders/PVRLoader.js
generated
vendored
Normal file
269
node_modules/three/examples/js/loaders/PVRLoader.js
generated
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* PVRLoader
|
||||
* Author: pierre lepers
|
||||
* Date: 17/09/2014 11:09
|
||||
*
|
||||
* PVR v2 (legacy) parser
|
||||
* TODO : Add Support for PVR v3 format
|
||||
* TODO : implement loadMipmaps option
|
||||
*/
|
||||
|
||||
THREE.PVRLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
this._parser = THREE.PVRLoader.parse;
|
||||
|
||||
};
|
||||
|
||||
THREE.PVRLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype );
|
||||
THREE.PVRLoader.prototype.constructor = THREE.PVRLoader;
|
||||
|
||||
|
||||
THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) {
|
||||
|
||||
var headerLengthInt = 13;
|
||||
var header = new Uint32Array( buffer, 0, headerLengthInt );
|
||||
|
||||
var pvrDatas = {
|
||||
buffer: buffer,
|
||||
header : header,
|
||||
loadMipmaps : loadMipmaps
|
||||
};
|
||||
|
||||
// PVR v3
|
||||
if ( header[ 0 ] === 0x03525650 ) {
|
||||
|
||||
return THREE.PVRLoader._parseV3( pvrDatas );
|
||||
|
||||
}
|
||||
// PVR v2
|
||||
else if ( header[ 11 ] === 0x21525650 ) {
|
||||
|
||||
return THREE.PVRLoader._parseV2( pvrDatas );
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( "[THREE.PVRLoader] Unknown PVR format" );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.PVRLoader._parseV3 = function ( pvrDatas ) {
|
||||
|
||||
var header = pvrDatas.header;
|
||||
var bpp, format;
|
||||
|
||||
|
||||
var metaLen = header[ 12 ],
|
||||
pixelFormat = header[ 2 ],
|
||||
height = header[ 6 ],
|
||||
width = header[ 7 ],
|
||||
numSurfs = header[ 9 ],
|
||||
numFaces = header[ 10 ],
|
||||
numMipmaps = header[ 11 ];
|
||||
|
||||
switch ( pixelFormat ) {
|
||||
case 0 : // PVRTC 2bpp RGB
|
||||
bpp = 2;
|
||||
format = THREE.RGB_PVRTC_2BPPV1_Format;
|
||||
break;
|
||||
case 1 : // PVRTC 2bpp RGBA
|
||||
bpp = 2;
|
||||
format = THREE.RGBA_PVRTC_2BPPV1_Format;
|
||||
break;
|
||||
case 2 : // PVRTC 4bpp RGB
|
||||
bpp = 4;
|
||||
format = THREE.RGB_PVRTC_4BPPV1_Format;
|
||||
break;
|
||||
case 3 : // PVRTC 4bpp RGBA
|
||||
bpp = 4;
|
||||
format = THREE.RGBA_PVRTC_4BPPV1_Format;
|
||||
break;
|
||||
default :
|
||||
throw new Error( "pvrtc - unsupported PVR format " + pixelFormat );
|
||||
}
|
||||
|
||||
pvrDatas.dataPtr = 52 + metaLen;
|
||||
pvrDatas.bpp = bpp;
|
||||
pvrDatas.format = format;
|
||||
pvrDatas.width = width;
|
||||
pvrDatas.height = height;
|
||||
pvrDatas.numSurfaces = numFaces;
|
||||
pvrDatas.numMipmaps = numMipmaps;
|
||||
|
||||
pvrDatas.isCubemap = ( numFaces === 6 );
|
||||
|
||||
return THREE.PVRLoader._extract( pvrDatas );
|
||||
|
||||
};
|
||||
|
||||
THREE.PVRLoader._parseV2 = function ( pvrDatas ) {
|
||||
|
||||
var header = pvrDatas.header;
|
||||
|
||||
var headerLength = header[ 0 ],
|
||||
height = header[ 1 ],
|
||||
width = header[ 2 ],
|
||||
numMipmaps = header[ 3 ],
|
||||
flags = header[ 4 ],
|
||||
dataLength = header[ 5 ],
|
||||
bpp = header[ 6 ],
|
||||
bitmaskRed = header[ 7 ],
|
||||
bitmaskGreen = header[ 8 ],
|
||||
bitmaskBlue = header[ 9 ],
|
||||
bitmaskAlpha = header[ 10 ],
|
||||
pvrTag = header[ 11 ],
|
||||
numSurfs = header[ 12 ];
|
||||
|
||||
|
||||
var TYPE_MASK = 0xff;
|
||||
var PVRTC_2 = 24,
|
||||
PVRTC_4 = 25;
|
||||
|
||||
var formatFlags = flags & TYPE_MASK;
|
||||
|
||||
|
||||
|
||||
var bpp, format;
|
||||
var _hasAlpha = bitmaskAlpha > 0;
|
||||
|
||||
if ( formatFlags === PVRTC_4 ) {
|
||||
|
||||
format = _hasAlpha ? THREE.RGBA_PVRTC_4BPPV1_Format : THREE.RGB_PVRTC_4BPPV1_Format;
|
||||
bpp = 4;
|
||||
|
||||
} else if ( formatFlags === PVRTC_2 ) {
|
||||
|
||||
format = _hasAlpha ? THREE.RGBA_PVRTC_2BPPV1_Format : THREE.RGB_PVRTC_2BPPV1_Format;
|
||||
bpp = 2;
|
||||
|
||||
} else
|
||||
throw new Error( "pvrtc - unknown format " + formatFlags );
|
||||
|
||||
|
||||
|
||||
pvrDatas.dataPtr = headerLength;
|
||||
pvrDatas.bpp = bpp;
|
||||
pvrDatas.format = format;
|
||||
pvrDatas.width = width;
|
||||
pvrDatas.height = height;
|
||||
pvrDatas.numSurfaces = numSurfs;
|
||||
pvrDatas.numMipmaps = numMipmaps + 1;
|
||||
|
||||
// guess cubemap type seems tricky in v2
|
||||
// it juste a pvr containing 6 surface (no explicit cubemap type)
|
||||
pvrDatas.isCubemap = ( numSurfs === 6 );
|
||||
|
||||
return THREE.PVRLoader._extract( pvrDatas );
|
||||
|
||||
};
|
||||
|
||||
|
||||
THREE.PVRLoader._extract = function ( pvrDatas ) {
|
||||
|
||||
var pvr = {
|
||||
mipmaps: [],
|
||||
width: pvrDatas.width,
|
||||
height: pvrDatas.height,
|
||||
format: pvrDatas.format,
|
||||
mipmapCount: pvrDatas.numMipmaps,
|
||||
isCubemap : pvrDatas.isCubemap
|
||||
};
|
||||
|
||||
var buffer = pvrDatas.buffer;
|
||||
|
||||
|
||||
|
||||
// console.log( "--------------------------" );
|
||||
|
||||
// console.log( "headerLength ", headerLength);
|
||||
// console.log( "height ", height );
|
||||
// console.log( "width ", width );
|
||||
// console.log( "numMipmaps ", numMipmaps );
|
||||
// console.log( "flags ", flags );
|
||||
// console.log( "dataLength ", dataLength );
|
||||
// console.log( "bpp ", bpp );
|
||||
// console.log( "bitmaskRed ", bitmaskRed );
|
||||
// console.log( "bitmaskGreen ", bitmaskGreen);
|
||||
// console.log( "bitmaskBlue ", bitmaskBlue );
|
||||
// console.log( "bitmaskAlpha ", bitmaskAlpha);
|
||||
// console.log( "pvrTag ", pvrTag );
|
||||
// console.log( "numSurfs ", numSurfs );
|
||||
|
||||
|
||||
|
||||
|
||||
var dataOffset = pvrDatas.dataPtr,
|
||||
bpp = pvrDatas.bpp,
|
||||
numSurfs = pvrDatas.numSurfaces,
|
||||
dataSize = 0,
|
||||
blockSize = 0,
|
||||
blockWidth = 0,
|
||||
blockHeight = 0,
|
||||
widthBlocks = 0,
|
||||
heightBlocks = 0;
|
||||
|
||||
|
||||
|
||||
if ( bpp === 2 ) {
|
||||
|
||||
blockWidth = 8;
|
||||
blockHeight = 4;
|
||||
|
||||
} else {
|
||||
|
||||
blockWidth = 4;
|
||||
blockHeight = 4;
|
||||
|
||||
}
|
||||
|
||||
blockSize = ( blockWidth * blockHeight ) * bpp / 8;
|
||||
|
||||
pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
|
||||
|
||||
var mipLevel = 0;
|
||||
|
||||
while ( mipLevel < pvrDatas.numMipmaps ) {
|
||||
|
||||
var sWidth = pvrDatas.width >> mipLevel,
|
||||
sHeight = pvrDatas.height >> mipLevel;
|
||||
|
||||
widthBlocks = sWidth / blockWidth;
|
||||
heightBlocks = sHeight / blockHeight;
|
||||
|
||||
// Clamp to minimum number of blocks
|
||||
if ( widthBlocks < 2 )
|
||||
widthBlocks = 2;
|
||||
if ( heightBlocks < 2 )
|
||||
heightBlocks = 2;
|
||||
|
||||
dataSize = widthBlocks * heightBlocks * blockSize;
|
||||
|
||||
|
||||
for ( var surfIndex = 0; surfIndex < numSurfs; surfIndex ++ ) {
|
||||
|
||||
var byteArray = new Uint8Array( buffer, dataOffset, dataSize );
|
||||
|
||||
var mipmap = {
|
||||
data: byteArray,
|
||||
width: sWidth,
|
||||
height: sHeight
|
||||
};
|
||||
|
||||
pvr.mipmaps[ surfIndex * pvrDatas.numMipmaps + mipLevel ] = mipmap;
|
||||
|
||||
dataOffset += dataSize;
|
||||
|
||||
|
||||
}
|
||||
|
||||
mipLevel ++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return pvr;
|
||||
|
||||
};
|
||||
169
node_modules/three/examples/js/loaders/PlayCanvasLoader.js
generated
vendored
Normal file
169
node_modules/three/examples/js/loaders/PlayCanvasLoader.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.PlayCanvasLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.PlayCanvasLoader.prototype = {
|
||||
|
||||
constructor: THREE.PlayCanvasLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( JSON.parse( text ) ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( json ) {
|
||||
|
||||
function parseVertices( data ) {
|
||||
|
||||
var attributes = {};
|
||||
|
||||
for ( var name in data ) {
|
||||
|
||||
var attribute = data[ name ];
|
||||
|
||||
var type = attribute.type;
|
||||
var size = attribute.components;
|
||||
|
||||
var array;
|
||||
|
||||
if ( type === 'float32' ) array = new Float32Array( attribute.data );
|
||||
if ( array === undefined ) console.log( 'PlayCanvasLoader: TODO', type );
|
||||
|
||||
attributes[ name ] = new THREE.BufferAttribute( array, size );
|
||||
|
||||
}
|
||||
|
||||
data._attributes = attributes;
|
||||
|
||||
}
|
||||
|
||||
function parseMeshes( data ) {
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
geometry.setIndex( new THREE.Uint16BufferAttribute( data.indices, 1 ) );
|
||||
|
||||
var attributes = model.vertices[ data.vertices ]._attributes;
|
||||
|
||||
for ( var name in attributes ) {
|
||||
|
||||
var attribute = attributes[ name ];
|
||||
|
||||
if ( name === 'texCoord0' ) name = 'uv';
|
||||
|
||||
geometry.addAttribute( name, attribute );
|
||||
|
||||
}
|
||||
|
||||
data._geometry = geometry;
|
||||
|
||||
}
|
||||
|
||||
function parseMeshInstances( data ) {
|
||||
|
||||
var node = model.nodes[ data.node ];
|
||||
var mesh = model.meshes[ data.mesh ];
|
||||
|
||||
if ( node._geometries === undefined ) {
|
||||
|
||||
node._geometries = [];
|
||||
|
||||
}
|
||||
|
||||
node._geometries.push( mesh._geometry );
|
||||
|
||||
}
|
||||
|
||||
function parseNodes( data ) {
|
||||
|
||||
var object = new THREE.Group();
|
||||
object.name = data.name;
|
||||
|
||||
if ( data._geometries !== undefined ) {
|
||||
|
||||
var material = new THREE.MeshPhongMaterial();
|
||||
|
||||
for ( var i = 0; i < data._geometries.length; i ++ ) {
|
||||
|
||||
var geometry = data._geometries[ i ];
|
||||
|
||||
object.add( new THREE.Mesh( geometry, material ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < data.rotation.length; i ++ ) {
|
||||
|
||||
data.rotation[ i ] *= Math.PI / 180;
|
||||
|
||||
}
|
||||
|
||||
object.position.fromArray( data.position );
|
||||
object.rotation.fromArray( data.rotation );
|
||||
object.scale.fromArray( data.scale );
|
||||
|
||||
data._object = object;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
console.log( json );
|
||||
|
||||
var model = json.model;
|
||||
|
||||
for ( var i = 0; i < model.vertices.length; i ++ ) {
|
||||
|
||||
parseVertices( model.vertices[ i ] );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < model.meshes.length; i ++ ) {
|
||||
|
||||
parseMeshes( model.meshes[ i ] );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < model.meshInstances.length; i ++ ) {
|
||||
|
||||
parseMeshInstances( model.meshInstances[ i ] );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < model.nodes.length; i ++ ) {
|
||||
|
||||
parseNodes( model.nodes[ i ] );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < model.parents.length; i ++ ) {
|
||||
|
||||
var parent = model.parents[ i ];
|
||||
|
||||
if ( parent === -1 ) continue;
|
||||
|
||||
model.nodes[ parent ]._object.add( model.nodes[ i ]._object );
|
||||
|
||||
|
||||
}
|
||||
|
||||
return model.nodes[ 0 ]._object;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
349
node_modules/three/examples/js/loaders/RGBELoader.js
generated
vendored
Normal file
349
node_modules/three/examples/js/loaders/RGBELoader.js
generated
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* @author Nikos M. / https://github.com/foo123/
|
||||
*/
|
||||
|
||||
// https://github.com/mrdoob/three.js/issues/5552
|
||||
// http://en.wikipedia.org/wiki/RGBE_image_format
|
||||
|
||||
THREE.HDRLoader = THREE.RGBELoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
// extend THREE.DataTextureLoader
|
||||
THREE.RGBELoader.prototype = Object.create( THREE.DataTextureLoader.prototype );
|
||||
|
||||
// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
|
||||
THREE.RGBELoader.prototype._parser = function( buffer ) {
|
||||
|
||||
var
|
||||
/* return codes for rgbe routines */
|
||||
RGBE_RETURN_SUCCESS = 0,
|
||||
RGBE_RETURN_FAILURE = - 1,
|
||||
|
||||
/* default error routine. change this to change error handling */
|
||||
rgbe_read_error = 1,
|
||||
rgbe_write_error = 2,
|
||||
rgbe_format_error = 3,
|
||||
rgbe_memory_error = 4,
|
||||
rgbe_error = function( rgbe_error_code, msg ) {
|
||||
|
||||
switch ( rgbe_error_code ) {
|
||||
case rgbe_read_error: console.error( "THREE.RGBELoader Read Error: " + ( msg || '' ) );
|
||||
break;
|
||||
case rgbe_write_error: console.error( "THREE.RGBELoader Write Error: " + ( msg || '' ) );
|
||||
break;
|
||||
case rgbe_format_error: console.error( "THREE.RGBELoader Bad File Format: " + ( msg || '' ) );
|
||||
break;
|
||||
default:
|
||||
case rgbe_memory_error: console.error( "THREE.RGBELoader: Error: " + ( msg || '' ) );
|
||||
}
|
||||
return RGBE_RETURN_FAILURE;
|
||||
|
||||
},
|
||||
|
||||
/* offsets to red, green, and blue components in a data (float) pixel */
|
||||
RGBE_DATA_RED = 0,
|
||||
RGBE_DATA_GREEN = 1,
|
||||
RGBE_DATA_BLUE = 2,
|
||||
|
||||
/* number of floats per pixel, use 4 since stored in rgba image format */
|
||||
RGBE_DATA_SIZE = 4,
|
||||
|
||||
/* flags indicating which fields in an rgbe_header_info are valid */
|
||||
RGBE_VALID_PROGRAMTYPE = 1,
|
||||
RGBE_VALID_FORMAT = 2,
|
||||
RGBE_VALID_DIMENSIONS = 4,
|
||||
|
||||
NEWLINE = "\n",
|
||||
|
||||
fgets = function( buffer, lineLimit, consume ) {
|
||||
|
||||
lineLimit = ! lineLimit ? 1024 : lineLimit;
|
||||
var p = buffer.pos,
|
||||
i = - 1, len = 0, s = '', chunkSize = 128,
|
||||
chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) )
|
||||
;
|
||||
while ( ( 0 > ( i = chunk.indexOf( NEWLINE ) ) ) && ( len < lineLimit ) && ( p < buffer.byteLength ) ) {
|
||||
|
||||
s += chunk; len += chunk.length;
|
||||
p += chunkSize;
|
||||
chunk += String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );
|
||||
|
||||
}
|
||||
|
||||
if ( - 1 < i ) {
|
||||
|
||||
/*for (i=l-1; i>=0; i--) {
|
||||
byteCode = m.charCodeAt(i);
|
||||
if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
|
||||
else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
|
||||
if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
|
||||
}*/
|
||||
if ( false !== consume ) buffer.pos += len + i + 1;
|
||||
return s + chunk.slice( 0, i );
|
||||
|
||||
}
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
/* minimal header reading. modify if you want to parse more information */
|
||||
RGBE_ReadHeader = function( buffer ) {
|
||||
|
||||
var line, match,
|
||||
|
||||
// regexes to parse header info fields
|
||||
magic_token_re = /^#\?(\S+)$/,
|
||||
gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/,
|
||||
exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/,
|
||||
format_re = /^\s*FORMAT=(\S+)\s*$/,
|
||||
dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/,
|
||||
|
||||
// RGBE format header struct
|
||||
header = {
|
||||
|
||||
valid: 0, /* indicate which fields are valid */
|
||||
|
||||
string: '', /* the actual header string */
|
||||
|
||||
comments: '', /* comments found in header */
|
||||
|
||||
programtype: 'RGBE', /* listed at beginning of file to identify it
|
||||
* after "#?". defaults to "RGBE" */
|
||||
|
||||
format: '', /* RGBE format, default 32-bit_rle_rgbe */
|
||||
|
||||
gamma: 1.0, /* image has already been gamma corrected with
|
||||
* given gamma. defaults to 1.0 (no correction) */
|
||||
|
||||
exposure: 1.0, /* a value of 1.0 in an image corresponds to
|
||||
* <exposure> watts/steradian/m^2.
|
||||
* defaults to 1.0 */
|
||||
|
||||
width: 0, height: 0 /* image dimensions, width/height */
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) {
|
||||
|
||||
return rgbe_error( rgbe_read_error, "no header found" );
|
||||
|
||||
}
|
||||
/* if you want to require the magic token then uncomment the next line */
|
||||
if ( ! ( match = line.match( magic_token_re ) ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "bad initial token" );
|
||||
|
||||
}
|
||||
header.valid |= RGBE_VALID_PROGRAMTYPE;
|
||||
header.programtype = match[ 1 ];
|
||||
header.string += line + "\n";
|
||||
|
||||
while ( true ) {
|
||||
|
||||
line = fgets( buffer );
|
||||
if ( false === line ) break;
|
||||
header.string += line + "\n";
|
||||
|
||||
if ( '#' === line.charAt( 0 ) ) {
|
||||
|
||||
header.comments += line + "\n";
|
||||
continue; // comment line
|
||||
|
||||
}
|
||||
|
||||
if ( match = line.match( gamma_re ) ) {
|
||||
|
||||
header.gamma = parseFloat( match[ 1 ], 10 );
|
||||
|
||||
}
|
||||
if ( match = line.match( exposure_re ) ) {
|
||||
|
||||
header.exposure = parseFloat( match[ 1 ], 10 );
|
||||
|
||||
}
|
||||
if ( match = line.match( format_re ) ) {
|
||||
|
||||
header.valid |= RGBE_VALID_FORMAT;
|
||||
header.format = match[ 1 ];//'32-bit_rle_rgbe';
|
||||
|
||||
}
|
||||
if ( match = line.match( dimensions_re ) ) {
|
||||
|
||||
header.valid |= RGBE_VALID_DIMENSIONS;
|
||||
header.height = parseInt( match[ 1 ], 10 );
|
||||
header.width = parseInt( match[ 2 ], 10 );
|
||||
|
||||
}
|
||||
|
||||
if ( ( header.valid & RGBE_VALID_FORMAT ) && ( header.valid & RGBE_VALID_DIMENSIONS ) ) break;
|
||||
|
||||
}
|
||||
|
||||
if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "missing format specifier" );
|
||||
|
||||
}
|
||||
if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "missing image size specifier" );
|
||||
|
||||
}
|
||||
|
||||
return header;
|
||||
|
||||
},
|
||||
|
||||
RGBE_ReadPixels_RLE = function( buffer, w, h ) {
|
||||
|
||||
var data_rgba, offset, pos, count, byteValue,
|
||||
scanline_buffer, ptr, ptr_end, i, l, off, isEncodedRun,
|
||||
scanline_width = w, num_scanlines = h, rgbeStart
|
||||
;
|
||||
|
||||
if (
|
||||
// run length encoding is not allowed so read flat
|
||||
( ( scanline_width < 8 ) || ( scanline_width > 0x7fff ) ) ||
|
||||
// this file is not run length encoded
|
||||
( ( 2 !== buffer[ 0 ] ) || ( 2 !== buffer[ 1 ] ) || ( buffer[ 2 ] & 0x80 ) )
|
||||
) {
|
||||
|
||||
// return the flat buffer
|
||||
return new Uint8Array( buffer );
|
||||
|
||||
}
|
||||
|
||||
if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "wrong scanline width" );
|
||||
|
||||
}
|
||||
|
||||
data_rgba = new Uint8Array( 4 * w * h );
|
||||
|
||||
if ( ! data_rgba || ! data_rgba.length ) {
|
||||
|
||||
return rgbe_error( rgbe_memory_error, "unable to allocate buffer space" );
|
||||
|
||||
}
|
||||
|
||||
offset = 0; pos = 0; ptr_end = 4 * scanline_width;
|
||||
rgbeStart = new Uint8Array( 4 );
|
||||
scanline_buffer = new Uint8Array( ptr_end );
|
||||
|
||||
// read in each successive scanline
|
||||
while ( ( num_scanlines > 0 ) && ( pos < buffer.byteLength ) ) {
|
||||
|
||||
if ( pos + 4 > buffer.byteLength ) {
|
||||
|
||||
return rgbe_error( rgbe_read_error );
|
||||
|
||||
}
|
||||
|
||||
rgbeStart[ 0 ] = buffer[ pos ++ ];
|
||||
rgbeStart[ 1 ] = buffer[ pos ++ ];
|
||||
rgbeStart[ 2 ] = buffer[ pos ++ ];
|
||||
rgbeStart[ 3 ] = buffer[ pos ++ ];
|
||||
|
||||
if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "bad rgbe scanline format" );
|
||||
|
||||
}
|
||||
|
||||
// read each of the four channels for the scanline into the buffer
|
||||
// first red, then green, then blue, then exponent
|
||||
ptr = 0;
|
||||
while ( ( ptr < ptr_end ) && ( pos < buffer.byteLength ) ) {
|
||||
|
||||
count = buffer[ pos ++ ];
|
||||
isEncodedRun = count > 128;
|
||||
if ( isEncodedRun ) count -= 128;
|
||||
|
||||
if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) {
|
||||
|
||||
return rgbe_error( rgbe_format_error, "bad scanline data" );
|
||||
|
||||
}
|
||||
|
||||
if ( isEncodedRun ) {
|
||||
|
||||
// a (encoded) run of the same value
|
||||
byteValue = buffer[ pos ++ ];
|
||||
for ( i = 0; i < count; i ++ ) {
|
||||
|
||||
scanline_buffer[ ptr ++ ] = byteValue;
|
||||
|
||||
}
|
||||
//ptr += count;
|
||||
|
||||
} else {
|
||||
|
||||
// a literal-run
|
||||
scanline_buffer.set( buffer.subarray( pos, pos + count ), ptr );
|
||||
ptr += count; pos += count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// now convert data from buffer into rgba
|
||||
// first red, then green, then blue, then exponent (alpha)
|
||||
l = scanline_width; //scanline_buffer.byteLength;
|
||||
for ( i = 0; i < l; i ++ ) {
|
||||
|
||||
off = 0;
|
||||
data_rgba[ offset ] = scanline_buffer[ i + off ];
|
||||
off += scanline_width; //1;
|
||||
data_rgba[ offset + 1 ] = scanline_buffer[ i + off ];
|
||||
off += scanline_width; //1;
|
||||
data_rgba[ offset + 2 ] = scanline_buffer[ i + off ];
|
||||
off += scanline_width; //1;
|
||||
data_rgba[ offset + 3 ] = scanline_buffer[ i + off ];
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
|
||||
num_scanlines --;
|
||||
|
||||
}
|
||||
|
||||
return data_rgba;
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
var byteArray = new Uint8Array( buffer ),
|
||||
byteLength = byteArray.byteLength;
|
||||
byteArray.pos = 0;
|
||||
var rgbe_header_info = RGBE_ReadHeader( byteArray );
|
||||
|
||||
if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) {
|
||||
|
||||
var w = rgbe_header_info.width,
|
||||
h = rgbe_header_info.height
|
||||
, image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h )
|
||||
;
|
||||
if ( RGBE_RETURN_FAILURE !== image_rgba_data ) {
|
||||
|
||||
return {
|
||||
width: w, height: h,
|
||||
data: image_rgba_data,
|
||||
header: rgbe_header_info.string,
|
||||
gamma: rgbe_header_info.gamma,
|
||||
exposure: rgbe_header_info.exposure,
|
||||
format: THREE.RGBEFormat, // handled as THREE.RGBAFormat in shaders
|
||||
type: THREE.UnsignedByteType
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
};
|
||||
280
node_modules/three/examples/js/loaders/STLLoader.js
generated
vendored
Normal file
280
node_modules/three/examples/js/loaders/STLLoader.js
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* @author aleeper / http://adamleeper.com/
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author gero3 / https://github.com/gero3
|
||||
* @author Mugen87 / https://github.com/Mugen87
|
||||
*
|
||||
* Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs.
|
||||
*
|
||||
* Supports both binary and ASCII encoded files, with automatic detection of type.
|
||||
*
|
||||
* The loader returns a non-indexed buffer geometry.
|
||||
*
|
||||
* Limitations:
|
||||
* Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL).
|
||||
* There is perhaps some question as to how valid it is to always assume little-endian-ness.
|
||||
* ASCII decoding assumes file is UTF-8.
|
||||
*
|
||||
* Usage:
|
||||
* var loader = new THREE.STLLoader();
|
||||
* loader.load( './models/stl/slotted_disk.stl', function ( geometry ) {
|
||||
* scene.add( new THREE.Mesh( geometry ) );
|
||||
* });
|
||||
*
|
||||
* For binary STLs geometry might contain colors for vertices. To use it:
|
||||
* // use the same code to load STL as above
|
||||
* if (geometry.hasColors) {
|
||||
* material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
|
||||
* } else { .... }
|
||||
* var mesh = new THREE.Mesh( geometry, material );
|
||||
*/
|
||||
|
||||
|
||||
THREE.STLLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.STLLoader.prototype = {
|
||||
|
||||
constructor: THREE.STLLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
parse: function ( data ) {
|
||||
|
||||
var isBinary = function () {
|
||||
|
||||
var expect, face_size, n_faces, reader;
|
||||
reader = new DataView( binData );
|
||||
face_size = ( 32 / 8 * 3 ) + ( ( 32 / 8 * 3 ) * 3 ) + ( 16 / 8 );
|
||||
n_faces = reader.getUint32( 80, true );
|
||||
expect = 80 + ( 32 / 8 ) + ( n_faces * face_size );
|
||||
|
||||
if ( expect === reader.byteLength ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// some binary files will have different size from expected,
|
||||
// checking characters higher than ASCII to confirm is binary
|
||||
var fileLength = reader.byteLength;
|
||||
for ( var index = 0; index < fileLength; index ++ ) {
|
||||
|
||||
if ( reader.getUint8( index, false ) > 127 ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
var binData = this.ensureBinary( data );
|
||||
|
||||
return isBinary() ? this.parseBinary( binData ) : this.parseASCII( this.ensureString( data ) );
|
||||
|
||||
},
|
||||
|
||||
parseBinary: function ( data ) {
|
||||
|
||||
var reader = new DataView( data );
|
||||
var faces = reader.getUint32( 80, true );
|
||||
|
||||
var r, g, b, hasColors = false, colors;
|
||||
var defaultR, defaultG, defaultB, alpha;
|
||||
|
||||
// process STL header
|
||||
// check for default color in header ("COLOR=rgba" sequence).
|
||||
|
||||
for ( var index = 0; index < 80 - 10; index ++ ) {
|
||||
|
||||
if ( ( reader.getUint32( index, false ) == 0x434F4C4F /*COLO*/ ) &&
|
||||
( reader.getUint8( index + 4 ) == 0x52 /*'R'*/ ) &&
|
||||
( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) {
|
||||
|
||||
hasColors = true;
|
||||
colors = [];
|
||||
|
||||
defaultR = reader.getUint8( index + 6 ) / 255;
|
||||
defaultG = reader.getUint8( index + 7 ) / 255;
|
||||
defaultB = reader.getUint8( index + 8 ) / 255;
|
||||
alpha = reader.getUint8( index + 9 ) / 255;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var dataOffset = 84;
|
||||
var faceLength = 12 * 4 + 2;
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
var vertices = [];
|
||||
var normals = [];
|
||||
|
||||
for ( var face = 0; face < faces; face ++ ) {
|
||||
|
||||
var start = dataOffset + face * faceLength;
|
||||
var normalX = reader.getFloat32( start, true );
|
||||
var normalY = reader.getFloat32( start + 4, true );
|
||||
var normalZ = reader.getFloat32( start + 8, true );
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
var packedColor = reader.getUint16( start + 48, true );
|
||||
|
||||
if ( ( packedColor & 0x8000 ) === 0 ) {
|
||||
|
||||
// facet has its own unique color
|
||||
|
||||
r = ( packedColor & 0x1F ) / 31;
|
||||
g = ( ( packedColor >> 5 ) & 0x1F ) / 31;
|
||||
b = ( ( packedColor >> 10 ) & 0x1F ) / 31;
|
||||
|
||||
} else {
|
||||
|
||||
r = defaultR;
|
||||
g = defaultG;
|
||||
b = defaultB;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 1; i <= 3; i ++ ) {
|
||||
|
||||
var vertexstart = start + i * 12;
|
||||
|
||||
vertices.push( reader.getFloat32( vertexstart, true ) );
|
||||
vertices.push( reader.getFloat32( vertexstart + 4, true ) );
|
||||
vertices.push( reader.getFloat32( vertexstart + 8, true ) );
|
||||
|
||||
normals.push( normalX, normalY, normalZ );
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
colors.push( r, g, b );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
|
||||
|
||||
if ( hasColors ) {
|
||||
|
||||
geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
|
||||
geometry.hasColors = true;
|
||||
geometry.alpha = alpha;
|
||||
|
||||
}
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
parseASCII: function ( data ) {
|
||||
|
||||
var geometry, length, patternFace, patternNormal, patternVertex, result, text;
|
||||
geometry = new THREE.BufferGeometry();
|
||||
patternFace = /facet([\s\S]*?)endfacet/g;
|
||||
|
||||
var vertices = [];
|
||||
var normals = [];
|
||||
|
||||
var normal = new THREE.Vector3();
|
||||
|
||||
while ( ( result = patternFace.exec( data ) ) !== null ) {
|
||||
|
||||
text = result[ 0 ];
|
||||
patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
|
||||
|
||||
while ( ( result = patternNormal.exec( text ) ) !== null ) {
|
||||
|
||||
normal.x = parseFloat( result[ 1 ] );
|
||||
normal.y = parseFloat( result[ 3 ] );
|
||||
normal.z = parseFloat( result[ 5 ] );
|
||||
|
||||
}
|
||||
|
||||
patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
|
||||
|
||||
while ( ( result = patternVertex.exec( text ) ) !== null ) {
|
||||
|
||||
vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) );
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
|
||||
|
||||
return geometry;
|
||||
|
||||
},
|
||||
|
||||
ensureString: function ( buf ) {
|
||||
|
||||
if ( typeof buf !== "string" ) {
|
||||
|
||||
var array_buffer = new Uint8Array( buf );
|
||||
var strArray = [];
|
||||
for ( var i = 0; i < buf.byteLength; i ++ ) {
|
||||
|
||||
strArray.push(String.fromCharCode( array_buffer[ i ] )); // implicitly assumes little-endian
|
||||
|
||||
}
|
||||
return strArray.join('');
|
||||
|
||||
} else {
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
ensureBinary: function ( buf ) {
|
||||
|
||||
if ( typeof buf === "string" ) {
|
||||
|
||||
var array_buffer = new Uint8Array( buf.length );
|
||||
for ( var i = 0; i < buf.length; i ++ ) {
|
||||
|
||||
array_buffer[ i ] = buf.charCodeAt( i ) & 0xff; // implicitly assumes little-endian
|
||||
|
||||
}
|
||||
return array_buffer.buffer || array_buffer;
|
||||
|
||||
} else {
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
33
node_modules/three/examples/js/loaders/SVGLoader.js
generated
vendored
Normal file
33
node_modules/three/examples/js/loaders/SVGLoader.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author zz85 / http://joshuakoo.com/
|
||||
*/
|
||||
|
||||
THREE.SVGLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.SVGLoader.prototype = {
|
||||
|
||||
constructor: THREE.SVGLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var parser = new DOMParser();
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.load( url, function ( svgString ) {
|
||||
|
||||
var doc = parser.parseFromString( svgString, 'image/svg+xml' ); // application/xml
|
||||
|
||||
onLoad( doc.documentElement );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
511
node_modules/three/examples/js/loaders/TGALoader.js
generated
vendored
Normal file
511
node_modules/three/examples/js/loaders/TGALoader.js
generated
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* @author Daosheng Mu / https://github.com/DaoshengMu/
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author takahirox / https://github.com/takahirox/
|
||||
*/
|
||||
|
||||
THREE.TGALoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.TGALoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var texture = new THREE.Texture();
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
|
||||
loader.load( url, function ( buffer ) {
|
||||
|
||||
texture.image = scope.parse( buffer );
|
||||
texture.needsUpdate = true;
|
||||
|
||||
if ( onLoad !== undefined ) {
|
||||
|
||||
onLoad( texture );
|
||||
|
||||
}
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
return texture;
|
||||
|
||||
};
|
||||
|
||||
// reference from vthibault, https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js
|
||||
THREE.TGALoader.prototype.parse = function ( buffer ) {
|
||||
|
||||
// TGA Constants
|
||||
var TGA_TYPE_NO_DATA = 0,
|
||||
TGA_TYPE_INDEXED = 1,
|
||||
TGA_TYPE_RGB = 2,
|
||||
TGA_TYPE_GREY = 3,
|
||||
TGA_TYPE_RLE_INDEXED = 9,
|
||||
TGA_TYPE_RLE_RGB = 10,
|
||||
TGA_TYPE_RLE_GREY = 11,
|
||||
|
||||
TGA_ORIGIN_MASK = 0x30,
|
||||
TGA_ORIGIN_SHIFT = 0x04,
|
||||
TGA_ORIGIN_BL = 0x00,
|
||||
TGA_ORIGIN_BR = 0x01,
|
||||
TGA_ORIGIN_UL = 0x02,
|
||||
TGA_ORIGIN_UR = 0x03;
|
||||
|
||||
|
||||
if ( buffer.length < 19 )
|
||||
console.error( 'THREE.TGALoader.parse: Not enough data to contain header.' );
|
||||
|
||||
var content = new Uint8Array( buffer ),
|
||||
offset = 0,
|
||||
header = {
|
||||
id_length: content[ offset ++ ],
|
||||
colormap_type: content[ offset ++ ],
|
||||
image_type: content[ offset ++ ],
|
||||
colormap_index: content[ offset ++ ] | content[ offset ++ ] << 8,
|
||||
colormap_length: content[ offset ++ ] | content[ offset ++ ] << 8,
|
||||
colormap_size: content[ offset ++ ],
|
||||
|
||||
origin: [
|
||||
content[ offset ++ ] | content[ offset ++ ] << 8,
|
||||
content[ offset ++ ] | content[ offset ++ ] << 8
|
||||
],
|
||||
width: content[ offset ++ ] | content[ offset ++ ] << 8,
|
||||
height: content[ offset ++ ] | content[ offset ++ ] << 8,
|
||||
pixel_size: content[ offset ++ ],
|
||||
flags: content[ offset ++ ]
|
||||
};
|
||||
|
||||
function tgaCheckHeader( header ) {
|
||||
|
||||
switch ( header.image_type ) {
|
||||
|
||||
// Check indexed type
|
||||
case TGA_TYPE_INDEXED:
|
||||
case TGA_TYPE_RLE_INDEXED:
|
||||
if ( header.colormap_length > 256 || header.colormap_size !== 24 || header.colormap_type !== 1 ) {
|
||||
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for indexed type' );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
// Check colormap type
|
||||
case TGA_TYPE_RGB:
|
||||
case TGA_TYPE_GREY:
|
||||
case TGA_TYPE_RLE_RGB:
|
||||
case TGA_TYPE_RLE_GREY:
|
||||
if ( header.colormap_type ) {
|
||||
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid type colormap data for colormap type' );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
// What the need of a file without data ?
|
||||
case TGA_TYPE_NO_DATA:
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: No data' );
|
||||
|
||||
// Invalid type ?
|
||||
default:
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid type " ' + header.image_type + '"' );
|
||||
|
||||
}
|
||||
|
||||
// Check image width and height
|
||||
if ( header.width <= 0 || header.height <= 0 ) {
|
||||
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid image size' );
|
||||
|
||||
}
|
||||
|
||||
// Check image pixel size
|
||||
if ( header.pixel_size !== 8 &&
|
||||
header.pixel_size !== 16 &&
|
||||
header.pixel_size !== 24 &&
|
||||
header.pixel_size !== 32 ) {
|
||||
|
||||
console.error( 'THREE.TGALoader.parse.tgaCheckHeader: Invalid pixel size "' + header.pixel_size + '"' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check tga if it is valid format
|
||||
tgaCheckHeader( header );
|
||||
|
||||
if ( header.id_length + offset > buffer.length ) {
|
||||
|
||||
console.error( 'THREE.TGALoader.parse: No data' );
|
||||
|
||||
}
|
||||
|
||||
// Skip the needn't data
|
||||
offset += header.id_length;
|
||||
|
||||
// Get targa information about RLE compression and palette
|
||||
var use_rle = false,
|
||||
use_pal = false,
|
||||
use_grey = false;
|
||||
|
||||
switch ( header.image_type ) {
|
||||
|
||||
case TGA_TYPE_RLE_INDEXED:
|
||||
use_rle = true;
|
||||
use_pal = true;
|
||||
break;
|
||||
|
||||
case TGA_TYPE_INDEXED:
|
||||
use_pal = true;
|
||||
break;
|
||||
|
||||
case TGA_TYPE_RLE_RGB:
|
||||
use_rle = true;
|
||||
break;
|
||||
|
||||
case TGA_TYPE_RGB:
|
||||
break;
|
||||
|
||||
case TGA_TYPE_RLE_GREY:
|
||||
use_rle = true;
|
||||
use_grey = true;
|
||||
break;
|
||||
|
||||
case TGA_TYPE_GREY:
|
||||
use_grey = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Parse tga image buffer
|
||||
function tgaParse( use_rle, use_pal, header, offset, data ) {
|
||||
|
||||
var pixel_data,
|
||||
pixel_size,
|
||||
pixel_total,
|
||||
palettes;
|
||||
|
||||
pixel_size = header.pixel_size >> 3;
|
||||
pixel_total = header.width * header.height * pixel_size;
|
||||
|
||||
// Read palettes
|
||||
if ( use_pal ) {
|
||||
|
||||
palettes = data.subarray( offset, offset += header.colormap_length * ( header.colormap_size >> 3 ) );
|
||||
|
||||
}
|
||||
|
||||
// Read RLE
|
||||
if ( use_rle ) {
|
||||
|
||||
pixel_data = new Uint8Array( pixel_total );
|
||||
|
||||
var c, count, i;
|
||||
var shift = 0;
|
||||
var pixels = new Uint8Array( pixel_size );
|
||||
|
||||
while ( shift < pixel_total ) {
|
||||
|
||||
c = data[ offset ++ ];
|
||||
count = ( c & 0x7f ) + 1;
|
||||
|
||||
// RLE pixels.
|
||||
if ( c & 0x80 ) {
|
||||
|
||||
// Bind pixel tmp array
|
||||
for ( i = 0; i < pixel_size; ++ i ) {
|
||||
|
||||
pixels[ i ] = data[ offset ++ ];
|
||||
|
||||
}
|
||||
|
||||
// Copy pixel array
|
||||
for ( i = 0; i < count; ++ i ) {
|
||||
|
||||
pixel_data.set( pixels, shift + i * pixel_size );
|
||||
|
||||
}
|
||||
|
||||
shift += pixel_size * count;
|
||||
|
||||
} else {
|
||||
|
||||
// Raw pixels.
|
||||
count *= pixel_size;
|
||||
for ( i = 0; i < count; ++ i ) {
|
||||
|
||||
pixel_data[ shift + i ] = data[ offset ++ ];
|
||||
|
||||
}
|
||||
shift += count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// RAW Pixels
|
||||
pixel_data = data.subarray(
|
||||
offset, offset += ( use_pal ? header.width * header.height : pixel_total )
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
pixel_data: pixel_data,
|
||||
palettes: palettes
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageData8bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image, palettes ) {
|
||||
|
||||
var colormap = palettes;
|
||||
var color, i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i ++ ) {
|
||||
|
||||
color = image[ i ];
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = 255;
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = colormap[ ( color * 3 ) + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = colormap[ ( color * 3 ) + 1 ];
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = colormap[ ( color * 3 ) + 2 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageData16bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
|
||||
|
||||
var color, i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i += 2 ) {
|
||||
|
||||
color = image[ i + 0 ] + ( image[ i + 1 ] << 8 ); // Inversed ?
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = ( color & 0x7C00 ) >> 7;
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = ( color & 0x03E0 ) >> 2;
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = ( color & 0x001F ) >> 3;
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = ( color & 0x8000 ) ? 0 : 255;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageData24bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
|
||||
|
||||
var i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i += 3 ) {
|
||||
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = 255;
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = image[ i + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = image[ i + 1 ];
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = image[ i + 2 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageData32bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
|
||||
|
||||
var i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i += 4 ) {
|
||||
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = image[ i + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = image[ i + 1 ];
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = image[ i + 2 ];
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = image[ i + 3 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageDataGrey8bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
|
||||
|
||||
var color, i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i ++ ) {
|
||||
|
||||
color = image[ i ];
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = color;
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = color;
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = color;
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = 255;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function tgaGetImageDataGrey16bits( imageData, y_start, y_step, y_end, x_start, x_step, x_end, image ) {
|
||||
|
||||
var i = 0, x, y;
|
||||
var width = header.width;
|
||||
|
||||
for ( y = y_start; y !== y_end; y += y_step ) {
|
||||
|
||||
for ( x = x_start; x !== x_end; x += x_step, i += 2 ) {
|
||||
|
||||
imageData[ ( x + width * y ) * 4 + 0 ] = image[ i + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 1 ] = image[ i + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 2 ] = image[ i + 0 ];
|
||||
imageData[ ( x + width * y ) * 4 + 3 ] = image[ i + 1 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return imageData;
|
||||
|
||||
}
|
||||
|
||||
function getTgaRGBA( data, width, height, image, palette ) {
|
||||
|
||||
var x_start,
|
||||
y_start,
|
||||
x_step,
|
||||
y_step,
|
||||
x_end,
|
||||
y_end;
|
||||
|
||||
switch ( ( header.flags & TGA_ORIGIN_MASK ) >> TGA_ORIGIN_SHIFT ) {
|
||||
default:
|
||||
case TGA_ORIGIN_UL:
|
||||
x_start = 0;
|
||||
x_step = 1;
|
||||
x_end = width;
|
||||
y_start = 0;
|
||||
y_step = 1;
|
||||
y_end = height;
|
||||
break;
|
||||
|
||||
case TGA_ORIGIN_BL:
|
||||
x_start = 0;
|
||||
x_step = 1;
|
||||
x_end = width;
|
||||
y_start = height - 1;
|
||||
y_step = - 1;
|
||||
y_end = - 1;
|
||||
break;
|
||||
|
||||
case TGA_ORIGIN_UR:
|
||||
x_start = width - 1;
|
||||
x_step = - 1;
|
||||
x_end = - 1;
|
||||
y_start = 0;
|
||||
y_step = 1;
|
||||
y_end = height;
|
||||
break;
|
||||
|
||||
case TGA_ORIGIN_BR:
|
||||
x_start = width - 1;
|
||||
x_step = - 1;
|
||||
x_end = - 1;
|
||||
y_start = height - 1;
|
||||
y_step = - 1;
|
||||
y_end = - 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( use_grey ) {
|
||||
|
||||
switch ( header.pixel_size ) {
|
||||
case 8:
|
||||
tgaGetImageDataGrey8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
|
||||
break;
|
||||
case 16:
|
||||
tgaGetImageDataGrey16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
|
||||
break;
|
||||
default:
|
||||
console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
switch ( header.pixel_size ) {
|
||||
case 8:
|
||||
tgaGetImageData8bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image, palette );
|
||||
break;
|
||||
|
||||
case 16:
|
||||
tgaGetImageData16bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
|
||||
break;
|
||||
|
||||
case 24:
|
||||
tgaGetImageData24bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
|
||||
break;
|
||||
|
||||
case 32:
|
||||
tgaGetImageData32bits( data, y_start, y_step, y_end, x_start, x_step, x_end, image );
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error( 'THREE.TGALoader.parse.getTgaRGBA: not support this format' );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load image data according to specific method
|
||||
// var func = 'tgaGetImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits';
|
||||
// func(data, y_start, y_step, y_end, x_start, x_step, x_end, width, image, palette );
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
var canvas = document.createElement( 'canvas' );
|
||||
canvas.width = header.width;
|
||||
canvas.height = header.height;
|
||||
|
||||
var context = canvas.getContext( '2d' );
|
||||
var imageData = context.createImageData( header.width, header.height );
|
||||
|
||||
var result = tgaParse( use_rle, use_pal, header, offset, content );
|
||||
var rgbaData = getTgaRGBA( imageData.data, header.width, header.height, result.pixel_data, result.palettes );
|
||||
|
||||
context.putImageData( imageData, 0, 0 );
|
||||
|
||||
return canvas;
|
||||
|
||||
};
|
||||
193
node_modules/three/examples/js/loaders/TTFLoader.js
generated
vendored
Normal file
193
node_modules/three/examples/js/loaders/TTFLoader.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @author gero3 / https://github.com/gero3
|
||||
* @author tentone / https://github.com/tentone
|
||||
* Requires opentype.js to be included in the project
|
||||
* Loads TTF files and converts them into typeface JSON that can be used directly
|
||||
* to create THREE.Font objects
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
THREE.TTFLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
this.reversed = false;
|
||||
|
||||
};
|
||||
|
||||
THREE.TTFLoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setResponseType( 'arraybuffer' );
|
||||
loader.load( url, function ( buffer ) {
|
||||
|
||||
if ( onLoad !== undefined ) {
|
||||
|
||||
onLoad( scope.parse( buffer ) );
|
||||
|
||||
}
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
};
|
||||
|
||||
THREE.TTFLoader.prototype.parse = function ( arraybuffer ) {
|
||||
|
||||
if ( typeof opentype === 'undefined' ) {
|
||||
|
||||
console.warn( 'TTFLoader requires opentype.js Make sure it\'s included before using the loader' );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
function convert( font, reversed ) {
|
||||
|
||||
var round = Math.round;
|
||||
|
||||
var glyphs = {};
|
||||
var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
|
||||
|
||||
for ( var i = 0; i < font.glyphs.length; i ++ ) {
|
||||
|
||||
var glyph = font.glyphs.glyphs[ i ];
|
||||
|
||||
if ( glyph.unicode !== undefined ) {
|
||||
|
||||
var token = {
|
||||
ha: round( glyph.advanceWidth * scale ),
|
||||
x_min: round( glyph.xMin * scale ),
|
||||
x_max: round( glyph.xMax * scale ),
|
||||
o: ''
|
||||
};
|
||||
|
||||
if ( reversed ) {
|
||||
|
||||
glyph.path.commands = reverseCommands( glyph.path.commands );
|
||||
|
||||
}
|
||||
|
||||
glyph.path.commands.forEach( function ( command, i ) {
|
||||
|
||||
if ( command.type.toLowerCase() === 'c' ) {
|
||||
|
||||
command.type = 'b';
|
||||
|
||||
}
|
||||
|
||||
token.o += command.type.toLowerCase() + ' ';
|
||||
|
||||
if ( command.x !== undefined && command.y !== undefined ) {
|
||||
|
||||
token.o += round( command.x * scale ) + ' ' + round( command.y * scale ) + ' ';
|
||||
|
||||
}
|
||||
|
||||
if ( command.x1 !== undefined && command.y1 !== undefined ) {
|
||||
|
||||
token.o += round( command.x1 * scale ) + ' ' + round( command.y1 * scale ) + ' ';
|
||||
|
||||
}
|
||||
|
||||
if ( command.x2 !== undefined && command.y2 !== undefined ) {
|
||||
|
||||
token.o += round( command.x2 * scale ) + ' ' + round( command.y2 * scale ) + ' ';
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
glyphs[ String.fromCharCode( glyph.unicode ) ] = token;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
glyphs: glyphs,
|
||||
|
||||
familyName: font.familyName,
|
||||
ascender: round( font.ascender * scale ),
|
||||
descender: round( font.descender * scale ),
|
||||
underlinePosition: font.tables.post.underlinePosition,
|
||||
underlineThickness: font.tables.post.underlineThickness,
|
||||
boundingBox: {
|
||||
xMin: font.tables.head.xMin,
|
||||
xMax: font.tables.head.xMax,
|
||||
yMin: font.tables.head.yMin,
|
||||
yMax: font.tables.head.yMax
|
||||
},
|
||||
|
||||
resolution: 1000,
|
||||
original_font_information: font.tables.name
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function reverseCommands( commands ) {
|
||||
|
||||
var paths = [];
|
||||
var path;
|
||||
|
||||
commands.forEach( function ( c ) {
|
||||
|
||||
if ( c.type.toLowerCase() === 'm' ) {
|
||||
|
||||
path = [ c ];
|
||||
paths.push( path );
|
||||
|
||||
} else if ( c.type.toLowerCase() !== 'z' ) {
|
||||
|
||||
path.push( c );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
var reversed = [];
|
||||
|
||||
paths.forEach( function ( p ) {
|
||||
|
||||
var result = {
|
||||
type: 'm',
|
||||
x: p[ p.length - 1 ].x,
|
||||
y: p[ p.length - 1 ].y
|
||||
};
|
||||
|
||||
reversed.push( result );
|
||||
|
||||
for ( var i = p.length - 1; i > 0; i -- ) {
|
||||
|
||||
var command = p[ i ];
|
||||
var result = { type: command.type };
|
||||
|
||||
if ( command.x2 !== undefined && command.y2 !== undefined ) {
|
||||
|
||||
result.x1 = command.x2;
|
||||
result.y1 = command.y2;
|
||||
result.x2 = command.x1;
|
||||
result.y2 = command.y1;
|
||||
|
||||
} else if ( command.x1 !== undefined && command.y1 !== undefined ) {
|
||||
|
||||
result.x1 = command.x1;
|
||||
result.y1 = command.y1;
|
||||
|
||||
}
|
||||
|
||||
result.x = p[ i - 1 ].x;
|
||||
result.y = p[ i - 1 ].y;
|
||||
reversed.push( result );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
return reversed;
|
||||
|
||||
}
|
||||
|
||||
return convert( opentype.parse( arraybuffer ), this.reversed );
|
||||
|
||||
};
|
||||
752
node_modules/three/examples/js/loaders/UTF8Loader.js
generated
vendored
Normal file
752
node_modules/three/examples/js/loaders/UTF8Loader.js
generated
vendored
Normal file
@@ -0,0 +1,752 @@
|
||||
/**
|
||||
* Loader for UTF8 version2 (after r51) encoded models generated by:
|
||||
* http://code.google.com/p/webgl-loader/
|
||||
*
|
||||
* Code to load/decompress mesh is taken from r100 of this webgl-loader
|
||||
*/
|
||||
|
||||
THREE.UTF8Loader = function () {};
|
||||
|
||||
/**
|
||||
* Load UTF8 encoded model
|
||||
* @param jsonUrl - URL from which to load json containing information about model
|
||||
* @param callback - Callback(THREE.Object3D) on successful loading of model
|
||||
* @param options - options on how to load model (see THREE.MTLLoader.MaterialCreator for basic options)
|
||||
* Additional options include
|
||||
* geometryBase: Base url from which to load referenced geometries
|
||||
* materialBase: Base url from which to load referenced textures
|
||||
*/
|
||||
|
||||
THREE.UTF8Loader.prototype.load = function ( jsonUrl, callback, options ) {
|
||||
|
||||
this.downloadModelJson( jsonUrl, callback, options );
|
||||
|
||||
};
|
||||
|
||||
// BufferGeometryCreator
|
||||
|
||||
THREE.UTF8Loader.BufferGeometryCreator = function () {
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.BufferGeometryCreator.prototype.create = function ( attribArray, indices ) {
|
||||
|
||||
var ntris = indices.length / 3;
|
||||
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
|
||||
var positions = new Float32Array( ntris * 3 * 3 );
|
||||
var normals = new Float32Array( ntris * 3 * 3 );
|
||||
var uvs = new Float32Array( ntris * 3 * 2 );
|
||||
|
||||
var i, j, offset;
|
||||
|
||||
var end = attribArray.length;
|
||||
var stride = 8;
|
||||
|
||||
// extract positions
|
||||
|
||||
j = 0;
|
||||
offset = 0;
|
||||
|
||||
for ( i = offset; i < end; i += stride ) {
|
||||
|
||||
positions[ j ++ ] = attribArray[ i ];
|
||||
positions[ j ++ ] = attribArray[ i + 1 ];
|
||||
positions[ j ++ ] = attribArray[ i + 2 ];
|
||||
|
||||
}
|
||||
|
||||
// extract uvs
|
||||
|
||||
j = 0;
|
||||
offset = 3;
|
||||
|
||||
for ( i = offset; i < end; i += stride ) {
|
||||
|
||||
uvs[ j ++ ] = attribArray[ i ];
|
||||
uvs[ j ++ ] = attribArray[ i + 1 ];
|
||||
}
|
||||
|
||||
// extract normals
|
||||
|
||||
j = 0;
|
||||
offset = 5;
|
||||
|
||||
for ( i = offset; i < end; i += stride ) {
|
||||
|
||||
normals[ j ++ ] = attribArray[ i ];
|
||||
normals[ j ++ ] = attribArray[ i + 1 ];
|
||||
normals[ j ++ ] = attribArray[ i + 2 ];
|
||||
|
||||
}
|
||||
|
||||
geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
|
||||
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
|
||||
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
||||
geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
|
||||
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
return geometry;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// UTF-8 decoder from webgl-loader (r100)
|
||||
// http://code.google.com/p/webgl-loader/
|
||||
|
||||
// Model manifest description. Contains objects like:
|
||||
// name: {
|
||||
// materials: { 'material_name': { ... } ... },
|
||||
// decodeParams: {
|
||||
// decodeOffsets: [ ... ],
|
||||
// decodeScales: [ ... ],
|
||||
// },
|
||||
// urls: {
|
||||
// 'url': [
|
||||
// { material: 'material_name',
|
||||
// attribRange: [#, #],
|
||||
// indexRange: [#, #],
|
||||
// names: [ 'object names' ... ],
|
||||
// lengths: [#, #, # ... ]
|
||||
// }
|
||||
// ],
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
|
||||
var DEFAULT_DECODE_PARAMS = {
|
||||
|
||||
decodeOffsets: [ -4095, -4095, -4095, 0, 0, -511, -511, -511 ],
|
||||
decodeScales: [ 1 / 8191, 1 / 8191, 1 / 8191, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023, 1 / 1023 ]
|
||||
|
||||
// TODO: normal decoding? (see walt.js)
|
||||
// needs to know: input, output (from vertex format!)
|
||||
//
|
||||
// Should split attrib/index.
|
||||
// 1) Decode position and non-normal attributes.
|
||||
// 2) Decode indices, computing normals
|
||||
// 3) Maybe normalize normals? Only necessary for refinement, or fixed?
|
||||
// 4) Maybe refine normals? Should this be part of regular refinement?
|
||||
// 5) Morphing
|
||||
|
||||
};
|
||||
|
||||
// Triangle strips!
|
||||
|
||||
// TODO: will it be an optimization to specialize this method at
|
||||
// runtime for different combinations of stride, decodeOffset and
|
||||
// decodeScale?
|
||||
|
||||
THREE.UTF8Loader.prototype.decompressAttribsInner_ = function ( str, inputStart, inputEnd,
|
||||
output, outputStart, stride,
|
||||
decodeOffset, decodeScale ) {
|
||||
|
||||
var prev = 0;
|
||||
|
||||
for ( var j = inputStart; j < inputEnd; j ++ ) {
|
||||
|
||||
var code = str.charCodeAt( j );
|
||||
prev += ( code >> 1 ) ^ ( -( code & 1 ) );
|
||||
|
||||
output[ outputStart ] = decodeScale * ( prev + decodeOffset );
|
||||
outputStart += stride;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.decompressIndices_ = function( str, inputStart, numIndices,
|
||||
output, outputStart ) {
|
||||
|
||||
var highest = 0;
|
||||
|
||||
for ( var i = 0; i < numIndices; i ++ ) {
|
||||
|
||||
var code = str.charCodeAt( inputStart ++ );
|
||||
|
||||
output[ outputStart ++ ] = highest - code;
|
||||
|
||||
if ( code === 0 ) {
|
||||
|
||||
highest ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.decompressAABBs_ = function ( str, inputStart, numBBoxen,
|
||||
decodeOffsets, decodeScales ) {
|
||||
var numFloats = 6 * numBBoxen;
|
||||
|
||||
var inputEnd = inputStart + numFloats;
|
||||
var outputStart = 0;
|
||||
|
||||
var bboxen = new Float32Array( numFloats );
|
||||
|
||||
for ( var i = inputStart; i < inputEnd; i += 6 ) {
|
||||
|
||||
var minX = str.charCodeAt(i + 0) + decodeOffsets[0];
|
||||
var minY = str.charCodeAt(i + 1) + decodeOffsets[1];
|
||||
var minZ = str.charCodeAt(i + 2) + decodeOffsets[2];
|
||||
|
||||
var radiusX = (str.charCodeAt(i + 3) + 1) >> 1;
|
||||
var radiusY = (str.charCodeAt(i + 4) + 1) >> 1;
|
||||
var radiusZ = (str.charCodeAt(i + 5) + 1) >> 1;
|
||||
|
||||
bboxen[ outputStart ++ ] = decodeScales[0] * (minX + radiusX);
|
||||
bboxen[ outputStart ++ ] = decodeScales[1] * (minY + radiusY);
|
||||
bboxen[ outputStart ++ ] = decodeScales[2] * (minZ + radiusZ);
|
||||
|
||||
bboxen[ outputStart ++ ] = decodeScales[0] * radiusX;
|
||||
bboxen[ outputStart ++ ] = decodeScales[1] * radiusY;
|
||||
bboxen[ outputStart ++ ] = decodeScales[2] * radiusZ;
|
||||
|
||||
}
|
||||
|
||||
return bboxen;
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.decompressMesh = function ( str, meshParams, decodeParams, name, idx, callback ) {
|
||||
|
||||
// Extract conversion parameters from attribArrays.
|
||||
|
||||
var stride = decodeParams.decodeScales.length;
|
||||
|
||||
var decodeOffsets = decodeParams.decodeOffsets;
|
||||
var decodeScales = decodeParams.decodeScales;
|
||||
|
||||
var attribStart = meshParams.attribRange[0];
|
||||
var numVerts = meshParams.attribRange[1];
|
||||
|
||||
// Decode attributes.
|
||||
|
||||
var inputOffset = attribStart;
|
||||
var attribsOut = new Float32Array( stride * numVerts );
|
||||
|
||||
for (var j = 0; j < stride; j ++ ) {
|
||||
|
||||
var end = inputOffset + numVerts;
|
||||
|
||||
var decodeScale = decodeScales[j];
|
||||
|
||||
if ( decodeScale ) {
|
||||
|
||||
// Assume if decodeScale is never set, simply ignore the
|
||||
// attribute.
|
||||
|
||||
this.decompressAttribsInner_( str, inputOffset, end,
|
||||
attribsOut, j, stride,
|
||||
decodeOffsets[j], decodeScale );
|
||||
}
|
||||
|
||||
inputOffset = end;
|
||||
|
||||
}
|
||||
|
||||
var indexStart = meshParams.indexRange[ 0 ];
|
||||
var numIndices = 3 * meshParams.indexRange[ 1 ];
|
||||
|
||||
var indicesOut = new Uint16Array( numIndices );
|
||||
|
||||
this.decompressIndices_( str, inputOffset, numIndices, indicesOut, 0 );
|
||||
|
||||
// Decode bboxen.
|
||||
|
||||
var bboxen = undefined;
|
||||
var bboxOffset = meshParams.bboxes;
|
||||
|
||||
if ( bboxOffset ) {
|
||||
|
||||
bboxen = this.decompressAABBs_( str, bboxOffset, meshParams.names.length, decodeOffsets, decodeScales );
|
||||
}
|
||||
|
||||
callback( name, idx, attribsOut, indicesOut, bboxen, meshParams );
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.copyAttrib = function ( stride, attribsOutFixed, lastAttrib, index ) {
|
||||
|
||||
for ( var j = 0; j < stride; j ++ ) {
|
||||
|
||||
lastAttrib[ j ] = attribsOutFixed[ stride * index + j ];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.decodeAttrib2 = function ( str, stride, decodeOffsets, decodeScales, deltaStart,
|
||||
numVerts, attribsOut, attribsOutFixed, lastAttrib,
|
||||
index ) {
|
||||
|
||||
for ( var j = 0; j < 5; j ++ ) {
|
||||
|
||||
var code = str.charCodeAt( deltaStart + numVerts * j + index );
|
||||
var delta = ( code >> 1) ^ (-(code & 1));
|
||||
|
||||
lastAttrib[ j ] += delta;
|
||||
attribsOutFixed[ stride * index + j ] = lastAttrib[ j ];
|
||||
attribsOut[ stride * index + j ] = decodeScales[ j ] * ( lastAttrib[ j ] + decodeOffsets[ j ] );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.accumulateNormal = function ( i0, i1, i2, attribsOutFixed, crosses ) {
|
||||
|
||||
var p0x = attribsOutFixed[ 8 * i0 ];
|
||||
var p0y = attribsOutFixed[ 8 * i0 + 1 ];
|
||||
var p0z = attribsOutFixed[ 8 * i0 + 2 ];
|
||||
|
||||
var p1x = attribsOutFixed[ 8 * i1 ];
|
||||
var p1y = attribsOutFixed[ 8 * i1 + 1 ];
|
||||
var p1z = attribsOutFixed[ 8 * i1 + 2 ];
|
||||
|
||||
var p2x = attribsOutFixed[ 8 * i2 ];
|
||||
var p2y = attribsOutFixed[ 8 * i2 + 1 ];
|
||||
var p2z = attribsOutFixed[ 8 * i2 + 2 ];
|
||||
|
||||
p1x -= p0x;
|
||||
p1y -= p0y;
|
||||
p1z -= p0z;
|
||||
|
||||
p2x -= p0x;
|
||||
p2y -= p0y;
|
||||
p2z -= p0z;
|
||||
|
||||
p0x = p1y * p2z - p1z * p2y;
|
||||
p0y = p1z * p2x - p1x * p2z;
|
||||
p0z = p1x * p2y - p1y * p2x;
|
||||
|
||||
crosses[ 3 * i0 ] += p0x;
|
||||
crosses[ 3 * i0 + 1 ] += p0y;
|
||||
crosses[ 3 * i0 + 2 ] += p0z;
|
||||
|
||||
crosses[ 3 * i1 ] += p0x;
|
||||
crosses[ 3 * i1 + 1 ] += p0y;
|
||||
crosses[ 3 * i1 + 2 ] += p0z;
|
||||
|
||||
crosses[ 3 * i2 ] += p0x;
|
||||
crosses[ 3 * i2 + 1 ] += p0y;
|
||||
crosses[ 3 * i2 + 2 ] += p0z;
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.decompressMesh2 = function( str, meshParams, decodeParams, name, idx, callback ) {
|
||||
|
||||
var MAX_BACKREF = 96;
|
||||
|
||||
// Extract conversion parameters from attribArrays.
|
||||
|
||||
var stride = decodeParams.decodeScales.length;
|
||||
|
||||
var decodeOffsets = decodeParams.decodeOffsets;
|
||||
var decodeScales = decodeParams.decodeScales;
|
||||
|
||||
var deltaStart = meshParams.attribRange[ 0 ];
|
||||
var numVerts = meshParams.attribRange[ 1 ];
|
||||
|
||||
var codeStart = meshParams.codeRange[ 0 ];
|
||||
var codeLength = meshParams.codeRange[ 1 ];
|
||||
|
||||
var numIndices = 3 * meshParams.codeRange[ 2 ];
|
||||
|
||||
var indicesOut = new Uint16Array( numIndices );
|
||||
|
||||
var crosses = new Int32Array( 3 * numVerts );
|
||||
|
||||
var lastAttrib = new Uint16Array( stride );
|
||||
|
||||
var attribsOutFixed = new Uint16Array( stride * numVerts );
|
||||
var attribsOut = new Float32Array( stride * numVerts );
|
||||
|
||||
var highest = 0;
|
||||
var outputStart = 0;
|
||||
|
||||
for ( var i = 0; i < numIndices; i += 3 ) {
|
||||
|
||||
var code = str.charCodeAt( codeStart ++ );
|
||||
|
||||
var max_backref = Math.min( i, MAX_BACKREF );
|
||||
|
||||
if ( code < max_backref ) {
|
||||
|
||||
// Parallelogram
|
||||
|
||||
var winding = code % 3;
|
||||
var backref = i - ( code - winding );
|
||||
var i0, i1, i2;
|
||||
|
||||
switch ( winding ) {
|
||||
|
||||
case 0:
|
||||
|
||||
i0 = indicesOut[ backref + 2 ];
|
||||
i1 = indicesOut[ backref + 1 ];
|
||||
i2 = indicesOut[ backref + 0 ];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
i0 = indicesOut[ backref + 0 ];
|
||||
i1 = indicesOut[ backref + 2 ];
|
||||
i2 = indicesOut[ backref + 1 ];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
i0 = indicesOut[ backref + 1 ];
|
||||
i1 = indicesOut[ backref + 0 ];
|
||||
i2 = indicesOut[ backref + 2 ];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
indicesOut[ outputStart ++ ] = i0;
|
||||
indicesOut[ outputStart ++ ] = i1;
|
||||
|
||||
code = str.charCodeAt( codeStart ++ );
|
||||
|
||||
var index = highest - code;
|
||||
indicesOut[ outputStart ++ ] = index;
|
||||
|
||||
if ( code === 0 ) {
|
||||
|
||||
for (var j = 0; j < 5; j ++ ) {
|
||||
|
||||
var deltaCode = str.charCodeAt( deltaStart + numVerts * j + highest );
|
||||
|
||||
var prediction = ((deltaCode >> 1) ^ (-(deltaCode & 1))) +
|
||||
attribsOutFixed[stride * i0 + j] +
|
||||
attribsOutFixed[stride * i1 + j] -
|
||||
attribsOutFixed[stride * i2 + j];
|
||||
|
||||
lastAttrib[j] = prediction;
|
||||
|
||||
attribsOutFixed[ stride * highest + j ] = prediction;
|
||||
attribsOut[ stride * highest + j ] = decodeScales[ j ] * ( prediction + decodeOffsets[ j ] );
|
||||
|
||||
}
|
||||
|
||||
highest ++;
|
||||
|
||||
} else {
|
||||
|
||||
this.copyAttrib( stride, attribsOutFixed, lastAttrib, index );
|
||||
|
||||
}
|
||||
|
||||
this.accumulateNormal( i0, i1, index, attribsOutFixed, crosses );
|
||||
|
||||
} else {
|
||||
|
||||
// Simple
|
||||
|
||||
var index0 = highest - ( code - max_backref );
|
||||
|
||||
indicesOut[ outputStart ++ ] = index0;
|
||||
|
||||
if ( code === max_backref ) {
|
||||
|
||||
this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
|
||||
numVerts, attribsOut, attribsOutFixed, lastAttrib,
|
||||
highest ++ );
|
||||
|
||||
} else {
|
||||
|
||||
this.copyAttrib(stride, attribsOutFixed, lastAttrib, index0);
|
||||
|
||||
}
|
||||
|
||||
code = str.charCodeAt( codeStart ++ );
|
||||
|
||||
var index1 = highest - code;
|
||||
indicesOut[ outputStart ++ ] = index1;
|
||||
|
||||
if ( code === 0 ) {
|
||||
|
||||
this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
|
||||
numVerts, attribsOut, attribsOutFixed, lastAttrib,
|
||||
highest ++ );
|
||||
|
||||
} else {
|
||||
|
||||
this.copyAttrib( stride, attribsOutFixed, lastAttrib, index1 );
|
||||
|
||||
}
|
||||
|
||||
code = str.charCodeAt( codeStart ++ );
|
||||
|
||||
var index2 = highest - code;
|
||||
indicesOut[ outputStart ++ ] = index2;
|
||||
|
||||
if ( code === 0 ) {
|
||||
|
||||
for ( var j = 0; j < 5; j ++ ) {
|
||||
|
||||
lastAttrib[ j ] = ( attribsOutFixed[ stride * index0 + j ] + attribsOutFixed[ stride * index1 + j ] ) / 2;
|
||||
|
||||
}
|
||||
|
||||
this.decodeAttrib2( str, stride, decodeOffsets, decodeScales, deltaStart,
|
||||
numVerts, attribsOut, attribsOutFixed, lastAttrib,
|
||||
highest ++ );
|
||||
|
||||
} else {
|
||||
|
||||
this.copyAttrib( stride, attribsOutFixed, lastAttrib, index2 );
|
||||
|
||||
}
|
||||
|
||||
this.accumulateNormal( index0, index1, index2, attribsOutFixed, crosses );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < numVerts; i ++ ) {
|
||||
|
||||
var nx = crosses[ 3 * i ];
|
||||
var ny = crosses[ 3 * i + 1 ];
|
||||
var nz = crosses[ 3 * i + 2 ];
|
||||
|
||||
var norm = 511.0 / Math.sqrt( nx * nx + ny * ny + nz * nz );
|
||||
|
||||
var cx = str.charCodeAt( deltaStart + 5 * numVerts + i );
|
||||
var cy = str.charCodeAt( deltaStart + 6 * numVerts + i );
|
||||
var cz = str.charCodeAt( deltaStart + 7 * numVerts + i );
|
||||
|
||||
attribsOut[ stride * i + 5 ] = norm * nx + ((cx >> 1) ^ (-(cx & 1)));
|
||||
attribsOut[ stride * i + 6 ] = norm * ny + ((cy >> 1) ^ (-(cy & 1)));
|
||||
attribsOut[ stride * i + 7 ] = norm * nz + ((cz >> 1) ^ (-(cz & 1)));
|
||||
}
|
||||
|
||||
callback( name, idx, attribsOut, indicesOut, undefined, meshParams );
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.downloadMesh = function ( path, name, meshEntry, decodeParams, callback ) {
|
||||
|
||||
var loader = this;
|
||||
var idx = 0;
|
||||
|
||||
function onprogress( data ) {
|
||||
|
||||
while ( idx < meshEntry.length ) {
|
||||
|
||||
var meshParams = meshEntry[ idx ];
|
||||
var indexRange = meshParams.indexRange;
|
||||
|
||||
if ( indexRange ) {
|
||||
|
||||
var meshEnd = indexRange[ 0 ] + 3 * indexRange[ 1 ];
|
||||
|
||||
if ( data.length < meshEnd ) break;
|
||||
|
||||
loader.decompressMesh( data, meshParams, decodeParams, name, idx, callback );
|
||||
|
||||
} else {
|
||||
|
||||
var codeRange = meshParams.codeRange;
|
||||
var meshEnd = codeRange[ 0 ] + codeRange[ 1 ];
|
||||
|
||||
if ( data.length < meshEnd ) break;
|
||||
|
||||
loader.decompressMesh2( data, meshParams, decodeParams, name, idx, callback );
|
||||
}
|
||||
|
||||
++ idx;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getHttpRequest( path, function( data ) {
|
||||
|
||||
onprogress( data );
|
||||
|
||||
// TODO: handle errors.
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.downloadMeshes = function ( path, meshUrlMap, decodeParams, callback ) {
|
||||
|
||||
for ( var url in meshUrlMap ) {
|
||||
|
||||
var meshEntry = meshUrlMap[url];
|
||||
this.downloadMesh( path + url, url, meshEntry, decodeParams, callback );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.createMeshCallback = function( materialBaseUrl, loadModelInfo, allDoneCallback ) {
|
||||
|
||||
var nCompletedUrls = 0;
|
||||
var nExpectedUrls = 0;
|
||||
|
||||
var expectedMeshesPerUrl = {};
|
||||
var decodedMeshesPerUrl = {};
|
||||
|
||||
var modelParts = {};
|
||||
|
||||
var meshUrlMap = loadModelInfo.urls;
|
||||
|
||||
for ( var url in meshUrlMap ) {
|
||||
|
||||
expectedMeshesPerUrl[ url ] = meshUrlMap[ url ].length;
|
||||
decodedMeshesPerUrl[ url ] = 0;
|
||||
|
||||
nExpectedUrls ++;
|
||||
|
||||
modelParts[ url ] = new THREE.Object3D();
|
||||
|
||||
}
|
||||
|
||||
var model = new THREE.Object3D();
|
||||
|
||||
// Prepare materials first...
|
||||
|
||||
var materialCreator = new THREE.MTLLoader.MaterialCreator( materialBaseUrl, loadModelInfo.options );
|
||||
materialCreator.setMaterials( loadModelInfo.materials );
|
||||
|
||||
materialCreator.preload();
|
||||
|
||||
// Create callback for creating mesh parts
|
||||
|
||||
var bufferGeometryCreator = new THREE.UTF8Loader.BufferGeometryCreator();
|
||||
|
||||
var meshCallback = function( name, idx, attribArray, indexArray, bboxen, meshParams ) {
|
||||
|
||||
// Got ourselves a new mesh
|
||||
|
||||
// name identifies this part of the model (url)
|
||||
// idx is the mesh index of this mesh of the part
|
||||
// attribArray defines the vertices
|
||||
// indexArray defines the faces
|
||||
// bboxen defines the bounding box
|
||||
// meshParams contains the material info
|
||||
|
||||
var geometry = bufferGeometryCreator.create( attribArray, indexArray );
|
||||
var material = materialCreator.create( meshParams.material );
|
||||
|
||||
var mesh = new THREE.Mesh( geometry, material );
|
||||
modelParts[ name ].add( mesh );
|
||||
|
||||
//model.add(new THREE.Mesh(geometry, material));
|
||||
|
||||
decodedMeshesPerUrl[ name ] ++;
|
||||
|
||||
if ( decodedMeshesPerUrl[ name ] === expectedMeshesPerUrl[ name ] ) {
|
||||
|
||||
nCompletedUrls ++;
|
||||
|
||||
model.add( modelParts[ name ] );
|
||||
|
||||
if ( nCompletedUrls === nExpectedUrls ) {
|
||||
|
||||
// ALL DONE!!!
|
||||
|
||||
allDoneCallback( model );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return meshCallback;
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.downloadModel = function ( geometryBase, materialBase, model, callback ) {
|
||||
|
||||
var meshCallback = this.createMeshCallback( materialBase, model, callback );
|
||||
this.downloadMeshes( geometryBase, model.urls, model.decodeParams, meshCallback );
|
||||
|
||||
};
|
||||
|
||||
THREE.UTF8Loader.prototype.downloadModelJson = function ( jsonUrl, callback, options ) {
|
||||
|
||||
getJsonRequest( jsonUrl, function( loaded ) {
|
||||
|
||||
if ( ! loaded.decodeParams ) {
|
||||
|
||||
if ( options && options.decodeParams ) {
|
||||
|
||||
loaded.decodeParams = options.decodeParams;
|
||||
|
||||
} else {
|
||||
|
||||
loaded.decodeParams = DEFAULT_DECODE_PARAMS;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loaded.options = options;
|
||||
|
||||
var geometryBase = jsonUrl.substr( 0, jsonUrl.lastIndexOf( "/" ) + 1 );
|
||||
var materialBase = geometryBase;
|
||||
|
||||
if ( options && options.geometryBase ) {
|
||||
|
||||
geometryBase = options.geometryBase;
|
||||
|
||||
if ( geometryBase.charAt( geometryBase.length - 1 ) !== "/" ) {
|
||||
|
||||
geometryBase = geometryBase + "/";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( options && options.materialBase ) {
|
||||
|
||||
materialBase = options.materialBase;
|
||||
|
||||
if ( materialBase.charAt( materialBase.length - 1 ) !== "/" ) {
|
||||
|
||||
materialBase = materialBase + "/";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.downloadModel( geometryBase, materialBase, loaded, callback );
|
||||
|
||||
}.bind( this ) );
|
||||
|
||||
};
|
||||
|
||||
// XMLHttpRequest stuff
|
||||
|
||||
function getHttpRequest( url, onload, opt_onprogress ) {
|
||||
|
||||
var req = new THREE.FileLoader();
|
||||
req.load( url, onload, opt_onprogress );
|
||||
|
||||
}
|
||||
|
||||
function getJsonRequest( url, onjson ) {
|
||||
|
||||
getHttpRequest( url,
|
||||
function( e ) { onjson( JSON.parse( e ) ); },
|
||||
function() {} );
|
||||
|
||||
}
|
||||
|
||||
function addListeners( dom, listeners ) {
|
||||
|
||||
// TODO: handle event capture, object binding.
|
||||
|
||||
for ( var key in listeners ) {
|
||||
|
||||
dom.addEventListener( key, listeners[ key ] );
|
||||
|
||||
}
|
||||
}
|
||||
1105
node_modules/three/examples/js/loaders/VRMLLoader.js
generated
vendored
Normal file
1105
node_modules/three/examples/js/loaders/VRMLLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1109
node_modules/three/examples/js/loaders/VTKLoader.js
generated
vendored
Normal file
1109
node_modules/three/examples/js/loaders/VTKLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
407
node_modules/three/examples/js/loaders/collada/Animation.js
generated
vendored
Normal file
407
node_modules/three/examples/js/loaders/collada/Animation.js
generated
vendored
Normal file
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
* @author mikael emtinger / http://gomo.se/
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.Animation = function ( root, data ) {
|
||||
|
||||
this.root = root;
|
||||
this.data = THREE.AnimationHandler.init( data );
|
||||
this.hierarchy = THREE.AnimationHandler.parse( root );
|
||||
|
||||
this.currentTime = 0;
|
||||
this.timeScale = 1;
|
||||
|
||||
this.isPlaying = false;
|
||||
this.loop = true;
|
||||
this.weight = 0;
|
||||
|
||||
this.interpolationType = THREE.AnimationHandler.LINEAR;
|
||||
|
||||
};
|
||||
|
||||
THREE.Animation.prototype = {
|
||||
|
||||
constructor: THREE.Animation,
|
||||
|
||||
keyTypes: [ "pos", "rot", "scl" ],
|
||||
|
||||
play: function ( startTime, weight ) {
|
||||
|
||||
this.currentTime = startTime !== undefined ? startTime : 0;
|
||||
this.weight = weight !== undefined ? weight : 1;
|
||||
|
||||
this.isPlaying = true;
|
||||
|
||||
this.reset();
|
||||
|
||||
THREE.AnimationHandler.play( this );
|
||||
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
|
||||
this.isPlaying = false;
|
||||
|
||||
THREE.AnimationHandler.stop( this );
|
||||
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
|
||||
for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
|
||||
|
||||
var object = this.hierarchy[ h ];
|
||||
|
||||
if ( object.animationCache === undefined ) {
|
||||
|
||||
object.animationCache = {
|
||||
animations: {},
|
||||
blending: {
|
||||
positionWeight: 0.0,
|
||||
quaternionWeight: 0.0,
|
||||
scaleWeight: 0.0
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
var name = this.data.name;
|
||||
var animations = object.animationCache.animations;
|
||||
var animationCache = animations[ name ];
|
||||
|
||||
if ( animationCache === undefined ) {
|
||||
|
||||
animationCache = {
|
||||
prevKey: { pos: 0, rot: 0, scl: 0 },
|
||||
nextKey: { pos: 0, rot: 0, scl: 0 },
|
||||
originalMatrix: object.matrix
|
||||
};
|
||||
|
||||
animations[ name ] = animationCache;
|
||||
|
||||
}
|
||||
|
||||
// Get keys to match our current time
|
||||
|
||||
for ( var t = 0; t < 3; t ++ ) {
|
||||
|
||||
var type = this.keyTypes[ t ];
|
||||
|
||||
var prevKey = this.data.hierarchy[ h ].keys[ 0 ];
|
||||
var nextKey = this.getNextKeyWith( type, h, 1 );
|
||||
|
||||
while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {
|
||||
|
||||
prevKey = nextKey;
|
||||
nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
|
||||
|
||||
}
|
||||
|
||||
animationCache.prevKey[ type ] = prevKey;
|
||||
animationCache.nextKey[ type ] = nextKey;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
resetBlendWeights: function () {
|
||||
|
||||
for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
|
||||
|
||||
var object = this.hierarchy[ h ];
|
||||
var animationCache = object.animationCache;
|
||||
|
||||
if ( animationCache !== undefined ) {
|
||||
|
||||
var blending = animationCache.blending;
|
||||
|
||||
blending.positionWeight = 0.0;
|
||||
blending.quaternionWeight = 0.0;
|
||||
blending.scaleWeight = 0.0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
update: ( function() {
|
||||
|
||||
var points = [];
|
||||
var target = new THREE.Vector3();
|
||||
var newVector = new THREE.Vector3();
|
||||
var newQuat = new THREE.Quaternion();
|
||||
|
||||
// Catmull-Rom spline
|
||||
|
||||
var interpolateCatmullRom = function ( points, scale ) {
|
||||
|
||||
var c = [], v3 = [],
|
||||
point, intPoint, weight, w2, w3,
|
||||
pa, pb, pc, pd;
|
||||
|
||||
point = ( points.length - 1 ) * scale;
|
||||
intPoint = Math.floor( point );
|
||||
weight = point - intPoint;
|
||||
|
||||
c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
|
||||
c[ 1 ] = intPoint;
|
||||
c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
|
||||
c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
|
||||
|
||||
pa = points[ c[ 0 ] ];
|
||||
pb = points[ c[ 1 ] ];
|
||||
pc = points[ c[ 2 ] ];
|
||||
pd = points[ c[ 3 ] ];
|
||||
|
||||
w2 = weight * weight;
|
||||
w3 = weight * w2;
|
||||
|
||||
v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
|
||||
v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
|
||||
v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );
|
||||
|
||||
return v3;
|
||||
|
||||
};
|
||||
|
||||
var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {
|
||||
|
||||
var v0 = ( p2 - p0 ) * 0.5,
|
||||
v1 = ( p3 - p1 ) * 0.5;
|
||||
|
||||
return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
|
||||
|
||||
};
|
||||
|
||||
return function ( delta ) {
|
||||
|
||||
if ( this.isPlaying === false ) return;
|
||||
|
||||
this.currentTime += delta * this.timeScale;
|
||||
|
||||
if ( this.weight === 0 )
|
||||
return;
|
||||
|
||||
//
|
||||
|
||||
var duration = this.data.length;
|
||||
|
||||
if ( this.currentTime > duration || this.currentTime < 0 ) {
|
||||
|
||||
if ( this.loop ) {
|
||||
|
||||
this.currentTime %= duration;
|
||||
|
||||
if ( this.currentTime < 0 )
|
||||
this.currentTime += duration;
|
||||
|
||||
this.reset();
|
||||
|
||||
} else {
|
||||
|
||||
this.stop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
|
||||
|
||||
var object = this.hierarchy[ h ];
|
||||
var animationCache = object.animationCache.animations[ this.data.name ];
|
||||
var blending = object.animationCache.blending;
|
||||
|
||||
// loop through pos/rot/scl
|
||||
|
||||
for ( var t = 0; t < 3; t ++ ) {
|
||||
|
||||
// get keys
|
||||
|
||||
var type = this.keyTypes[ t ];
|
||||
var prevKey = animationCache.prevKey[ type ];
|
||||
var nextKey = animationCache.nextKey[ type ];
|
||||
|
||||
if ( ( this.timeScale > 0 && nextKey.time <= this.currentTime ) ||
|
||||
( this.timeScale < 0 && prevKey.time >= this.currentTime ) ) {
|
||||
|
||||
prevKey = this.data.hierarchy[ h ].keys[ 0 ];
|
||||
nextKey = this.getNextKeyWith( type, h, 1 );
|
||||
|
||||
while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {
|
||||
|
||||
prevKey = nextKey;
|
||||
nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
|
||||
|
||||
}
|
||||
|
||||
animationCache.prevKey[ type ] = prevKey;
|
||||
animationCache.nextKey[ type ] = nextKey;
|
||||
|
||||
}
|
||||
|
||||
var scale = ( this.currentTime - prevKey.time ) / ( nextKey.time - prevKey.time );
|
||||
|
||||
var prevXYZ = prevKey[ type ];
|
||||
var nextXYZ = nextKey[ type ];
|
||||
|
||||
if ( scale < 0 ) scale = 0;
|
||||
if ( scale > 1 ) scale = 1;
|
||||
|
||||
// interpolate
|
||||
|
||||
if ( type === "pos" ) {
|
||||
|
||||
if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) {
|
||||
|
||||
newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
|
||||
newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
|
||||
newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
|
||||
|
||||
// blend
|
||||
var proportionalWeight = this.weight / ( this.weight + blending.positionWeight );
|
||||
object.position.lerp( newVector, proportionalWeight );
|
||||
blending.positionWeight += this.weight;
|
||||
|
||||
} else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
|
||||
this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
|
||||
|
||||
points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ];
|
||||
points[ 1 ] = prevXYZ;
|
||||
points[ 2 ] = nextXYZ;
|
||||
points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ];
|
||||
|
||||
scale = scale * 0.33 + 0.33;
|
||||
|
||||
var currentPoint = interpolateCatmullRom( points, scale );
|
||||
var proportionalWeight = this.weight / ( this.weight + blending.positionWeight );
|
||||
blending.positionWeight += this.weight;
|
||||
|
||||
// blend
|
||||
|
||||
var vector = object.position;
|
||||
|
||||
vector.x = vector.x + ( currentPoint[ 0 ] - vector.x ) * proportionalWeight;
|
||||
vector.y = vector.y + ( currentPoint[ 1 ] - vector.y ) * proportionalWeight;
|
||||
vector.z = vector.z + ( currentPoint[ 2 ] - vector.z ) * proportionalWeight;
|
||||
|
||||
if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
|
||||
|
||||
var forwardPoint = interpolateCatmullRom( points, scale * 1.01 );
|
||||
|
||||
target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] );
|
||||
target.sub( vector );
|
||||
target.y = 0;
|
||||
target.normalize();
|
||||
|
||||
var angle = Math.atan2( target.x, target.z );
|
||||
object.rotation.set( 0, angle, 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( type === "rot" ) {
|
||||
|
||||
THREE.Quaternion.slerp( prevXYZ, nextXYZ, newQuat, scale );
|
||||
|
||||
// Avoid paying the cost of an additional slerp if we don't have to
|
||||
if ( blending.quaternionWeight === 0 ) {
|
||||
|
||||
object.quaternion.copy( newQuat );
|
||||
blending.quaternionWeight = this.weight;
|
||||
|
||||
} else {
|
||||
|
||||
var proportionalWeight = this.weight / ( this.weight + blending.quaternionWeight );
|
||||
THREE.Quaternion.slerp( object.quaternion, newQuat, object.quaternion, proportionalWeight );
|
||||
blending.quaternionWeight += this.weight;
|
||||
|
||||
}
|
||||
|
||||
} else if ( type === "scl" ) {
|
||||
|
||||
newVector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
|
||||
newVector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
|
||||
newVector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
|
||||
|
||||
var proportionalWeight = this.weight / ( this.weight + blending.scaleWeight );
|
||||
object.scale.lerp( newVector, proportionalWeight );
|
||||
blending.scaleWeight += this.weight;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
} )(),
|
||||
|
||||
getNextKeyWith: function ( type, h, key ) {
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys;
|
||||
|
||||
if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
|
||||
this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
|
||||
|
||||
key = key < keys.length - 1 ? key : keys.length - 1;
|
||||
|
||||
} else {
|
||||
|
||||
key = key % keys.length;
|
||||
|
||||
}
|
||||
|
||||
for ( ; key < keys.length; key ++ ) {
|
||||
|
||||
if ( keys[ key ][ type ] !== undefined ) {
|
||||
|
||||
return keys[ key ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this.data.hierarchy[ h ].keys[ 0 ];
|
||||
|
||||
},
|
||||
|
||||
getPrevKeyWith: function ( type, h, key ) {
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys;
|
||||
|
||||
if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
|
||||
this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
|
||||
|
||||
key = key > 0 ? key : 0;
|
||||
|
||||
} else {
|
||||
|
||||
key = key >= 0 ? key : key + keys.length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
for ( ; key >= 0; key -- ) {
|
||||
|
||||
if ( keys[ key ][ type ] !== undefined ) {
|
||||
|
||||
return keys[ key ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this.data.hierarchy[ h ].keys[ keys.length - 1 ];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
220
node_modules/three/examples/js/loaders/collada/AnimationHandler.js
generated
vendored
Normal file
220
node_modules/three/examples/js/loaders/collada/AnimationHandler.js
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* @author mikael emtinger / http://gomo.se/
|
||||
*/
|
||||
|
||||
THREE.AnimationHandler = {
|
||||
|
||||
LINEAR: 0,
|
||||
CATMULLROM: 1,
|
||||
CATMULLROM_FORWARD: 2,
|
||||
|
||||
//
|
||||
|
||||
add: function () {
|
||||
|
||||
console.warn( 'THREE.AnimationHandler.add() has been deprecated.' );
|
||||
|
||||
},
|
||||
get: function () {
|
||||
|
||||
console.warn( 'THREE.AnimationHandler.get() has been deprecated.' );
|
||||
|
||||
},
|
||||
remove: function () {
|
||||
|
||||
console.warn( 'THREE.AnimationHandler.remove() has been deprecated.' );
|
||||
|
||||
},
|
||||
|
||||
//
|
||||
|
||||
animations: [],
|
||||
|
||||
init: function ( data ) {
|
||||
|
||||
if ( data.initialized === true ) return data;
|
||||
|
||||
// loop through all keys
|
||||
|
||||
for ( var h = 0; h < data.hierarchy.length; h ++ ) {
|
||||
|
||||
for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
|
||||
|
||||
// remove minus times
|
||||
|
||||
if ( data.hierarchy[ h ].keys[ k ].time < 0 ) {
|
||||
|
||||
data.hierarchy[ h ].keys[ k ].time = 0;
|
||||
|
||||
}
|
||||
|
||||
// create quaternions
|
||||
|
||||
if ( data.hierarchy[ h ].keys[ k ].rot !== undefined &&
|
||||
! ( data.hierarchy[ h ].keys[ k ].rot instanceof THREE.Quaternion ) ) {
|
||||
|
||||
var quat = data.hierarchy[ h ].keys[ k ].rot;
|
||||
data.hierarchy[ h ].keys[ k ].rot = new THREE.Quaternion().fromArray( quat );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// prepare morph target keys
|
||||
|
||||
if ( data.hierarchy[ h ].keys.length && data.hierarchy[ h ].keys[ 0 ].morphTargets !== undefined ) {
|
||||
|
||||
// get all used
|
||||
|
||||
var usedMorphTargets = {};
|
||||
|
||||
for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
|
||||
|
||||
for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
|
||||
|
||||
var morphTargetName = data.hierarchy[ h ].keys[ k ].morphTargets[ m ];
|
||||
usedMorphTargets[ morphTargetName ] = - 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data.hierarchy[ h ].usedMorphTargets = usedMorphTargets;
|
||||
|
||||
|
||||
// set all used on all frames
|
||||
|
||||
for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
|
||||
|
||||
var influences = {};
|
||||
|
||||
for ( var morphTargetName in usedMorphTargets ) {
|
||||
|
||||
for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
|
||||
|
||||
if ( data.hierarchy[ h ].keys[ k ].morphTargets[ m ] === morphTargetName ) {
|
||||
|
||||
influences[ morphTargetName ] = data.hierarchy[ h ].keys[ k ].morphTargetsInfluences[ m ];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( m === data.hierarchy[ h ].keys[ k ].morphTargets.length ) {
|
||||
|
||||
influences[ morphTargetName ] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data.hierarchy[ h ].keys[ k ].morphTargetsInfluences = influences;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// remove all keys that are on the same time
|
||||
|
||||
for ( var k = 1; k < data.hierarchy[ h ].keys.length; k ++ ) {
|
||||
|
||||
if ( data.hierarchy[ h ].keys[ k ].time === data.hierarchy[ h ].keys[ k - 1 ].time ) {
|
||||
|
||||
data.hierarchy[ h ].keys.splice( k, 1 );
|
||||
k --;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// set index
|
||||
|
||||
for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
|
||||
|
||||
data.hierarchy[ h ].keys[ k ].index = k;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data.initialized = true;
|
||||
|
||||
return data;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( root ) {
|
||||
|
||||
var parseRecurseHierarchy = function ( root, hierarchy ) {
|
||||
|
||||
hierarchy.push( root );
|
||||
|
||||
for ( var c = 0; c < root.children.length; c ++ )
|
||||
parseRecurseHierarchy( root.children[ c ], hierarchy );
|
||||
|
||||
};
|
||||
|
||||
// setup hierarchy
|
||||
|
||||
var hierarchy = [];
|
||||
|
||||
if ( root instanceof THREE.SkinnedMesh ) {
|
||||
|
||||
for ( var b = 0; b < root.skeleton.bones.length; b ++ ) {
|
||||
|
||||
hierarchy.push( root.skeleton.bones[ b ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
parseRecurseHierarchy( root, hierarchy );
|
||||
|
||||
}
|
||||
|
||||
return hierarchy;
|
||||
|
||||
},
|
||||
|
||||
play: function ( animation ) {
|
||||
|
||||
if ( this.animations.indexOf( animation ) === - 1 ) {
|
||||
|
||||
this.animations.push( animation );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
stop: function ( animation ) {
|
||||
|
||||
var index = this.animations.indexOf( animation );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
this.animations.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
update: function ( deltaTimeMS ) {
|
||||
|
||||
for ( var i = 0; i < this.animations.length; i ++ ) {
|
||||
|
||||
this.animations[ i ].resetBlendWeights();
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < this.animations.length; i ++ ) {
|
||||
|
||||
this.animations[ i ].update( deltaTimeMS );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
236
node_modules/three/examples/js/loaders/collada/KeyFrameAnimation.js
generated
vendored
Normal file
236
node_modules/three/examples/js/loaders/collada/KeyFrameAnimation.js
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* @author mikael emtinger / http://gomo.se/
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author khang duong
|
||||
* @author erik kitson
|
||||
*/
|
||||
|
||||
THREE.KeyFrameAnimation = function ( data ) {
|
||||
|
||||
this.root = data.node;
|
||||
this.data = THREE.AnimationHandler.init( data );
|
||||
this.hierarchy = THREE.AnimationHandler.parse( this.root );
|
||||
this.currentTime = 0;
|
||||
this.timeScale = 0.001;
|
||||
this.isPlaying = false;
|
||||
this.isPaused = true;
|
||||
this.loop = true;
|
||||
|
||||
// initialize to first keyframes
|
||||
|
||||
for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys,
|
||||
sids = this.data.hierarchy[ h ].sids,
|
||||
obj = this.hierarchy[ h ];
|
||||
|
||||
if ( keys.length && sids ) {
|
||||
|
||||
for ( var s = 0; s < sids.length; s ++ ) {
|
||||
|
||||
var sid = sids[ s ],
|
||||
next = this.getNextKeyWith( sid, h, 0 );
|
||||
|
||||
if ( next ) {
|
||||
|
||||
next.apply( sid );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
obj.matrixAutoUpdate = false;
|
||||
this.data.hierarchy[ h ].node.updateMatrix();
|
||||
obj.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.KeyFrameAnimation.prototype = {
|
||||
|
||||
constructor: THREE.KeyFrameAnimation,
|
||||
|
||||
play: function ( startTime ) {
|
||||
|
||||
this.currentTime = startTime !== undefined ? startTime : 0;
|
||||
|
||||
if ( this.isPlaying === false ) {
|
||||
|
||||
this.isPlaying = true;
|
||||
|
||||
// reset key cache
|
||||
|
||||
var h, hl = this.hierarchy.length,
|
||||
object,
|
||||
node;
|
||||
|
||||
for ( h = 0; h < hl; h ++ ) {
|
||||
|
||||
object = this.hierarchy[ h ];
|
||||
node = this.data.hierarchy[ h ];
|
||||
|
||||
if ( node.animationCache === undefined ) {
|
||||
|
||||
node.animationCache = {};
|
||||
node.animationCache.prevKey = null;
|
||||
node.animationCache.nextKey = null;
|
||||
node.animationCache.originalMatrix = object.matrix;
|
||||
|
||||
}
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys;
|
||||
|
||||
if ( keys.length > 1 ) {
|
||||
|
||||
node.animationCache.prevKey = keys[ 0 ];
|
||||
node.animationCache.nextKey = keys[ 1 ];
|
||||
|
||||
this.startTime = Math.min( keys[ 0 ].time, this.startTime );
|
||||
this.endTime = Math.max( keys[ keys.length - 1 ].time, this.endTime );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.update( 0 );
|
||||
|
||||
}
|
||||
|
||||
this.isPaused = false;
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
|
||||
this.isPlaying = false;
|
||||
this.isPaused = false;
|
||||
|
||||
// reset JIT matrix and remove cache
|
||||
|
||||
for ( var h = 0; h < this.data.hierarchy.length; h ++ ) {
|
||||
|
||||
var obj = this.hierarchy[ h ];
|
||||
var node = this.data.hierarchy[ h ];
|
||||
|
||||
if ( node.animationCache !== undefined ) {
|
||||
|
||||
var original = node.animationCache.originalMatrix;
|
||||
|
||||
original.copy( obj.matrix );
|
||||
obj.matrix = original;
|
||||
|
||||
delete node.animationCache;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
update: function ( delta ) {
|
||||
|
||||
if ( this.isPlaying === false ) return;
|
||||
|
||||
this.currentTime += delta * this.timeScale;
|
||||
|
||||
//
|
||||
|
||||
var duration = this.data.length;
|
||||
|
||||
if ( this.loop === true && this.currentTime > duration ) {
|
||||
|
||||
this.currentTime %= duration;
|
||||
|
||||
}
|
||||
|
||||
this.currentTime = Math.min( this.currentTime, duration );
|
||||
|
||||
for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
|
||||
|
||||
var object = this.hierarchy[ h ];
|
||||
var node = this.data.hierarchy[ h ];
|
||||
|
||||
var keys = node.keys,
|
||||
animationCache = node.animationCache;
|
||||
|
||||
|
||||
if ( keys.length ) {
|
||||
|
||||
var prevKey = animationCache.prevKey;
|
||||
var nextKey = animationCache.nextKey;
|
||||
|
||||
if ( nextKey.time <= this.currentTime ) {
|
||||
|
||||
while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {
|
||||
|
||||
prevKey = nextKey;
|
||||
nextKey = keys[ prevKey.index + 1 ];
|
||||
|
||||
}
|
||||
|
||||
animationCache.prevKey = prevKey;
|
||||
animationCache.nextKey = nextKey;
|
||||
|
||||
}
|
||||
|
||||
if ( nextKey.time >= this.currentTime ) {
|
||||
|
||||
prevKey.interpolate( nextKey, this.currentTime );
|
||||
|
||||
} else {
|
||||
|
||||
prevKey.interpolate( nextKey, nextKey.time );
|
||||
|
||||
}
|
||||
|
||||
this.data.hierarchy[ h ].node.updateMatrix();
|
||||
object.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getNextKeyWith: function ( sid, h, key ) {
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys;
|
||||
key = key % keys.length;
|
||||
|
||||
for ( ; key < keys.length; key ++ ) {
|
||||
|
||||
if ( keys[ key ].hasTarget( sid ) ) {
|
||||
|
||||
return keys[ key ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return keys[ 0 ];
|
||||
|
||||
},
|
||||
|
||||
getPrevKeyWith: function ( sid, h, key ) {
|
||||
|
||||
var keys = this.data.hierarchy[ h ].keys;
|
||||
key = key >= 0 ? key : key + keys.length;
|
||||
|
||||
for ( ; key >= 0; key -- ) {
|
||||
|
||||
if ( keys[ key ].hasTarget( sid ) ) {
|
||||
|
||||
return keys[ key ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return keys[ keys.length - 1 ];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
257
node_modules/three/examples/js/loaders/ctm/CTMLoader.js
generated
vendored
Normal file
257
node_modules/three/examples/js/loaders/ctm/CTMLoader.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* Loader for CTM encoded models generated by OpenCTM tools:
|
||||
* http://openctm.sourceforge.net/
|
||||
*
|
||||
* Uses js-openctm library by Juan Mellado
|
||||
* http://code.google.com/p/js-openctm/
|
||||
*
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.CTMLoader = function () {
|
||||
|
||||
THREE.Loader.call( this );
|
||||
|
||||
};
|
||||
|
||||
THREE.CTMLoader.prototype = Object.create( THREE.Loader.prototype );
|
||||
THREE.CTMLoader.prototype.constructor = THREE.CTMLoader;
|
||||
|
||||
// Load multiple CTM parts defined in JSON
|
||||
|
||||
THREE.CTMLoader.prototype.loadParts = function( url, callback, parameters ) {
|
||||
|
||||
parameters = parameters || {};
|
||||
|
||||
var scope = this;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
var basePath = parameters.basePath ? parameters.basePath : this.extractUrlBase( url );
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
|
||||
if ( xhr.readyState === 4 ) {
|
||||
|
||||
if ( xhr.status === 200 || xhr.status === 0 ) {
|
||||
|
||||
var jsonObject = JSON.parse( xhr.responseText );
|
||||
|
||||
var materials = [], geometries = [], counter = 0;
|
||||
|
||||
function callbackFinal( geometry ) {
|
||||
|
||||
counter += 1;
|
||||
|
||||
geometries.push( geometry );
|
||||
|
||||
if ( counter === jsonObject.offsets.length ) {
|
||||
|
||||
callback( geometries, materials );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// init materials
|
||||
|
||||
for ( var i = 0; i < jsonObject.materials.length; i ++ ) {
|
||||
|
||||
materials[ i ] = scope.createMaterial( jsonObject.materials[ i ], basePath );
|
||||
|
||||
}
|
||||
|
||||
// load joined CTM file
|
||||
|
||||
var partUrl = basePath + jsonObject.data;
|
||||
var parametersPart = { useWorker: parameters.useWorker, worker:parameters.worker, offsets: jsonObject.offsets };
|
||||
scope.load( partUrl, callbackFinal, parametersPart );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
xhr.open( "GET", url, true );
|
||||
xhr.setRequestHeader( "Content-Type", "text/plain" );
|
||||
xhr.send( null );
|
||||
|
||||
};
|
||||
|
||||
// Load CTMLoader compressed models
|
||||
// - parameters
|
||||
// - url (required)
|
||||
// - callback (required)
|
||||
|
||||
THREE.CTMLoader.prototype.load = function( url, callback, parameters ) {
|
||||
|
||||
parameters = parameters || {};
|
||||
|
||||
var scope = this;
|
||||
|
||||
var offsets = parameters.offsets !== undefined ? parameters.offsets : [ 0 ];
|
||||
|
||||
var xhr = new XMLHttpRequest(),
|
||||
callbackProgress = null;
|
||||
|
||||
var length = 0;
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
|
||||
if ( xhr.readyState === 4 ) {
|
||||
|
||||
if ( xhr.status === 200 || xhr.status === 0 ) {
|
||||
|
||||
var binaryData = new Uint8Array(xhr.response);
|
||||
|
||||
var s = Date.now();
|
||||
|
||||
if ( parameters.useWorker ) {
|
||||
|
||||
var worker = parameters.worker || new Worker( "js/loaders/ctm/CTMWorker.js" );
|
||||
|
||||
worker.onmessage = function( event ) {
|
||||
|
||||
var files = event.data;
|
||||
|
||||
for ( var i = 0; i < files.length; i ++ ) {
|
||||
|
||||
var ctmFile = files[ i ];
|
||||
|
||||
var e1 = Date.now();
|
||||
// console.log( "CTM data parse time [worker]: " + (e1-s) + " ms" );
|
||||
|
||||
scope.createModel( ctmFile, callback );
|
||||
|
||||
var e = Date.now();
|
||||
console.log( "model load time [worker]: " + (e - e1) + " ms, total: " + (e - s));
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
worker.postMessage( { "data": binaryData, "offsets": offsets } );
|
||||
|
||||
} else {
|
||||
|
||||
for ( var i = 0; i < offsets.length; i ++ ) {
|
||||
|
||||
var stream = new CTM.Stream( binaryData );
|
||||
stream.offset = offsets[ i ];
|
||||
|
||||
var ctmFile = new CTM.File( stream );
|
||||
|
||||
scope.createModel( ctmFile, callback );
|
||||
|
||||
}
|
||||
|
||||
//var e = Date.now();
|
||||
//console.log( "CTM data parse time [inline]: " + (e-s) + " ms" );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" );
|
||||
|
||||
}
|
||||
|
||||
} else if ( xhr.readyState === 3 ) {
|
||||
|
||||
if ( callbackProgress ) {
|
||||
|
||||
if ( length === 0 ) {
|
||||
|
||||
length = xhr.getResponseHeader( "Content-Length" );
|
||||
|
||||
}
|
||||
|
||||
callbackProgress( { total: length, loaded: xhr.responseText.length } );
|
||||
|
||||
}
|
||||
|
||||
} else if ( xhr.readyState === 2 ) {
|
||||
|
||||
length = xhr.getResponseHeader( "Content-Length" );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
xhr.open( "GET", url, true );
|
||||
xhr.responseType = "arraybuffer";
|
||||
|
||||
xhr.send( null );
|
||||
|
||||
};
|
||||
|
||||
|
||||
THREE.CTMLoader.prototype.createModel = function ( file, callback ) {
|
||||
|
||||
var Model = function () {
|
||||
|
||||
THREE.BufferGeometry.call( this );
|
||||
|
||||
this.materials = [];
|
||||
|
||||
var indices = file.body.indices,
|
||||
positions = file.body.vertices,
|
||||
normals = file.body.normals;
|
||||
|
||||
var uvs, colors;
|
||||
|
||||
var uvMaps = file.body.uvMaps;
|
||||
|
||||
if ( uvMaps !== undefined && uvMaps.length > 0 ) {
|
||||
|
||||
uvs = uvMaps[ 0 ].uv;
|
||||
|
||||
}
|
||||
|
||||
var attrMaps = file.body.attrMaps;
|
||||
|
||||
if ( attrMaps !== undefined && attrMaps.length > 0 && attrMaps[ 0 ].name === 'Color' ) {
|
||||
|
||||
colors = attrMaps[ 0 ].attr;
|
||||
|
||||
}
|
||||
|
||||
this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
|
||||
this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
|
||||
|
||||
if ( normals !== undefined ) {
|
||||
|
||||
this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( uvs !== undefined ) {
|
||||
|
||||
this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( colors !== undefined ) {
|
||||
|
||||
this.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Model.prototype = Object.create( THREE.BufferGeometry.prototype );
|
||||
Model.prototype.constructor = Model;
|
||||
|
||||
var geometry = new Model();
|
||||
|
||||
// compute vertex normals if not present in the CTM model
|
||||
if ( geometry.attributes.normal === undefined ) {
|
||||
geometry.computeVertexNormals();
|
||||
}
|
||||
|
||||
callback( geometry );
|
||||
|
||||
};
|
||||
19
node_modules/three/examples/js/loaders/ctm/CTMWorker.js
generated
vendored
Normal file
19
node_modules/three/examples/js/loaders/ctm/CTMWorker.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
importScripts( "lzma.js", "ctm.js" );
|
||||
|
||||
self.onmessage = function( event ) {
|
||||
|
||||
var files = [];
|
||||
|
||||
for ( var i = 0; i < event.data.offsets.length; i ++ ) {
|
||||
|
||||
var stream = new CTM.Stream( event.data.data );
|
||||
stream.offset = event.data.offsets[ i ];
|
||||
|
||||
files[ i ] = new CTM.File( stream );
|
||||
|
||||
}
|
||||
|
||||
self.postMessage( files );
|
||||
self.close();
|
||||
|
||||
};
|
||||
661
node_modules/three/examples/js/loaders/ctm/ctm.js
generated
vendored
Normal file
661
node_modules/three/examples/js/loaders/ctm/ctm.js
generated
vendored
Normal file
@@ -0,0 +1,661 @@
|
||||
/*
|
||||
Copyright (c) 2011 Juan Mellado
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
References:
|
||||
- "OpenCTM: The Open Compressed Triangle Mesh file format" by Marcus Geelnard
|
||||
http://openctm.sourceforge.net/
|
||||
*/
|
||||
|
||||
var CTM = CTM || {};
|
||||
|
||||
// browserify support
|
||||
if ( typeof module === 'object' ) {
|
||||
|
||||
module.exports = CTM;
|
||||
|
||||
}
|
||||
|
||||
CTM.CompressionMethod = {
|
||||
RAW: 0x00574152,
|
||||
MG1: 0x0031474d,
|
||||
MG2: 0x0032474d
|
||||
};
|
||||
|
||||
CTM.Flags = {
|
||||
NORMALS: 0x00000001
|
||||
};
|
||||
|
||||
CTM.File = function(stream) {
|
||||
this.load(stream);
|
||||
};
|
||||
|
||||
CTM.File.prototype.load = function(stream) {
|
||||
this.header = new CTM.FileHeader(stream);
|
||||
|
||||
this.body = new CTM.FileBody(this.header);
|
||||
|
||||
this.getReader().read(stream, this.body);
|
||||
};
|
||||
|
||||
CTM.File.prototype.getReader = function() {
|
||||
var reader;
|
||||
|
||||
switch (this.header.compressionMethod){
|
||||
case CTM.CompressionMethod.RAW:
|
||||
reader = new CTM.ReaderRAW();
|
||||
break;
|
||||
case CTM.CompressionMethod.MG1:
|
||||
reader = new CTM.ReaderMG1();
|
||||
break;
|
||||
case CTM.CompressionMethod.MG2:
|
||||
reader = new CTM.ReaderMG2();
|
||||
break;
|
||||
}
|
||||
|
||||
return reader;
|
||||
};
|
||||
|
||||
CTM.FileHeader = function(stream) {
|
||||
stream.readInt32(); //magic "OCTM"
|
||||
this.fileFormat = stream.readInt32();
|
||||
this.compressionMethod = stream.readInt32();
|
||||
this.vertexCount = stream.readInt32();
|
||||
this.triangleCount = stream.readInt32();
|
||||
this.uvMapCount = stream.readInt32();
|
||||
this.attrMapCount = stream.readInt32();
|
||||
this.flags = stream.readInt32();
|
||||
this.comment = stream.readString();
|
||||
};
|
||||
|
||||
CTM.FileHeader.prototype.hasNormals = function() {
|
||||
return this.flags & CTM.Flags.NORMALS;
|
||||
};
|
||||
|
||||
CTM.FileBody = function(header) {
|
||||
var i = header.triangleCount * 3,
|
||||
v = header.vertexCount * 3,
|
||||
n = header.hasNormals() ? header.vertexCount * 3 : 0,
|
||||
u = header.vertexCount * 2,
|
||||
a = header.vertexCount * 4,
|
||||
j = 0;
|
||||
|
||||
var data = new ArrayBuffer(
|
||||
(i + v + n + (u * header.uvMapCount) + (a * header.attrMapCount) ) * 4);
|
||||
|
||||
this.indices = new Uint32Array(data, 0, i);
|
||||
|
||||
this.vertices = new Float32Array(data, i * 4, v);
|
||||
|
||||
if ( header.hasNormals() ) {
|
||||
this.normals = new Float32Array(data, (i + v) * 4, n);
|
||||
}
|
||||
|
||||
if (header.uvMapCount) {
|
||||
this.uvMaps = [];
|
||||
for (j = 0; j < header.uvMapCount; ++ j) {
|
||||
this.uvMaps[j] = { uv: new Float32Array(data,
|
||||
(i + v + n + (j * u) ) * 4, u) };
|
||||
}
|
||||
}
|
||||
|
||||
if (header.attrMapCount) {
|
||||
this.attrMaps = [];
|
||||
for (j = 0; j < header.attrMapCount; ++ j) {
|
||||
this.attrMaps[j] = { attr: new Float32Array(data,
|
||||
(i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CTM.FileMG2Header = function(stream) {
|
||||
stream.readInt32(); //magic "MG2H"
|
||||
this.vertexPrecision = stream.readFloat32();
|
||||
this.normalPrecision = stream.readFloat32();
|
||||
this.lowerBoundx = stream.readFloat32();
|
||||
this.lowerBoundy = stream.readFloat32();
|
||||
this.lowerBoundz = stream.readFloat32();
|
||||
this.higherBoundx = stream.readFloat32();
|
||||
this.higherBoundy = stream.readFloat32();
|
||||
this.higherBoundz = stream.readFloat32();
|
||||
this.divx = stream.readInt32();
|
||||
this.divy = stream.readInt32();
|
||||
this.divz = stream.readInt32();
|
||||
|
||||
this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx;
|
||||
this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy;
|
||||
this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz;
|
||||
};
|
||||
|
||||
CTM.ReaderRAW = function() {
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.read = function(stream, body) {
|
||||
this.readIndices(stream, body.indices);
|
||||
this.readVertices(stream, body.vertices);
|
||||
|
||||
if (body.normals) {
|
||||
this.readNormals(stream, body.normals);
|
||||
}
|
||||
if (body.uvMaps) {
|
||||
this.readUVMaps(stream, body.uvMaps);
|
||||
}
|
||||
if (body.attrMaps) {
|
||||
this.readAttrMaps(stream, body.attrMaps);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.readIndices = function(stream, indices) {
|
||||
stream.readInt32(); //magic "INDX"
|
||||
stream.readArrayInt32(indices);
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.readVertices = function(stream, vertices) {
|
||||
stream.readInt32(); //magic "VERT"
|
||||
stream.readArrayFloat32(vertices);
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.readNormals = function(stream, normals) {
|
||||
stream.readInt32(); //magic "NORM"
|
||||
stream.readArrayFloat32(normals);
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps) {
|
||||
var i = 0;
|
||||
for (; i < uvMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "TEXC"
|
||||
|
||||
uvMaps[i].name = stream.readString();
|
||||
uvMaps[i].filename = stream.readString();
|
||||
stream.readArrayFloat32(uvMaps[i].uv);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps) {
|
||||
var i = 0;
|
||||
for (; i < attrMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "ATTR"
|
||||
|
||||
attrMaps[i].name = stream.readString();
|
||||
stream.readArrayFloat32(attrMaps[i].attr);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG1 = function() {
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.read = function(stream, body) {
|
||||
this.readIndices(stream, body.indices);
|
||||
this.readVertices(stream, body.vertices);
|
||||
|
||||
if (body.normals) {
|
||||
this.readNormals(stream, body.normals);
|
||||
}
|
||||
if (body.uvMaps) {
|
||||
this.readUVMaps(stream, body.uvMaps);
|
||||
}
|
||||
if (body.attrMaps) {
|
||||
this.readAttrMaps(stream, body.attrMaps);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.readIndices = function(stream, indices) {
|
||||
stream.readInt32(); //magic "INDX"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(indices, 3);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
CTM.restoreIndices(indices, indices.length);
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.readVertices = function(stream, vertices) {
|
||||
stream.readInt32(); //magic "VERT"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(vertices, 1);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.readNormals = function(stream, normals) {
|
||||
stream.readInt32(); //magic "NORM"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(normals, 3);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps) {
|
||||
var i = 0;
|
||||
for (; i < uvMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "TEXC"
|
||||
|
||||
uvMaps[i].name = stream.readString();
|
||||
uvMaps[i].filename = stream.readString();
|
||||
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps) {
|
||||
var i = 0;
|
||||
for (; i < attrMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "ATTR"
|
||||
|
||||
attrMaps[i].name = stream.readString();
|
||||
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG2 = function() {
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.read = function(stream, body) {
|
||||
this.MG2Header = new CTM.FileMG2Header(stream);
|
||||
|
||||
this.readVertices(stream, body.vertices);
|
||||
this.readIndices(stream, body.indices);
|
||||
|
||||
if (body.normals) {
|
||||
this.readNormals(stream, body);
|
||||
}
|
||||
if (body.uvMaps) {
|
||||
this.readUVMaps(stream, body.uvMaps);
|
||||
}
|
||||
if (body.attrMaps) {
|
||||
this.readAttrMaps(stream, body.attrMaps);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readVertices = function(stream, vertices) {
|
||||
stream.readInt32(); //magic "VERT"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(vertices, 3);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
var gridIndices = this.readGridIndices(stream, vertices);
|
||||
|
||||
CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision);
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices) {
|
||||
stream.readInt32(); //magic "GIDX"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var gridIndices = new Uint32Array(vertices.length / 3);
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(gridIndices, 1);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
CTM.restoreGridIndices(gridIndices, gridIndices.length);
|
||||
|
||||
return gridIndices;
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readIndices = function(stream, indices) {
|
||||
stream.readInt32(); //magic "INDX"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(indices, 3);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
CTM.restoreIndices(indices, indices.length);
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readNormals = function(stream, body) {
|
||||
stream.readInt32(); //magic "NORM"
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(body.normals, 3);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
var smooth = CTM.calcSmoothNormals(body.indices, body.vertices);
|
||||
|
||||
CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision);
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps) {
|
||||
var i = 0;
|
||||
for (; i < uvMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "TEXC"
|
||||
|
||||
uvMaps[i].name = stream.readString();
|
||||
uvMaps[i].filename = stream.readString();
|
||||
|
||||
var precision = stream.readFloat32();
|
||||
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
CTM.restoreMap(uvMaps[i].uv, 2, precision);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps) {
|
||||
var i = 0;
|
||||
for (; i < attrMaps.length; ++ i) {
|
||||
stream.readInt32(); //magic "ATTR"
|
||||
|
||||
attrMaps[i].name = stream.readString();
|
||||
|
||||
var precision = stream.readFloat32();
|
||||
|
||||
stream.readInt32(); //packed size
|
||||
|
||||
var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4);
|
||||
LZMA.decompress(stream, stream, interleaved, interleaved.data.length);
|
||||
|
||||
CTM.restoreMap(attrMaps[i].attr, 4, precision);
|
||||
}
|
||||
};
|
||||
|
||||
CTM.restoreIndices = function(indices, len) {
|
||||
var i = 3;
|
||||
if (len > 0) {
|
||||
indices[2] += indices[0];
|
||||
indices[1] += indices[0];
|
||||
}
|
||||
for (; i < len; i += 3) {
|
||||
indices[i] += indices[i - 3];
|
||||
|
||||
if (indices[i] === indices[i - 3]) {
|
||||
indices[i + 1] += indices[i - 2];
|
||||
}else {
|
||||
indices[i + 1] += indices[i];
|
||||
}
|
||||
|
||||
indices[i + 2] += indices[i];
|
||||
}
|
||||
};
|
||||
|
||||
CTM.restoreGridIndices = function(gridIndices, len) {
|
||||
var i = 1;
|
||||
for (; i < len; ++ i) {
|
||||
gridIndices[i] += gridIndices[i - 1];
|
||||
}
|
||||
};
|
||||
|
||||
CTM.restoreVertices = function(vertices, grid, gridIndices, precision) {
|
||||
var gridIdx, delta, x, y, z,
|
||||
intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length),
|
||||
ydiv = grid.divx, zdiv = ydiv * grid.divy,
|
||||
prevGridIdx = 0x7fffffff, prevDelta = 0,
|
||||
i = 0, j = 0, len = gridIndices.length;
|
||||
|
||||
for (; i < len; j += 3) {
|
||||
x = gridIdx = gridIndices[i ++];
|
||||
|
||||
z = ~~(x / zdiv);
|
||||
x -= ~~(z * zdiv);
|
||||
y = ~~(x / ydiv);
|
||||
x -= ~~(y * ydiv);
|
||||
|
||||
delta = intVertices[j];
|
||||
if (gridIdx === prevGridIdx) {
|
||||
delta += prevDelta;
|
||||
}
|
||||
|
||||
vertices[j] = grid.lowerBoundx +
|
||||
x * grid.sizex + precision * delta;
|
||||
vertices[j + 1] = grid.lowerBoundy +
|
||||
y * grid.sizey + precision * intVertices[j + 1];
|
||||
vertices[j + 2] = grid.lowerBoundz +
|
||||
z * grid.sizez + precision * intVertices[j + 2];
|
||||
|
||||
prevGridIdx = gridIdx;
|
||||
prevDelta = delta;
|
||||
}
|
||||
};
|
||||
|
||||
CTM.restoreNormals = function(normals, smooth, precision) {
|
||||
var ro, phi, theta, sinPhi,
|
||||
nx, ny, nz, by, bz, len,
|
||||
intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length),
|
||||
i = 0, k = normals.length,
|
||||
PI_DIV_2 = 3.141592653589793238462643 * 0.5;
|
||||
|
||||
for (; i < k; i += 3) {
|
||||
ro = intNormals[i] * precision;
|
||||
phi = intNormals[i + 1];
|
||||
|
||||
if (phi === 0) {
|
||||
normals[i] = smooth[i] * ro;
|
||||
normals[i + 1] = smooth[i + 1] * ro;
|
||||
normals[i + 2] = smooth[i + 2] * ro;
|
||||
}else {
|
||||
|
||||
if (phi <= 4) {
|
||||
theta = (intNormals[i + 2] - 2) * PI_DIV_2;
|
||||
}else {
|
||||
theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2;
|
||||
}
|
||||
|
||||
phi *= precision * PI_DIV_2;
|
||||
sinPhi = ro * Math.sin(phi);
|
||||
|
||||
nx = sinPhi * Math.cos(theta);
|
||||
ny = sinPhi * Math.sin(theta);
|
||||
nz = ro * Math.cos(phi);
|
||||
|
||||
bz = smooth[i + 1];
|
||||
by = smooth[i] - smooth[i + 2];
|
||||
|
||||
len = Math.sqrt(2 * bz * bz + by * by);
|
||||
if (len > 1e-20) {
|
||||
by /= len;
|
||||
bz /= len;
|
||||
}
|
||||
|
||||
normals[i] = smooth[i] * nz +
|
||||
(smooth[i + 1] * bz - smooth[i + 2] * by) * ny - bz * nx;
|
||||
normals[i + 1] = smooth[i + 1] * nz -
|
||||
(smooth[i + 2] + smooth[i] ) * bz * ny + by * nx;
|
||||
normals[i + 2] = smooth[i + 2] * nz +
|
||||
(smooth[i] * by + smooth[i + 1] * bz) * ny + bz * nx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CTM.restoreMap = function(map, count, precision) {
|
||||
var delta, value,
|
||||
intMap = new Uint32Array(map.buffer, map.byteOffset, map.length),
|
||||
i = 0, j, len = map.length;
|
||||
|
||||
for (; i < count; ++ i) {
|
||||
delta = 0;
|
||||
|
||||
for (j = i; j < len; j += count) {
|
||||
value = intMap[j];
|
||||
|
||||
delta += value & 1 ? -( (value + 1) >> 1) : value >> 1;
|
||||
|
||||
map[j] = delta * precision;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CTM.calcSmoothNormals = function(indices, vertices) {
|
||||
var smooth = new Float32Array(vertices.length),
|
||||
indx, indy, indz, nx, ny, nz,
|
||||
v1x, v1y, v1z, v2x, v2y, v2z, len,
|
||||
i, k;
|
||||
|
||||
for (i = 0, k = indices.length; i < k;) {
|
||||
indx = indices[i ++] * 3;
|
||||
indy = indices[i ++] * 3;
|
||||
indz = indices[i ++] * 3;
|
||||
|
||||
v1x = vertices[indy] - vertices[indx];
|
||||
v2x = vertices[indz] - vertices[indx];
|
||||
v1y = vertices[indy + 1] - vertices[indx + 1];
|
||||
v2y = vertices[indz + 1] - vertices[indx + 1];
|
||||
v1z = vertices[indy + 2] - vertices[indx + 2];
|
||||
v2z = vertices[indz + 2] - vertices[indx + 2];
|
||||
|
||||
nx = v1y * v2z - v1z * v2y;
|
||||
ny = v1z * v2x - v1x * v2z;
|
||||
nz = v1x * v2y - v1y * v2x;
|
||||
|
||||
len = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
||||
if (len > 1e-10) {
|
||||
nx /= len;
|
||||
ny /= len;
|
||||
nz /= len;
|
||||
}
|
||||
|
||||
smooth[indx] += nx;
|
||||
smooth[indx + 1] += ny;
|
||||
smooth[indx + 2] += nz;
|
||||
smooth[indy] += nx;
|
||||
smooth[indy + 1] += ny;
|
||||
smooth[indy + 2] += nz;
|
||||
smooth[indz] += nx;
|
||||
smooth[indz + 1] += ny;
|
||||
smooth[indz + 2] += nz;
|
||||
}
|
||||
|
||||
for (i = 0, k = smooth.length; i < k; i += 3) {
|
||||
len = Math.sqrt(smooth[i] * smooth[i] +
|
||||
smooth[i + 1] * smooth[i + 1] +
|
||||
smooth[i + 2] * smooth[i + 2]);
|
||||
|
||||
if (len > 1e-10) {
|
||||
smooth[i] /= len;
|
||||
smooth[i + 1] /= len;
|
||||
smooth[i + 2] /= len;
|
||||
}
|
||||
}
|
||||
|
||||
return smooth;
|
||||
};
|
||||
|
||||
CTM.isLittleEndian = (function() {
|
||||
var buffer = new ArrayBuffer(2),
|
||||
bytes = new Uint8Array(buffer),
|
||||
ints = new Uint16Array(buffer);
|
||||
|
||||
bytes[0] = 1;
|
||||
|
||||
return ints[0] === 1;
|
||||
}());
|
||||
|
||||
CTM.InterleavedStream = function(data, count) {
|
||||
this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
||||
this.offset = CTM.isLittleEndian ? 3 : 0;
|
||||
this.count = count * 4;
|
||||
this.len = this.data.length;
|
||||
};
|
||||
|
||||
CTM.InterleavedStream.prototype.writeByte = function(value) {
|
||||
this.data[this.offset] = value;
|
||||
|
||||
this.offset += this.count;
|
||||
if (this.offset >= this.len) {
|
||||
|
||||
this.offset -= this.len - 4;
|
||||
if (this.offset >= this.count) {
|
||||
|
||||
this.offset -= this.count + (CTM.isLittleEndian ? 1 : -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CTM.Stream = function(data) {
|
||||
this.data = data;
|
||||
this.offset = 0;
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23);
|
||||
|
||||
CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126);
|
||||
|
||||
CTM.Stream.prototype.readByte = function() {
|
||||
return this.data[this.offset ++] & 0xff;
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.readInt32 = function() {
|
||||
var i = this.readByte();
|
||||
i |= this.readByte() << 8;
|
||||
i |= this.readByte() << 16;
|
||||
return i | (this.readByte() << 24);
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.readFloat32 = function() {
|
||||
var m = this.readByte();
|
||||
m += this.readByte() << 8;
|
||||
|
||||
var b1 = this.readByte();
|
||||
var b2 = this.readByte();
|
||||
|
||||
m += (b1 & 0x7f) << 16;
|
||||
var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7);
|
||||
var s = b2 & 0x80 ? -1 : 1;
|
||||
|
||||
if (e === 255) {
|
||||
return m !== 0 ? NaN : s * Infinity;
|
||||
}
|
||||
if (e > 0) {
|
||||
return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127);
|
||||
}
|
||||
if (m !== 0) {
|
||||
return s * m * this.TWO_POW_MINUS126;
|
||||
}
|
||||
return s * 0;
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.readString = function() {
|
||||
var len = this.readInt32();
|
||||
|
||||
this.offset += len;
|
||||
|
||||
return String.fromCharCode.apply(null, this.data.subarray(this.offset - len, this.offset));
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.readArrayInt32 = function(array) {
|
||||
var i = 0, len = array.length;
|
||||
|
||||
while (i < len) {
|
||||
array[i ++] = this.readInt32();
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
CTM.Stream.prototype.readArrayFloat32 = function(array) {
|
||||
var i = 0, len = array.length;
|
||||
|
||||
while (i < len) {
|
||||
array[i ++] = this.readFloat32();
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
20
node_modules/three/examples/js/loaders/ctm/license/OpenCTM.txt
generated
vendored
Normal file
20
node_modules/three/examples/js/loaders/ctm/license/OpenCTM.txt
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2009-2010 Marcus Geelnard
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
19
node_modules/three/examples/js/loaders/ctm/license/js-lzma.txt
generated
vendored
Normal file
19
node_modules/three/examples/js/loaders/ctm/license/js-lzma.txt
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011 Juan Mellado
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
19
node_modules/three/examples/js/loaders/ctm/license/js-openctm.txt
generated
vendored
Normal file
19
node_modules/three/examples/js/loaders/ctm/license/js-openctm.txt
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011 Juan Mellado
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
517
node_modules/three/examples/js/loaders/ctm/lzma.js
generated
vendored
Normal file
517
node_modules/three/examples/js/loaders/ctm/lzma.js
generated
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
|
||||
var LZMA = LZMA || {};
|
||||
|
||||
// browserify support
|
||||
if ( typeof module === 'object' ) {
|
||||
|
||||
module.exports = LZMA;
|
||||
|
||||
}
|
||||
|
||||
LZMA.OutWindow = function() {
|
||||
this._windowSize = 0;
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.create = function(windowSize) {
|
||||
if ( (!this._buffer) || (this._windowSize !== windowSize) ) {
|
||||
this._buffer = [];
|
||||
}
|
||||
this._windowSize = windowSize;
|
||||
this._pos = 0;
|
||||
this._streamPos = 0;
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.flush = function() {
|
||||
var size = this._pos - this._streamPos;
|
||||
if (size !== 0) {
|
||||
while (size --) {
|
||||
this._stream.writeByte(this._buffer[this._streamPos ++]);
|
||||
}
|
||||
if (this._pos >= this._windowSize) {
|
||||
this._pos = 0;
|
||||
}
|
||||
this._streamPos = this._pos;
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.releaseStream = function() {
|
||||
this.flush();
|
||||
this._stream = null;
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.setStream = function(stream) {
|
||||
this.releaseStream();
|
||||
this._stream = stream;
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.init = function(solid) {
|
||||
if (!solid) {
|
||||
this._streamPos = 0;
|
||||
this._pos = 0;
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.copyBlock = function(distance, len) {
|
||||
var pos = this._pos - distance - 1;
|
||||
if (pos < 0) {
|
||||
pos += this._windowSize;
|
||||
}
|
||||
while (len --) {
|
||||
if (pos >= this._windowSize) {
|
||||
pos = 0;
|
||||
}
|
||||
this._buffer[this._pos ++] = this._buffer[pos ++];
|
||||
if (this._pos >= this._windowSize) {
|
||||
this.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.putByte = function(b) {
|
||||
this._buffer[this._pos ++] = b;
|
||||
if (this._pos >= this._windowSize) {
|
||||
this.flush();
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.getByte = function(distance) {
|
||||
var pos = this._pos - distance - 1;
|
||||
if (pos < 0) {
|
||||
pos += this._windowSize;
|
||||
}
|
||||
return this._buffer[pos];
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder = function() {
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.setStream = function(stream) {
|
||||
this._stream = stream;
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.releaseStream = function() {
|
||||
this._stream = null;
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.init = function() {
|
||||
var i = 5;
|
||||
|
||||
this._code = 0;
|
||||
this._range = -1;
|
||||
|
||||
while (i --) {
|
||||
this._code = (this._code << 8) | this._stream.readByte();
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits) {
|
||||
var result = 0, i = numTotalBits, t;
|
||||
|
||||
while (i --) {
|
||||
this._range >>>= 1;
|
||||
t = (this._code - this._range) >>> 31;
|
||||
this._code -= this._range & (t - 1);
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if ( (this._range & 0xff000000) === 0) {
|
||||
this._code = (this._code << 8) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.decodeBit = function(probs, index) {
|
||||
var prob = probs[index],
|
||||
newBound = (this._range >>> 11) * prob;
|
||||
|
||||
if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ) {
|
||||
this._range = newBound;
|
||||
probs[index] += (2048 - prob) >>> 5;
|
||||
if ( (this._range & 0xff000000) === 0) {
|
||||
this._code = (this._code << 8) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
this._range -= newBound;
|
||||
this._code -= newBound;
|
||||
probs[index] -= prob >>> 5;
|
||||
if ( (this._range & 0xff000000) === 0) {
|
||||
this._code = (this._code << 8) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
LZMA.initBitModels = function(probs, len) {
|
||||
while (len --) {
|
||||
probs[len] = 1024;
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder = function(numBitLevels) {
|
||||
this._models = [];
|
||||
this._numBitLevels = numBitLevels;
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.init = function() {
|
||||
LZMA.initBitModels(this._models, 1 << this._numBitLevels);
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder) {
|
||||
var m = 1, i = this._numBitLevels;
|
||||
|
||||
while (i --) {
|
||||
m = (m << 1) | rangeDecoder.decodeBit(this._models, m);
|
||||
}
|
||||
return m - (1 << this._numBitLevels);
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder) {
|
||||
var m = 1, symbol = 0, i = 0, bit;
|
||||
|
||||
for (; i < this._numBitLevels; ++ i) {
|
||||
bit = rangeDecoder.decodeBit(this._models, m);
|
||||
m = (m << 1) | bit;
|
||||
symbol |= bit << i;
|
||||
}
|
||||
return symbol;
|
||||
};
|
||||
|
||||
LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels) {
|
||||
var m = 1, symbol = 0, i = 0, bit;
|
||||
|
||||
for (; i < numBitLevels; ++ i) {
|
||||
bit = rangeDecoder.decodeBit(models, startIndex + m);
|
||||
m = (m << 1) | bit;
|
||||
symbol |= bit << i;
|
||||
}
|
||||
return symbol;
|
||||
};
|
||||
|
||||
LZMA.LenDecoder = function() {
|
||||
this._choice = [];
|
||||
this._lowCoder = [];
|
||||
this._midCoder = [];
|
||||
this._highCoder = new LZMA.BitTreeDecoder(8);
|
||||
this._numPosStates = 0;
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.create = function(numPosStates) {
|
||||
for (; this._numPosStates < numPosStates; ++ this._numPosStates) {
|
||||
this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
|
||||
this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3);
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.init = function() {
|
||||
var i = this._numPosStates;
|
||||
LZMA.initBitModels(this._choice, 2);
|
||||
while (i --) {
|
||||
this._lowCoder[i].init();
|
||||
this._midCoder[i].init();
|
||||
}
|
||||
this._highCoder.init();
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState) {
|
||||
if (rangeDecoder.decodeBit(this._choice, 0) === 0) {
|
||||
return this._lowCoder[posState].decode(rangeDecoder);
|
||||
}
|
||||
if (rangeDecoder.decodeBit(this._choice, 1) === 0) {
|
||||
return 8 + this._midCoder[posState].decode(rangeDecoder);
|
||||
}
|
||||
return 16 + this._highCoder.decode(rangeDecoder);
|
||||
};
|
||||
|
||||
LZMA.Decoder2 = function() {
|
||||
this._decoders = [];
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.init = function() {
|
||||
LZMA.initBitModels(this._decoders, 0x300);
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder) {
|
||||
var symbol = 1;
|
||||
|
||||
do {
|
||||
symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
|
||||
}while (symbol < 0x100);
|
||||
|
||||
return symbol & 0xff;
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte) {
|
||||
var symbol = 1, matchBit, bit;
|
||||
|
||||
do {
|
||||
matchBit = (matchByte >> 7) & 1;
|
||||
matchByte <<= 1;
|
||||
bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol);
|
||||
symbol = (symbol << 1) | bit;
|
||||
if (matchBit !== bit) {
|
||||
while (symbol < 0x100) {
|
||||
symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}while (symbol < 0x100);
|
||||
|
||||
return symbol & 0xff;
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder = function() {
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits) {
|
||||
var i;
|
||||
|
||||
if (this._coders
|
||||
&& (this._numPrevBits === numPrevBits)
|
||||
&& (this._numPosBits === numPosBits) ) {
|
||||
return;
|
||||
}
|
||||
this._numPosBits = numPosBits;
|
||||
this._posMask = (1 << numPosBits) - 1;
|
||||
this._numPrevBits = numPrevBits;
|
||||
|
||||
this._coders = [];
|
||||
|
||||
i = 1 << (this._numPrevBits + this._numPosBits);
|
||||
while (i --) {
|
||||
this._coders[i] = new LZMA.Decoder2();
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.init = function() {
|
||||
var i = 1 << (this._numPrevBits + this._numPosBits);
|
||||
while (i --) {
|
||||
this._coders[i].init();
|
||||
}
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte) {
|
||||
return this._coders[( (pos & this._posMask) << this._numPrevBits)
|
||||
+ ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )];
|
||||
};
|
||||
|
||||
LZMA.Decoder = function() {
|
||||
this._outWindow = new LZMA.OutWindow();
|
||||
this._rangeDecoder = new LZMA.RangeDecoder();
|
||||
this._isMatchDecoders = [];
|
||||
this._isRepDecoders = [];
|
||||
this._isRepG0Decoders = [];
|
||||
this._isRepG1Decoders = [];
|
||||
this._isRepG2Decoders = [];
|
||||
this._isRep0LongDecoders = [];
|
||||
this._posSlotDecoder = [];
|
||||
this._posDecoders = [];
|
||||
this._posAlignDecoder = new LZMA.BitTreeDecoder(4);
|
||||
this._lenDecoder = new LZMA.LenDecoder();
|
||||
this._repLenDecoder = new LZMA.LenDecoder();
|
||||
this._literalDecoder = new LZMA.LiteralDecoder();
|
||||
this._dictionarySize = -1;
|
||||
this._dictionarySizeCheck = -1;
|
||||
|
||||
this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6);
|
||||
this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6);
|
||||
this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6);
|
||||
this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6);
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize) {
|
||||
if (dictionarySize < 0) {
|
||||
return false;
|
||||
}
|
||||
if (this._dictionarySize !== dictionarySize) {
|
||||
this._dictionarySize = dictionarySize;
|
||||
this._dictionarySizeCheck = Math.max(this._dictionarySize, 1);
|
||||
this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) );
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb) {
|
||||
var numPosStates = 1 << pb;
|
||||
|
||||
if (lc > 8 || lp > 4 || pb > 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._literalDecoder.create(lp, lc);
|
||||
|
||||
this._lenDecoder.create(numPosStates);
|
||||
this._repLenDecoder.create(numPosStates);
|
||||
this._posStateMask = numPosStates - 1;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.init = function() {
|
||||
var i = 4;
|
||||
|
||||
this._outWindow.init(false);
|
||||
|
||||
LZMA.initBitModels(this._isMatchDecoders, 192);
|
||||
LZMA.initBitModels(this._isRep0LongDecoders, 192);
|
||||
LZMA.initBitModels(this._isRepDecoders, 12);
|
||||
LZMA.initBitModels(this._isRepG0Decoders, 12);
|
||||
LZMA.initBitModels(this._isRepG1Decoders, 12);
|
||||
LZMA.initBitModels(this._isRepG2Decoders, 12);
|
||||
LZMA.initBitModels(this._posDecoders, 114);
|
||||
|
||||
this._literalDecoder.init();
|
||||
|
||||
while (i --) {
|
||||
this._posSlotDecoder[i].init();
|
||||
}
|
||||
|
||||
this._lenDecoder.init();
|
||||
this._repLenDecoder.init();
|
||||
this._posAlignDecoder.init();
|
||||
this._rangeDecoder.init();
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize) {
|
||||
var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
|
||||
posState, decoder2, len, distance, posSlot, numDirectBits;
|
||||
|
||||
this._rangeDecoder.setStream(inStream);
|
||||
this._outWindow.setStream(outStream);
|
||||
|
||||
this.init();
|
||||
|
||||
while (outSize < 0 || nowPos64 < outSize) {
|
||||
posState = nowPos64 & this._posStateMask;
|
||||
|
||||
if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0) {
|
||||
decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte);
|
||||
|
||||
if (state >= 7) {
|
||||
prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) );
|
||||
}else {
|
||||
prevByte = decoder2.decodeNormal(this._rangeDecoder);
|
||||
}
|
||||
this._outWindow.putByte(prevByte);
|
||||
|
||||
state = state < 4 ? 0 : state - (state < 10 ? 3 : 6);
|
||||
|
||||
}else {
|
||||
|
||||
if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1) {
|
||||
len = 0;
|
||||
if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0) {
|
||||
if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0) {
|
||||
state = state < 7 ? 9 : 11;
|
||||
len = 1;
|
||||
}
|
||||
}else {
|
||||
if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0) {
|
||||
distance = rep1;
|
||||
}else {
|
||||
if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0) {
|
||||
distance = rep2;
|
||||
}else {
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
if (len === 0) {
|
||||
len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState);
|
||||
state = state < 7 ? 8 : 11;
|
||||
}
|
||||
}else {
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
|
||||
len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState);
|
||||
state = state < 7 ? 7 : 10;
|
||||
|
||||
posSlot = this._posSlotDecoder[len <= 5 ? len - 2 : 3].decode(this._rangeDecoder);
|
||||
if (posSlot >= 4) {
|
||||
|
||||
numDirectBits = (posSlot >> 1) - 1;
|
||||
rep0 = (2 | (posSlot & 1) ) << numDirectBits;
|
||||
|
||||
if (posSlot < 14) {
|
||||
rep0 += LZMA.reverseDecode2(this._posDecoders,
|
||||
rep0 - posSlot - 1, this._rangeDecoder, numDirectBits);
|
||||
}else {
|
||||
rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4;
|
||||
rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder);
|
||||
if (rep0 < 0) {
|
||||
if (rep0 === -1) {
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
rep0 = posSlot;
|
||||
}
|
||||
}
|
||||
|
||||
if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._outWindow.copyBlock(rep0, len);
|
||||
nowPos64 += len;
|
||||
prevByte = this._outWindow.getByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
this._outWindow.flush();
|
||||
this._outWindow.releaseStream();
|
||||
this._rangeDecoder.releaseStream();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setDecoderProperties = function(properties) {
|
||||
var value, lc, lp, pb, dictionarySize;
|
||||
|
||||
if (properties.size < 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = properties.readByte();
|
||||
lc = value % 9;
|
||||
value = ~~(value / 9);
|
||||
lp = value % 5;
|
||||
pb = ~~(value / 5);
|
||||
|
||||
if ( !this.setLcLpPb(lc, lp, pb) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dictionarySize = properties.readByte();
|
||||
dictionarySize |= properties.readByte() << 8;
|
||||
dictionarySize |= properties.readByte() << 16;
|
||||
dictionarySize += properties.readByte() * 16777216;
|
||||
|
||||
return this.setDictionarySize(dictionarySize);
|
||||
};
|
||||
|
||||
LZMA.decompress = function(properties, inStream, outStream, outSize) {
|
||||
var decoder = new LZMA.Decoder();
|
||||
|
||||
if ( !decoder.setDecoderProperties(properties) ) {
|
||||
throw "Incorrect stream properties";
|
||||
}
|
||||
|
||||
if ( !decoder.decode(inStream, outStream, outSize) ) {
|
||||
throw "Error in data stream";
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
1132
node_modules/three/examples/js/loaders/deprecated/SceneLoader.js
generated
vendored
Normal file
1132
node_modules/three/examples/js/loaders/deprecated/SceneLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3168
node_modules/three/examples/js/loaders/sea3d/SEA3D.js
generated
vendored
Normal file
3168
node_modules/three/examples/js/loaders/sea3d/SEA3D.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
887
node_modules/three/examples/js/loaders/sea3d/SEA3DDeflate.js
generated
vendored
Normal file
887
node_modules/three/examples/js/loaders/sea3d/SEA3DDeflate.js
generated
vendored
Normal file
@@ -0,0 +1,887 @@
|
||||
/*
|
||||
* $Id: rawinflate.js,v 0.3 2013/04/09 14:25:38 dankogai Exp dankogai $
|
||||
*
|
||||
* GNU General Public License, version 2 (GPL-2.0)
|
||||
* http://opensource.org/licenses/GPL-2.0
|
||||
* original:
|
||||
* http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
SEA3D.Deflate = function () {
|
||||
|
||||
/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
|
||||
* Version: 1.0.0.1
|
||||
* LastModified: Dec 25 1999
|
||||
*/
|
||||
|
||||
/* Interface:
|
||||
* data = zip_inflate(src);
|
||||
*/
|
||||
|
||||
/* constant parameters */
|
||||
var zip_WSIZE = 32768; // Sliding Window size
|
||||
var zip_STORED_BLOCK = 0;
|
||||
var zip_STATIC_TREES = 1;
|
||||
var zip_DYN_TREES = 2;
|
||||
|
||||
/* for inflate */
|
||||
var zip_lbits = 9; // bits in base literal/length lookup table
|
||||
var zip_dbits = 6; // bits in base distance lookup table
|
||||
var zip_INBUFSIZ = 32768; // Input buffer size
|
||||
var zip_INBUF_EXTRA = 64; // Extra buffer
|
||||
|
||||
/* variables (inflate) */
|
||||
var zip_slide;
|
||||
var zip_wp; // current position in slide
|
||||
var zip_fixed_tl = null; // inflate static
|
||||
var zip_fixed_td; // inflate static
|
||||
var zip_fixed_bl, fixed_bd, zip_fixed_bd; // inflate static
|
||||
var zip_bit_buf; // bit buffer
|
||||
var zip_bit_len; // bits in bit buffer
|
||||
var zip_method;
|
||||
var zip_eof;
|
||||
var zip_copy_leng;
|
||||
var zip_copy_dist;
|
||||
var zip_tl, zip_td; // literal/length and distance decoder tables
|
||||
var zip_bl, zip_bd; // number of bits decoded by tl and td
|
||||
|
||||
var zip_inflate_data;
|
||||
var zip_inflate_pos;
|
||||
|
||||
|
||||
/* constant tables (inflate) */
|
||||
var zip_MASK_BITS = new Array(
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff );
|
||||
// Tables for deflate from PKZIP's appnote.txt.
|
||||
var zip_cplens = new Array( // Copy lengths for literal codes 257..285
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 );
|
||||
/* note: see note #13 above about the 258 in this list. */
|
||||
var zip_cplext = new Array( // Extra bits for literal codes 257..285
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 ); // 99==invalid
|
||||
var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577 );
|
||||
var zip_cpdext = new Array( // Extra bits for distance codes
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13 );
|
||||
var zip_border = new Array( // Order of the bit length code lengths
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 );
|
||||
/* objects (inflate) */
|
||||
|
||||
var zip_HuftList = function () {
|
||||
|
||||
this.next = null;
|
||||
this.list = null;
|
||||
|
||||
}
|
||||
|
||||
var zip_HuftNode = function () {
|
||||
|
||||
this.e = 0; // number of extra bits or operation
|
||||
this.b = 0; // number of bits in this code or subcode
|
||||
|
||||
// union
|
||||
this.n = 0; // literal, length base, or distance base
|
||||
this.t = null; // (zip_HuftNode) pointer to next level of table
|
||||
|
||||
}
|
||||
|
||||
var zip_HuftBuild = function ( b, // code lengths in bits (all assumed <= BMAX)
|
||||
n, // number of codes (assumed <= N_MAX)
|
||||
s, // number of simple-valued codes (0..s-1)
|
||||
d, // list of base values for non-simple codes
|
||||
e, // list of extra bits for non-simple codes
|
||||
mm // maximum lookup bits
|
||||
) {
|
||||
|
||||
this.BMAX = 16; // maximum bit length of any code
|
||||
this.N_MAX = 288; // maximum number of codes in any set
|
||||
this.status = 0; // 0: success, 1: incomplete table, 2: bad input
|
||||
this.root = null; // (zip_HuftList) starting table
|
||||
this.m = 0; // maximum lookup bits, returns actual
|
||||
|
||||
/* Given a list of code lengths and a maximum table size, make a set of
|
||||
tables to decode that set of codes. Return zero on success, one if
|
||||
the given code set is incomplete (the tables are still built in this
|
||||
case), two if the input is invalid (all zero length codes or an
|
||||
oversubscribed set of lengths), and three if not enough memory.
|
||||
The code with value 256 is special, and the tables are constructed
|
||||
so that no bits beyond that code are fetched when that code is
|
||||
decoded. */
|
||||
{
|
||||
|
||||
var a; // counter for codes of length k
|
||||
var c = new Array( this.BMAX + 1 ); // bit length count table
|
||||
var el; // length of EOB code (value 256)
|
||||
var f; // i repeats in table every f entries
|
||||
var g; // maximum code length
|
||||
var h; // table level
|
||||
var i; // counter, current code
|
||||
var j; // counter
|
||||
var k; // number of bits in current code
|
||||
var lx = new Array( this.BMAX + 1 ); // stack of bits per table
|
||||
var p; // pointer into c[], b[], or v[]
|
||||
var pidx; // index of p
|
||||
var q; // (zip_HuftNode) points to current table
|
||||
var r = new zip_HuftNode(); // table entry for structure assignment
|
||||
var u = new Array( this.BMAX ); // zip_HuftNode[BMAX][] table stack
|
||||
var v = new Array( this.N_MAX ); // values in order of bit length
|
||||
var w;
|
||||
var x = new Array( this.BMAX + 1 );// bit offsets, then code stack
|
||||
var xp; // pointer into x or c
|
||||
var y; // number of dummy codes added
|
||||
var z; // number of entries in current table
|
||||
var o;
|
||||
var tail; // (zip_HuftList)
|
||||
|
||||
tail = this.root = null;
|
||||
for ( i = 0; i < c.length; i ++ )
|
||||
c[ i ] = 0;
|
||||
for ( i = 0; i < lx.length; i ++ )
|
||||
lx[ i ] = 0;
|
||||
for ( i = 0; i < u.length; i ++ )
|
||||
u[ i ] = null;
|
||||
for ( i = 0; i < v.length; i ++ )
|
||||
v[ i ] = 0;
|
||||
for ( i = 0; i < x.length; i ++ )
|
||||
x[ i ] = 0;
|
||||
|
||||
// Generate counts for each bit length
|
||||
el = n > 256 ? b[ 256 ] : this.BMAX; // set length of EOB code, if any
|
||||
p = b; pidx = 0;
|
||||
i = n;
|
||||
do {
|
||||
|
||||
c[ p[ pidx ]] ++; // assume all entries <= BMAX
|
||||
pidx ++;
|
||||
|
||||
} while ( -- i > 0 );
|
||||
if ( c[ 0 ] == n ) {
|
||||
|
||||
// null input--all zero length codes
|
||||
this.root = null;
|
||||
this.m = 0;
|
||||
this.status = 0;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Find minimum and maximum length, bound *m by those
|
||||
for ( j = 1; j <= this.BMAX; j ++ )
|
||||
if ( c[ j ] != 0 )
|
||||
break;
|
||||
k = j; // minimum code length
|
||||
if ( mm < j )
|
||||
mm = j;
|
||||
for ( i = this.BMAX; i != 0; i -- )
|
||||
if ( c[ i ] != 0 )
|
||||
break;
|
||||
g = i; // maximum code length
|
||||
if ( mm > i )
|
||||
mm = i;
|
||||
|
||||
// Adjust last length count to fill out codes, if needed
|
||||
for ( y = 1 << j; j < i; j ++, y <<= 1 )
|
||||
if ( ( y -= c[ j ] ) < 0 ) {
|
||||
|
||||
this.status = 2; // bad input: more codes than bits
|
||||
this.m = mm;
|
||||
return;
|
||||
|
||||
}
|
||||
if ( ( y -= c[ i ] ) < 0 ) {
|
||||
|
||||
this.status = 2;
|
||||
this.m = mm;
|
||||
return;
|
||||
|
||||
}
|
||||
c[ i ] += y;
|
||||
|
||||
// Generate starting offsets into the value table for each length
|
||||
x[ 1 ] = j = 0;
|
||||
p = c;
|
||||
pidx = 1;
|
||||
xp = 2;
|
||||
while ( -- i > 0 ) // note that i == g from above
|
||||
x[ xp ++ ] = ( j += p[ pidx ++ ] );
|
||||
|
||||
// Make a table of values in order of bit lengths
|
||||
p = b; pidx = 0;
|
||||
i = 0;
|
||||
do {
|
||||
|
||||
if ( ( j = p[ pidx ++ ] ) != 0 )
|
||||
v[ x[ j ] ++ ] = i;
|
||||
|
||||
} while ( ++ i < n );
|
||||
n = x[ g ]; // set n to length of v
|
||||
|
||||
// Generate the Huffman codes and for each, make the table entries
|
||||
x[ 0 ] = i = 0; // first Huffman code is zero
|
||||
p = v; pidx = 0; // grab values in bit order
|
||||
h = - 1; // no tables yet--level -1
|
||||
w = lx[ 0 ] = 0; // no bits decoded yet
|
||||
q = null; // ditto
|
||||
z = 0; // ditto
|
||||
|
||||
// go through the bit lengths (k already is bits in shortest code)
|
||||
for ( ; k <= g; k ++ ) {
|
||||
|
||||
a = c[ k ];
|
||||
while ( a -- > 0 ) {
|
||||
|
||||
// here i is the Huffman code of length k bits for value p[pidx]
|
||||
// make tables up to required level
|
||||
while ( k > w + lx[ 1 + h ] ) {
|
||||
|
||||
w += lx[ 1 + h ]; // add bits already decoded
|
||||
h ++;
|
||||
|
||||
// compute minimum size table less than or equal to *m bits
|
||||
z = ( z = g - w ) > mm ? mm : z; // upper limit
|
||||
if ( ( f = 1 << ( j = k - w ) ) > a + 1 ) {
|
||||
|
||||
// try a k-w bit table
|
||||
// too few codes for k-w bit table
|
||||
f -= a + 1; // deduct codes from patterns left
|
||||
xp = k;
|
||||
while ( ++ j < z ) {
|
||||
|
||||
// try smaller tables up to z bits
|
||||
if ( ( f <<= 1 ) <= c[ ++ xp ] )
|
||||
break; // enough codes to use up j bits
|
||||
f -= c[ xp ]; // else deduct codes from patterns
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if ( w + j > el && w < el )
|
||||
j = el - w; // make EOB code end at table
|
||||
z = 1 << j; // table entries for j-bit table
|
||||
lx[ 1 + h ] = j; // set table size in stack
|
||||
|
||||
// allocate and link in new table
|
||||
q = new Array( z );
|
||||
for ( o = 0; o < z; o ++ ) {
|
||||
|
||||
q[ o ] = new zip_HuftNode();
|
||||
|
||||
}
|
||||
|
||||
if ( tail == null )
|
||||
tail = this.root = new zip_HuftList();
|
||||
else
|
||||
tail = tail.next = new zip_HuftList();
|
||||
tail.next = null;
|
||||
tail.list = q;
|
||||
u[ h ] = q; // table starts after link
|
||||
|
||||
/* connect to last table, if there is one */
|
||||
if ( h > 0 ) {
|
||||
|
||||
x[ h ] = i; // save pattern for backing up
|
||||
r.b = lx[ h ]; // bits to dump before this table
|
||||
r.e = 16 + j; // bits in this table
|
||||
r.t = q; // pointer to this table
|
||||
j = ( i & ( ( 1 << w ) - 1 ) ) >> ( w - lx[ h ] );
|
||||
u[ h - 1 ][ j ].e = r.e;
|
||||
u[ h - 1 ][ j ].b = r.b;
|
||||
u[ h - 1 ][ j ].n = r.n;
|
||||
u[ h - 1 ][ j ].t = r.t;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set up table entry in r
|
||||
r.b = k - w;
|
||||
if ( pidx >= n )
|
||||
r.e = 99; // out of values--invalid code
|
||||
else if ( p[ pidx ] < s ) {
|
||||
|
||||
r.e = ( p[ pidx ] < 256 ? 16 : 15 ); // 256 is end-of-block code
|
||||
r.n = p[ pidx ++ ]; // simple code is just the value
|
||||
|
||||
} else {
|
||||
|
||||
r.e = e[ p[ pidx ] - s ]; // non-simple--look up in lists
|
||||
r.n = d[ p[ pidx ++ ] - s ];
|
||||
|
||||
}
|
||||
|
||||
// fill code-like entries with r //
|
||||
f = 1 << ( k - w );
|
||||
for ( j = i >> w; j < z; j += f ) {
|
||||
|
||||
q[ j ].e = r.e;
|
||||
q[ j ].b = r.b;
|
||||
q[ j ].n = r.n;
|
||||
q[ j ].t = r.t;
|
||||
|
||||
}
|
||||
|
||||
// backwards increment the k-bit code i
|
||||
for ( j = 1 << ( k - 1 ); ( i & j ) != 0; j >>= 1 )
|
||||
i ^= j;
|
||||
i ^= j;
|
||||
|
||||
// backup over finished tables
|
||||
while ( ( i & ( ( 1 << w ) - 1 ) ) != x[ h ] ) {
|
||||
|
||||
w -= lx[ h ]; // don't need to update q
|
||||
h --;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* return actual size of base table */
|
||||
this.m = lx[ 1 ];
|
||||
|
||||
/* Return true (1) if we were given an incomplete table */
|
||||
this.status = ( ( y != 0 && g != 1 ) ? 1 : 0 );
|
||||
|
||||
} /* end of constructor */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* routines (inflate) */
|
||||
|
||||
var zip_GET_BYTE = function () {
|
||||
|
||||
if ( zip_inflate_data.length == zip_inflate_pos )
|
||||
return - 1;
|
||||
return zip_inflate_data[ zip_inflate_pos ++ ];
|
||||
|
||||
}
|
||||
|
||||
var zip_NEEDBITS = function ( n ) {
|
||||
|
||||
while ( zip_bit_len < n ) {
|
||||
|
||||
zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
|
||||
zip_bit_len += 8;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var zip_GETBITS = function ( n ) {
|
||||
|
||||
return zip_bit_buf & zip_MASK_BITS[ n ];
|
||||
|
||||
}
|
||||
|
||||
var zip_DUMPBITS = function ( n ) {
|
||||
|
||||
zip_bit_buf >>= n;
|
||||
zip_bit_len -= n;
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_codes = function ( buff, off, size ) {
|
||||
|
||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
||||
Return an error code or zero if it all goes ok. */
|
||||
var e; // table entry flag/number of extra bits
|
||||
var t; // (zip_HuftNode) pointer to table entry
|
||||
var n;
|
||||
|
||||
if ( size == 0 )
|
||||
return 0;
|
||||
|
||||
// inflate the coded data
|
||||
n = 0;
|
||||
for ( ;; ) {
|
||||
|
||||
// do until end of block
|
||||
zip_NEEDBITS( zip_bl );
|
||||
t = zip_tl.list[ zip_GETBITS( zip_bl ) ];
|
||||
e = t.e;
|
||||
while ( e > 16 ) {
|
||||
|
||||
if ( e == 99 )
|
||||
return - 1;
|
||||
zip_DUMPBITS( t.b );
|
||||
e -= 16;
|
||||
zip_NEEDBITS( e );
|
||||
t = t.t[ zip_GETBITS( e ) ];
|
||||
e = t.e;
|
||||
|
||||
}
|
||||
zip_DUMPBITS( t.b );
|
||||
|
||||
if ( e == 16 ) {
|
||||
|
||||
// then it's a literal
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[ off + n ++ ] = zip_slide[ zip_wp ++ ] = t.n;
|
||||
if ( n == size )
|
||||
return size;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// exit if end of block
|
||||
if ( e == 15 )
|
||||
break;
|
||||
|
||||
// it's an EOB or a length
|
||||
|
||||
// get length of block to copy
|
||||
zip_NEEDBITS( e );
|
||||
zip_copy_leng = t.n + zip_GETBITS( e );
|
||||
zip_DUMPBITS( e );
|
||||
|
||||
// decode distance of block to copy
|
||||
zip_NEEDBITS( zip_bd );
|
||||
t = zip_td.list[ zip_GETBITS( zip_bd ) ];
|
||||
e = t.e;
|
||||
|
||||
while ( e > 16 ) {
|
||||
|
||||
if ( e == 99 )
|
||||
return - 1;
|
||||
zip_DUMPBITS( t.b );
|
||||
e -= 16;
|
||||
zip_NEEDBITS( e );
|
||||
t = t.t[ zip_GETBITS( e ) ];
|
||||
e = t.e;
|
||||
|
||||
}
|
||||
zip_DUMPBITS( t.b );
|
||||
zip_NEEDBITS( e );
|
||||
zip_copy_dist = zip_wp - t.n - zip_GETBITS( e );
|
||||
zip_DUMPBITS( e );
|
||||
|
||||
// do the copy
|
||||
while ( zip_copy_leng > 0 && n < size ) {
|
||||
|
||||
zip_copy_leng --;
|
||||
zip_copy_dist &= zip_WSIZE - 1;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[ off + n ++ ] = zip_slide[ zip_wp ++ ]
|
||||
= zip_slide[ zip_copy_dist ++ ];
|
||||
|
||||
}
|
||||
|
||||
if ( n == size )
|
||||
return size;
|
||||
|
||||
}
|
||||
|
||||
zip_method = - 1; // done
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_stored = function ( buff, off, size ) {
|
||||
|
||||
/* "decompress" an inflated type 0 (stored) block. */
|
||||
var n;
|
||||
|
||||
// go to byte boundary
|
||||
n = zip_bit_len & 7;
|
||||
zip_DUMPBITS( n );
|
||||
|
||||
// get the length and its complement
|
||||
zip_NEEDBITS( 16 );
|
||||
n = zip_GETBITS( 16 );
|
||||
zip_DUMPBITS( 16 );
|
||||
zip_NEEDBITS( 16 );
|
||||
if ( n != ( ( ~ zip_bit_buf ) & 0xffff ) )
|
||||
return - 1; // error in compressed data
|
||||
zip_DUMPBITS( 16 );
|
||||
|
||||
// read and output the compressed data
|
||||
zip_copy_leng = n;
|
||||
|
||||
n = 0;
|
||||
while ( zip_copy_leng > 0 && n < size ) {
|
||||
|
||||
zip_copy_leng --;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
zip_NEEDBITS( 8 );
|
||||
buff[ off + n ++ ] = zip_slide[ zip_wp ++ ] =
|
||||
zip_GETBITS( 8 );
|
||||
zip_DUMPBITS( 8 );
|
||||
|
||||
}
|
||||
|
||||
if ( zip_copy_leng == 0 )
|
||||
zip_method = - 1; // done
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_fixed = function ( buff, off, size ) {
|
||||
|
||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
||||
either replace this with a custom decoder, or at least precompute the
|
||||
Huffman tables. */
|
||||
|
||||
// if first time, set up tables for fixed blocks
|
||||
if ( zip_fixed_tl == null ) {
|
||||
|
||||
var i; // temporary variable
|
||||
var l = new Array( 288 ); // length list for huft_build
|
||||
var h; // zip_HuftBuild
|
||||
|
||||
// literal table
|
||||
for ( i = 0; i < 144; i ++ )
|
||||
l[ i ] = 8;
|
||||
for ( ; i < 256; i ++ )
|
||||
l[ i ] = 9;
|
||||
for ( ; i < 280; i ++ )
|
||||
l[ i ] = 7;
|
||||
for ( ; i < 288; i ++ ) // make a complete, but wrong code set
|
||||
l[ i ] = 8;
|
||||
zip_fixed_bl = 7;
|
||||
|
||||
h = new zip_HuftBuild( l, 288, 257, zip_cplens, zip_cplext,
|
||||
zip_fixed_bl );
|
||||
if ( h.status != 0 ) {
|
||||
|
||||
alert( "HufBuild error: " + h.status );
|
||||
return - 1;
|
||||
|
||||
}
|
||||
zip_fixed_tl = h.root;
|
||||
zip_fixed_bl = h.m;
|
||||
|
||||
// distance table
|
||||
for ( i = 0; i < 30; i ++ ) // make an incomplete code set
|
||||
l[ i ] = 5;
|
||||
zip_fixed_bd = 5;
|
||||
|
||||
h = new zip_HuftBuild( l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd );
|
||||
if ( h.status > 1 ) {
|
||||
|
||||
zip_fixed_tl = null;
|
||||
alert( "HufBuild error: " + h.status );
|
||||
return - 1;
|
||||
|
||||
}
|
||||
zip_fixed_td = h.root;
|
||||
zip_fixed_bd = h.m;
|
||||
|
||||
}
|
||||
|
||||
zip_tl = zip_fixed_tl;
|
||||
zip_td = zip_fixed_td;
|
||||
zip_bl = zip_fixed_bl;
|
||||
zip_bd = zip_fixed_bd;
|
||||
return zip_inflate_codes( buff, off, size );
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_dynamic = function ( buff, off, size ) {
|
||||
|
||||
// decompress an inflated type 2 (dynamic Huffman codes) block.
|
||||
var i; // temporary variables
|
||||
var j;
|
||||
var l; // last length
|
||||
var n; // number of lengths to get
|
||||
var t; // (zip_HuftNode) literal/length code table
|
||||
var nb; // number of bit length codes
|
||||
var nl; // number of literal/length codes
|
||||
var nd; // number of distance codes
|
||||
var ll = new Array( 286 + 30 ); // literal/length and distance code lengths
|
||||
var h; // (zip_HuftBuild)
|
||||
|
||||
for ( i = 0; i < ll.length; i ++ )
|
||||
ll[ i ] = 0;
|
||||
|
||||
// read in table lengths
|
||||
zip_NEEDBITS( 5 );
|
||||
nl = 257 + zip_GETBITS( 5 ); // number of literal/length codes
|
||||
zip_DUMPBITS( 5 );
|
||||
zip_NEEDBITS( 5 );
|
||||
nd = 1 + zip_GETBITS( 5 ); // number of distance codes
|
||||
zip_DUMPBITS( 5 );
|
||||
zip_NEEDBITS( 4 );
|
||||
nb = 4 + zip_GETBITS( 4 ); // number of bit length codes
|
||||
zip_DUMPBITS( 4 );
|
||||
if ( nl > 286 || nd > 30 )
|
||||
return - 1; // bad lengths
|
||||
|
||||
// read in bit-length-code lengths
|
||||
for ( j = 0; j < nb; j ++ )
|
||||
{
|
||||
|
||||
zip_NEEDBITS( 3 );
|
||||
ll[ zip_border[ j ]] = zip_GETBITS( 3 );
|
||||
zip_DUMPBITS( 3 );
|
||||
|
||||
}
|
||||
for ( ; j < 19; j ++ )
|
||||
ll[ zip_border[ j ]] = 0;
|
||||
|
||||
// build decoding table for trees--single level, 7 bit lookup
|
||||
zip_bl = 7;
|
||||
h = new zip_HuftBuild( ll, 19, 19, null, null, zip_bl );
|
||||
if ( h.status != 0 )
|
||||
return - 1; // incomplete code set
|
||||
|
||||
zip_tl = h.root;
|
||||
zip_bl = h.m;
|
||||
|
||||
// read in literal and distance code lengths
|
||||
n = nl + nd;
|
||||
i = l = 0;
|
||||
while ( i < n ) {
|
||||
|
||||
zip_NEEDBITS( zip_bl );
|
||||
t = zip_tl.list[ zip_GETBITS( zip_bl ) ];
|
||||
j = t.b;
|
||||
zip_DUMPBITS( j );
|
||||
j = t.n;
|
||||
if ( j < 16 ) // length of code in bits (0..15)
|
||||
ll[ i ++ ] = l = j; // save last length in l
|
||||
else if ( j == 16 ) {
|
||||
|
||||
// repeat last length 3 to 6 times
|
||||
zip_NEEDBITS( 2 );
|
||||
j = 3 + zip_GETBITS( 2 );
|
||||
zip_DUMPBITS( 2 );
|
||||
if ( i + j > n )
|
||||
return - 1;
|
||||
while ( j -- > 0 )
|
||||
ll[ i ++ ] = l;
|
||||
|
||||
} else if ( j == 17 ) {
|
||||
|
||||
// 3 to 10 zero length codes
|
||||
zip_NEEDBITS( 3 );
|
||||
j = 3 + zip_GETBITS( 3 );
|
||||
zip_DUMPBITS( 3 );
|
||||
if ( i + j > n )
|
||||
return - 1;
|
||||
while ( j -- > 0 )
|
||||
ll[ i ++ ] = 0;
|
||||
l = 0;
|
||||
|
||||
} else {
|
||||
|
||||
// j == 18: 11 to 138 zero length codes
|
||||
zip_NEEDBITS( 7 );
|
||||
j = 11 + zip_GETBITS( 7 );
|
||||
zip_DUMPBITS( 7 );
|
||||
if ( i + j > n )
|
||||
return - 1;
|
||||
while ( j -- > 0 )
|
||||
ll[ i ++ ] = 0;
|
||||
l = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build the decoding tables for literal/length and distance codes
|
||||
zip_bl = zip_lbits;
|
||||
h = new zip_HuftBuild( ll, nl, 257, zip_cplens, zip_cplext, zip_bl );
|
||||
if ( zip_bl == 0 ) // no literals or lengths
|
||||
h.status = 1;
|
||||
if ( h.status != 0 ) {
|
||||
|
||||
/*if(h.status == 1)
|
||||
;// **incomplete literal tree** */
|
||||
return - 1; // incomplete code set
|
||||
|
||||
}
|
||||
zip_tl = h.root;
|
||||
zip_bl = h.m;
|
||||
|
||||
for ( i = 0; i < nd; i ++ )
|
||||
ll[ i ] = ll[ i + nl ];
|
||||
zip_bd = zip_dbits;
|
||||
h = new zip_HuftBuild( ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd );
|
||||
zip_td = h.root;
|
||||
zip_bd = h.m;
|
||||
|
||||
if ( zip_bd == 0 && nl > 257 ) {
|
||||
|
||||
// lengths but no distances
|
||||
// **incomplete distance tree**
|
||||
return - 1;
|
||||
|
||||
}
|
||||
|
||||
/*if(h.status == 1) {
|
||||
;// **incomplete distance tree**
|
||||
}*/
|
||||
if ( h.status != 0 )
|
||||
return - 1;
|
||||
|
||||
// decompress until an end-of-block code
|
||||
return zip_inflate_codes( buff, off, size );
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_start = function () {
|
||||
|
||||
var i;
|
||||
|
||||
if ( zip_slide == null )
|
||||
zip_slide = new Array( 2 * zip_WSIZE );
|
||||
zip_wp = 0;
|
||||
zip_bit_buf = 0;
|
||||
zip_bit_len = 0;
|
||||
zip_method = - 1;
|
||||
zip_eof = false;
|
||||
zip_copy_leng = zip_copy_dist = 0;
|
||||
zip_tl = null;
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate_internal = function ( buff, off, size ) {
|
||||
|
||||
// decompress an inflated entry
|
||||
var n, i;
|
||||
|
||||
n = 0;
|
||||
while ( n < size ) {
|
||||
|
||||
if ( zip_eof && zip_method == - 1 )
|
||||
return n;
|
||||
|
||||
if ( zip_copy_leng > 0 ) {
|
||||
|
||||
if ( zip_method != zip_STORED_BLOCK ) {
|
||||
|
||||
// STATIC_TREES or DYN_TREES
|
||||
while ( zip_copy_leng > 0 && n < size ) {
|
||||
|
||||
zip_copy_leng --;
|
||||
zip_copy_dist &= zip_WSIZE - 1;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
buff[ off + n ++ ] = zip_slide[ zip_wp ++ ] =
|
||||
zip_slide[ zip_copy_dist ++ ];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
while ( zip_copy_leng > 0 && n < size ) {
|
||||
|
||||
zip_copy_leng --;
|
||||
zip_wp &= zip_WSIZE - 1;
|
||||
zip_NEEDBITS( 8 );
|
||||
buff[ off + n ++ ] = zip_slide[ zip_wp ++ ] = zip_GETBITS( 8 );
|
||||
zip_DUMPBITS( 8 );
|
||||
|
||||
}
|
||||
if ( zip_copy_leng == 0 )
|
||||
zip_method = - 1; // done
|
||||
|
||||
}
|
||||
if ( n == size )
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
if ( zip_method == - 1 ) {
|
||||
|
||||
if ( zip_eof )
|
||||
break;
|
||||
|
||||
// read in last block bit
|
||||
zip_NEEDBITS( 1 );
|
||||
if ( zip_GETBITS( 1 ) != 0 )
|
||||
zip_eof = true;
|
||||
zip_DUMPBITS( 1 );
|
||||
|
||||
// read in block type
|
||||
zip_NEEDBITS( 2 );
|
||||
zip_method = zip_GETBITS( 2 );
|
||||
zip_DUMPBITS( 2 );
|
||||
zip_tl = null;
|
||||
zip_copy_leng = 0;
|
||||
|
||||
}
|
||||
|
||||
switch ( zip_method ) {
|
||||
case 0: // zip_STORED_BLOCK
|
||||
i = zip_inflate_stored( buff, off + n, size - n );
|
||||
break;
|
||||
|
||||
case 1: // zip_STATIC_TREES
|
||||
if ( zip_tl != null )
|
||||
i = zip_inflate_codes( buff, off + n, size - n );
|
||||
else
|
||||
i = zip_inflate_fixed( buff, off + n, size - n );
|
||||
break;
|
||||
|
||||
case 2: // zip_DYN_TREES
|
||||
if ( zip_tl != null )
|
||||
i = zip_inflate_codes( buff, off + n, size - n );
|
||||
else
|
||||
i = zip_inflate_dynamic( buff, off + n, size - n );
|
||||
break;
|
||||
|
||||
default: // error
|
||||
i = - 1;
|
||||
}
|
||||
|
||||
if ( i == - 1 ) {
|
||||
|
||||
if ( zip_eof )
|
||||
return 0;
|
||||
return - 1;
|
||||
|
||||
}
|
||||
n += i;
|
||||
|
||||
}
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
var zip_inflate = function ( data ) {
|
||||
|
||||
var i, j, pos = 0;
|
||||
|
||||
zip_inflate_start();
|
||||
zip_inflate_data = new Uint8Array( data );
|
||||
zip_inflate_pos = 0;
|
||||
|
||||
var buff = new Uint8Array( 1024 );
|
||||
|
||||
var out = [];
|
||||
while ( ( i = zip_inflate_internal( buff, 0, buff.length ) ) > 0 )
|
||||
for ( j = 0; j < i; j ++ )
|
||||
out[ pos ++ ] = buff[ j ];
|
||||
|
||||
zip_inflate_data = null; // G.C.
|
||||
return new Uint8Array( out ).buffer;
|
||||
|
||||
}
|
||||
|
||||
return { inflate: zip_inflate };
|
||||
|
||||
}();
|
||||
|
||||
/**
|
||||
* SEA3D Deflate
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
SEA3D.File.DeflateUncompress = function ( data ) {
|
||||
|
||||
return SEA3D.Deflate.inflate( data );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.File.setDecompressionEngine( 1, "deflate", SEA3D.File.DeflateUncompress );
|
||||
810
node_modules/three/examples/js/loaders/sea3d/SEA3DLZMA.js
generated
vendored
Normal file
810
node_modules/three/examples/js/loaders/sea3d/SEA3DLZMA.js
generated
vendored
Normal file
@@ -0,0 +1,810 @@
|
||||
/*
|
||||
Copyright (c) 2011 Juan Mellado
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
References:
|
||||
- "LZMA SDK" by Igor Pavlov
|
||||
http://www.7-zip.org/sdk.html
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
SEA3D.LZMA = function () {
|
||||
|
||||
var LZMA = LZMA || {};
|
||||
|
||||
LZMA.OutWindow = function () {
|
||||
|
||||
this._windowSize = 0;
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.create = function ( windowSize ) {
|
||||
|
||||
if ( ( ! this._buffer ) || ( this._windowSize !== windowSize ) ) {
|
||||
|
||||
this._buffer = [];
|
||||
|
||||
}
|
||||
this._windowSize = windowSize;
|
||||
this._pos = 0;
|
||||
this._streamPos = 0;
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.flush = function () {
|
||||
|
||||
var size = this._pos - this._streamPos;
|
||||
if ( size !== 0 ) {
|
||||
|
||||
while ( size -- ) {
|
||||
|
||||
this._stream.writeByte( this._buffer[ this._streamPos ++ ] );
|
||||
|
||||
}
|
||||
if ( this._pos >= this._windowSize ) {
|
||||
|
||||
this._pos = 0;
|
||||
|
||||
}
|
||||
this._streamPos = this._pos;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.releaseStream = function () {
|
||||
|
||||
this.flush();
|
||||
this._stream = null;
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.setStream = function ( stream ) {
|
||||
|
||||
this.releaseStream();
|
||||
this._stream = stream;
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.init = function ( solid ) {
|
||||
|
||||
if ( ! solid ) {
|
||||
|
||||
this._streamPos = 0;
|
||||
this._pos = 0;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.copyBlock = function ( distance, len ) {
|
||||
|
||||
var pos = this._pos - distance - 1;
|
||||
if ( pos < 0 ) {
|
||||
|
||||
pos += this._windowSize;
|
||||
|
||||
}
|
||||
while ( len -- ) {
|
||||
|
||||
if ( pos >= this._windowSize ) {
|
||||
|
||||
pos = 0;
|
||||
|
||||
}
|
||||
this._buffer[ this._pos ++ ] = this._buffer[ pos ++ ];
|
||||
if ( this._pos >= this._windowSize ) {
|
||||
|
||||
this.flush();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.putByte = function ( b ) {
|
||||
|
||||
this._buffer[ this._pos ++ ] = b;
|
||||
if ( this._pos >= this._windowSize ) {
|
||||
|
||||
this.flush();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.OutWindow.prototype.getByte = function ( distance ) {
|
||||
|
||||
var pos = this._pos - distance - 1;
|
||||
if ( pos < 0 ) {
|
||||
|
||||
pos += this._windowSize;
|
||||
|
||||
}
|
||||
return this._buffer[ pos ];
|
||||
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder = function () {
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.setStream = function ( stream ) {
|
||||
|
||||
this._stream = stream;
|
||||
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.releaseStream = function () {
|
||||
|
||||
this._stream = null;
|
||||
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.init = function () {
|
||||
|
||||
var i = 5;
|
||||
|
||||
this._code = 0;
|
||||
this._range = - 1;
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
this._code = ( this._code << 8 ) | this._stream.readByte();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.decodeDirectBits = function ( numTotalBits ) {
|
||||
|
||||
var result = 0, i = numTotalBits, t;
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
this._range >>>= 1;
|
||||
t = ( this._code - this._range ) >>> 31;
|
||||
this._code -= this._range & ( t - 1 );
|
||||
result = ( result << 1 ) | ( 1 - t );
|
||||
|
||||
if ( ( this._range & 0xff000000 ) === 0 ) {
|
||||
|
||||
this._code = ( this._code << 8 ) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
};
|
||||
|
||||
LZMA.RangeDecoder.prototype.decodeBit = function ( probs, index ) {
|
||||
|
||||
var prob = probs[ index ],
|
||||
newBound = ( this._range >>> 11 ) * prob;
|
||||
|
||||
if ( ( this._code ^ 0x80000000 ) < ( newBound ^ 0x80000000 ) ) {
|
||||
|
||||
this._range = newBound;
|
||||
probs[ index ] += ( 2048 - prob ) >>> 5;
|
||||
if ( ( this._range & 0xff000000 ) === 0 ) {
|
||||
|
||||
this._code = ( this._code << 8 ) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
this._range -= newBound;
|
||||
this._code -= newBound;
|
||||
probs[ index ] -= prob >>> 5;
|
||||
if ( ( this._range & 0xff000000 ) === 0 ) {
|
||||
|
||||
this._code = ( this._code << 8 ) | this._stream.readByte();
|
||||
this._range <<= 8;
|
||||
|
||||
}
|
||||
return 1;
|
||||
|
||||
};
|
||||
|
||||
LZMA.initBitModels = function ( probs, len ) {
|
||||
|
||||
while ( len -- ) {
|
||||
|
||||
probs[ len ] = 1024;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder = function ( numBitLevels ) {
|
||||
|
||||
this._models = [];
|
||||
this._numBitLevels = numBitLevels;
|
||||
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.init = function () {
|
||||
|
||||
LZMA.initBitModels( this._models, 1 << this._numBitLevels );
|
||||
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.decode = function ( rangeDecoder ) {
|
||||
|
||||
var m = 1, i = this._numBitLevels;
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
m = ( m << 1 ) | rangeDecoder.decodeBit( this._models, m );
|
||||
|
||||
}
|
||||
return m - ( 1 << this._numBitLevels );
|
||||
|
||||
};
|
||||
|
||||
LZMA.BitTreeDecoder.prototype.reverseDecode = function ( rangeDecoder ) {
|
||||
|
||||
var m = 1, symbol = 0, i = 0, bit;
|
||||
|
||||
for ( ; i < this._numBitLevels; ++ i ) {
|
||||
|
||||
bit = rangeDecoder.decodeBit( this._models, m );
|
||||
m = ( m << 1 ) | bit;
|
||||
symbol |= bit << i;
|
||||
|
||||
}
|
||||
return symbol;
|
||||
|
||||
};
|
||||
|
||||
LZMA.reverseDecode2 = function ( models, startIndex, rangeDecoder, numBitLevels ) {
|
||||
|
||||
var m = 1, symbol = 0, i = 0, bit;
|
||||
|
||||
for ( ; i < numBitLevels; ++ i ) {
|
||||
|
||||
bit = rangeDecoder.decodeBit( models, startIndex + m );
|
||||
m = ( m << 1 ) | bit;
|
||||
symbol |= bit << i;
|
||||
|
||||
}
|
||||
return symbol;
|
||||
|
||||
};
|
||||
|
||||
LZMA.LenDecoder = function () {
|
||||
|
||||
this._choice = [];
|
||||
this._lowCoder = [];
|
||||
this._midCoder = [];
|
||||
this._highCoder = new LZMA.BitTreeDecoder( 8 );
|
||||
this._numPosStates = 0;
|
||||
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.create = function ( numPosStates ) {
|
||||
|
||||
for ( ; this._numPosStates < numPosStates; ++ this._numPosStates ) {
|
||||
|
||||
this._lowCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 );
|
||||
this._midCoder[ this._numPosStates ] = new LZMA.BitTreeDecoder( 3 );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.init = function () {
|
||||
|
||||
var i = this._numPosStates;
|
||||
LZMA.initBitModels( this._choice, 2 );
|
||||
while ( i -- ) {
|
||||
|
||||
this._lowCoder[ i ].init();
|
||||
this._midCoder[ i ].init();
|
||||
|
||||
}
|
||||
this._highCoder.init();
|
||||
|
||||
};
|
||||
|
||||
LZMA.LenDecoder.prototype.decode = function ( rangeDecoder, posState ) {
|
||||
|
||||
if ( rangeDecoder.decodeBit( this._choice, 0 ) === 0 ) {
|
||||
|
||||
return this._lowCoder[ posState ].decode( rangeDecoder );
|
||||
|
||||
}
|
||||
if ( rangeDecoder.decodeBit( this._choice, 1 ) === 0 ) {
|
||||
|
||||
return 8 + this._midCoder[ posState ].decode( rangeDecoder );
|
||||
|
||||
}
|
||||
return 16 + this._highCoder.decode( rangeDecoder );
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder2 = function () {
|
||||
|
||||
this._decoders = [];
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.init = function () {
|
||||
|
||||
LZMA.initBitModels( this._decoders, 0x300 );
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.decodeNormal = function ( rangeDecoder ) {
|
||||
|
||||
var symbol = 1;
|
||||
|
||||
do {
|
||||
|
||||
symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol );
|
||||
|
||||
}while ( symbol < 0x100 );
|
||||
|
||||
return symbol & 0xff;
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder2.prototype.decodeWithMatchByte = function ( rangeDecoder, matchByte ) {
|
||||
|
||||
var symbol = 1, matchBit, bit;
|
||||
|
||||
do {
|
||||
|
||||
matchBit = ( matchByte >> 7 ) & 1;
|
||||
matchByte <<= 1;
|
||||
bit = rangeDecoder.decodeBit( this._decoders, ( ( 1 + matchBit ) << 8 ) + symbol );
|
||||
symbol = ( symbol << 1 ) | bit;
|
||||
if ( matchBit !== bit ) {
|
||||
|
||||
while ( symbol < 0x100 ) {
|
||||
|
||||
symbol = ( symbol << 1 ) | rangeDecoder.decodeBit( this._decoders, symbol );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}while ( symbol < 0x100 );
|
||||
|
||||
return symbol & 0xff;
|
||||
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder = function () {
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.create = function ( numPosBits, numPrevBits ) {
|
||||
|
||||
var i;
|
||||
|
||||
if ( this._coders
|
||||
&& ( this._numPrevBits === numPrevBits )
|
||||
&& ( this._numPosBits === numPosBits ) ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
this._numPosBits = numPosBits;
|
||||
this._posMask = ( 1 << numPosBits ) - 1;
|
||||
this._numPrevBits = numPrevBits;
|
||||
|
||||
this._coders = [];
|
||||
|
||||
i = 1 << ( this._numPrevBits + this._numPosBits );
|
||||
while ( i -- ) {
|
||||
|
||||
this._coders[ i ] = new LZMA.Decoder2();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.init = function () {
|
||||
|
||||
var i = 1 << ( this._numPrevBits + this._numPosBits );
|
||||
while ( i -- ) {
|
||||
|
||||
this._coders[ i ].init();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
LZMA.LiteralDecoder.prototype.getDecoder = function ( pos, prevByte ) {
|
||||
|
||||
return this._coders[ ( ( pos & this._posMask ) << this._numPrevBits )
|
||||
+ ( ( prevByte & 0xff ) >>> ( 8 - this._numPrevBits ) ) ];
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder = function () {
|
||||
|
||||
this._outWindow = new LZMA.OutWindow();
|
||||
this._rangeDecoder = new LZMA.RangeDecoder();
|
||||
this._isMatchDecoders = [];
|
||||
this._isRepDecoders = [];
|
||||
this._isRepG0Decoders = [];
|
||||
this._isRepG1Decoders = [];
|
||||
this._isRepG2Decoders = [];
|
||||
this._isRep0LongDecoders = [];
|
||||
this._posSlotDecoder = [];
|
||||
this._posDecoders = [];
|
||||
this._posAlignDecoder = new LZMA.BitTreeDecoder( 4 );
|
||||
this._lenDecoder = new LZMA.LenDecoder();
|
||||
this._repLenDecoder = new LZMA.LenDecoder();
|
||||
this._literalDecoder = new LZMA.LiteralDecoder();
|
||||
this._dictionarySize = - 1;
|
||||
this._dictionarySizeCheck = - 1;
|
||||
|
||||
this._posSlotDecoder[ 0 ] = new LZMA.BitTreeDecoder( 6 );
|
||||
this._posSlotDecoder[ 1 ] = new LZMA.BitTreeDecoder( 6 );
|
||||
this._posSlotDecoder[ 2 ] = new LZMA.BitTreeDecoder( 6 );
|
||||
this._posSlotDecoder[ 3 ] = new LZMA.BitTreeDecoder( 6 );
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setDictionarySize = function ( dictionarySize ) {
|
||||
|
||||
if ( dictionarySize < 0 ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
if ( this._dictionarySize !== dictionarySize ) {
|
||||
|
||||
this._dictionarySize = dictionarySize;
|
||||
this._dictionarySizeCheck = Math.max( this._dictionarySize, 1 );
|
||||
this._outWindow.create( Math.max( this._dictionarySizeCheck, 4096 ) );
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setLcLpPb = function ( lc, lp, pb ) {
|
||||
|
||||
var numPosStates = 1 << pb;
|
||||
|
||||
if ( lc > 8 || lp > 4 || pb > 4 ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
this._literalDecoder.create( lp, lc );
|
||||
|
||||
this._lenDecoder.create( numPosStates );
|
||||
this._repLenDecoder.create( numPosStates );
|
||||
this._posStateMask = numPosStates - 1;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.init = function () {
|
||||
|
||||
var i = 4;
|
||||
|
||||
this._outWindow.init( false );
|
||||
|
||||
LZMA.initBitModels( this._isMatchDecoders, 192 );
|
||||
LZMA.initBitModels( this._isRep0LongDecoders, 192 );
|
||||
LZMA.initBitModels( this._isRepDecoders, 12 );
|
||||
LZMA.initBitModels( this._isRepG0Decoders, 12 );
|
||||
LZMA.initBitModels( this._isRepG1Decoders, 12 );
|
||||
LZMA.initBitModels( this._isRepG2Decoders, 12 );
|
||||
LZMA.initBitModels( this._posDecoders, 114 );
|
||||
|
||||
this._literalDecoder.init();
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
this._posSlotDecoder[ i ].init();
|
||||
|
||||
}
|
||||
|
||||
this._lenDecoder.init();
|
||||
this._repLenDecoder.init();
|
||||
this._posAlignDecoder.init();
|
||||
this._rangeDecoder.init();
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.decode = function ( inStream, outStream, outSize ) {
|
||||
|
||||
var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0,
|
||||
posState, decoder2, len, distance, posSlot, numDirectBits;
|
||||
|
||||
this._rangeDecoder.setStream( inStream );
|
||||
this._outWindow.setStream( outStream );
|
||||
|
||||
this.init();
|
||||
|
||||
while ( outSize < 0 || nowPos64 < outSize ) {
|
||||
|
||||
posState = nowPos64 & this._posStateMask;
|
||||
|
||||
if ( this._rangeDecoder.decodeBit( this._isMatchDecoders, ( state << 4 ) + posState ) === 0 ) {
|
||||
|
||||
decoder2 = this._literalDecoder.getDecoder( nowPos64 ++, prevByte );
|
||||
|
||||
if ( state >= 7 ) {
|
||||
|
||||
prevByte = decoder2.decodeWithMatchByte( this._rangeDecoder, this._outWindow.getByte( rep0 ) );
|
||||
|
||||
} else {
|
||||
|
||||
prevByte = decoder2.decodeNormal( this._rangeDecoder );
|
||||
|
||||
}
|
||||
this._outWindow.putByte( prevByte );
|
||||
|
||||
state = state < 4 ? 0 : state - ( state < 10 ? 3 : 6 );
|
||||
|
||||
} else {
|
||||
|
||||
if ( this._rangeDecoder.decodeBit( this._isRepDecoders, state ) === 1 ) {
|
||||
|
||||
len = 0;
|
||||
if ( this._rangeDecoder.decodeBit( this._isRepG0Decoders, state ) === 0 ) {
|
||||
|
||||
if ( this._rangeDecoder.decodeBit( this._isRep0LongDecoders, ( state << 4 ) + posState ) === 0 ) {
|
||||
|
||||
state = state < 7 ? 9 : 11;
|
||||
len = 1;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( this._rangeDecoder.decodeBit( this._isRepG1Decoders, state ) === 0 ) {
|
||||
|
||||
distance = rep1;
|
||||
|
||||
} else {
|
||||
|
||||
if ( this._rangeDecoder.decodeBit( this._isRepG2Decoders, state ) === 0 ) {
|
||||
|
||||
distance = rep2;
|
||||
|
||||
} else {
|
||||
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
|
||||
}
|
||||
rep2 = rep1;
|
||||
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
|
||||
}
|
||||
if ( len === 0 ) {
|
||||
|
||||
len = 2 + this._repLenDecoder.decode( this._rangeDecoder, posState );
|
||||
state = state < 7 ? 8 : 11;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
|
||||
len = 2 + this._lenDecoder.decode( this._rangeDecoder, posState );
|
||||
state = state < 7 ? 7 : 10;
|
||||
|
||||
posSlot = this._posSlotDecoder[ len <= 5 ? len - 2 : 3 ].decode( this._rangeDecoder );
|
||||
if ( posSlot >= 4 ) {
|
||||
|
||||
numDirectBits = ( posSlot >> 1 ) - 1;
|
||||
rep0 = ( 2 | ( posSlot & 1 ) ) << numDirectBits;
|
||||
|
||||
if ( posSlot < 14 ) {
|
||||
|
||||
rep0 += LZMA.reverseDecode2( this._posDecoders,
|
||||
rep0 - posSlot - 1, this._rangeDecoder, numDirectBits );
|
||||
|
||||
} else {
|
||||
|
||||
rep0 += this._rangeDecoder.decodeDirectBits( numDirectBits - 4 ) << 4;
|
||||
rep0 += this._posAlignDecoder.reverseDecode( this._rangeDecoder );
|
||||
if ( rep0 < 0 ) {
|
||||
|
||||
if ( rep0 === - 1 ) {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
rep0 = posSlot;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
this._outWindow.copyBlock( rep0, len );
|
||||
nowPos64 += len;
|
||||
prevByte = this._outWindow.getByte( 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._outWindow.flush();
|
||||
this._outWindow.releaseStream();
|
||||
this._rangeDecoder.releaseStream();
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
LZMA.Decoder.prototype.setDecoderProperties = function ( properties ) {
|
||||
|
||||
var value, lc, lp, pb, dictionarySize;
|
||||
|
||||
if ( properties.size < 5 ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
value = properties.readByte();
|
||||
lc = value % 9;
|
||||
value = ~~ ( value / 9 );
|
||||
lp = value % 5;
|
||||
pb = ~~ ( value / 5 );
|
||||
|
||||
if ( ! this.setLcLpPb( lc, lp, pb ) ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
dictionarySize = properties.readByte();
|
||||
dictionarySize |= properties.readByte() << 8;
|
||||
dictionarySize |= properties.readByte() << 16;
|
||||
dictionarySize += properties.readByte() * 16777216;
|
||||
|
||||
return this.setDictionarySize( dictionarySize );
|
||||
|
||||
};
|
||||
|
||||
LZMA.decompress = function ( properties, inStream, outStream, outSize ) {
|
||||
|
||||
var decoder = new LZMA.Decoder();
|
||||
|
||||
if ( ! decoder.setDecoderProperties( properties ) ) {
|
||||
|
||||
throw "Incorrect stream properties";
|
||||
|
||||
}
|
||||
|
||||
if ( ! decoder.decode( inStream, outStream, outSize ) ) {
|
||||
|
||||
throw "Error in data stream";
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
LZMA.decompressFile = function ( inStream, outStream ) {
|
||||
|
||||
var decoder = new LZMA.Decoder(), outSize;
|
||||
|
||||
if ( ! decoder.setDecoderProperties( inStream ) ) {
|
||||
|
||||
throw "Incorrect stream properties";
|
||||
|
||||
}
|
||||
|
||||
outSize = inStream.readByte();
|
||||
outSize |= inStream.readByte() << 8;
|
||||
outSize |= inStream.readByte() << 16;
|
||||
outSize += inStream.readByte() * 16777216;
|
||||
|
||||
inStream.readByte();
|
||||
inStream.readByte();
|
||||
inStream.readByte();
|
||||
inStream.readByte();
|
||||
|
||||
if ( ! decoder.decode( inStream, outStream, outSize ) ) {
|
||||
|
||||
throw "Error in data stream";
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
return LZMA;
|
||||
|
||||
}();
|
||||
|
||||
|
||||
/**
|
||||
* SEA3D LZMA
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
SEA3D.File.LZMAUncompress = function ( data ) {
|
||||
|
||||
data = new Uint8Array( data );
|
||||
|
||||
var inStream = {
|
||||
data: data,
|
||||
position: 0,
|
||||
readByte: function () {
|
||||
|
||||
return this.data[ this.position ++ ];
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
var outStream = {
|
||||
data: [],
|
||||
position: 0,
|
||||
writeByte: function ( value ) {
|
||||
|
||||
this.data[ this.position ++ ] = value;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
SEA3D.LZMA.decompressFile( inStream, outStream );
|
||||
|
||||
return new Uint8Array( outStream.data ).buffer;
|
||||
|
||||
};
|
||||
|
||||
SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );
|
||||
720
node_modules/three/examples/js/loaders/sea3d/SEA3DLegacy.js
generated
vendored
Normal file
720
node_modules/three/examples/js/loaders/sea3d/SEA3DLegacy.js
generated
vendored
Normal file
@@ -0,0 +1,720 @@
|
||||
/**
|
||||
* SEA3D Legacy for Three.JS
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
Object.assign( THREE.SEA3D.prototype, {
|
||||
|
||||
_onHead: THREE.SEA3D.prototype.onHead,
|
||||
_updateTransform: THREE.SEA3D.prototype.updateTransform,
|
||||
_readVertexAnimation: THREE.SEA3D.prototype.readVertexAnimation,
|
||||
_readGeometryBuffer: THREE.SEA3D.prototype.readGeometryBuffer,
|
||||
_readLine: THREE.SEA3D.prototype.readLine,
|
||||
_getAnimationType: THREE.SEA3D.prototype.getAnimationType,
|
||||
_readAnimation: THREE.SEA3D.prototype.readAnimation
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
// Utils
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.isLegacy = function ( sea ) {
|
||||
|
||||
var sea3d = sea.sea3d;
|
||||
|
||||
if ( sea3d.sign == 'S3D' && ! sea._legacy ) {
|
||||
|
||||
sea._legacy = sea3d.typeUnique[ sea.type ] == true;
|
||||
|
||||
return sea3d.config.legacy;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.flipVec3 = function ( v ) {
|
||||
|
||||
if ( ! v ) return;
|
||||
|
||||
var i = 2;
|
||||
|
||||
while ( i < v.length ) {
|
||||
|
||||
v[ i ] = - v[ i ];
|
||||
|
||||
i += 3;
|
||||
|
||||
}
|
||||
|
||||
return v;
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.expandJoints = function ( sea ) {
|
||||
|
||||
var numJoints = sea.numVertex * 4;
|
||||
|
||||
var joint = sea.isBig ? new Uint32Array( numJoints ) : new Uint16Array( numJoints );
|
||||
var weight = new Float32Array( numJoints );
|
||||
|
||||
var w = 0, jpv = sea.jointPerVertex;
|
||||
|
||||
for ( var i = 0; i < sea.numVertex; i ++ ) {
|
||||
|
||||
var tjsIndex = i * 4;
|
||||
var seaIndex = i * jpv;
|
||||
|
||||
joint[ tjsIndex ] = sea.joint[ seaIndex ];
|
||||
if ( jpv > 1 ) joint[ tjsIndex + 1 ] = sea.joint[ seaIndex + 1 ];
|
||||
if ( jpv > 2 ) joint[ tjsIndex + 2 ] = sea.joint[ seaIndex + 2 ];
|
||||
if ( jpv > 3 ) joint[ tjsIndex + 3 ] = sea.joint[ seaIndex + 3 ];
|
||||
|
||||
weight[ tjsIndex ] = sea.weight[ seaIndex ];
|
||||
if ( jpv > 1 ) weight[ tjsIndex + 1 ] = sea.weight[ seaIndex + 1 ];
|
||||
if ( jpv > 2 ) weight[ tjsIndex + 2 ] = sea.weight[ seaIndex + 2 ];
|
||||
if ( jpv > 3 ) weight[ tjsIndex + 3 ] = sea.weight[ seaIndex + 3 ];
|
||||
|
||||
w = weight[ tjsIndex ] + weight[ tjsIndex + 1 ] + weight[ tjsIndex + 2 ] + weight[ tjsIndex + 3 ];
|
||||
|
||||
weight[ tjsIndex ] += 1 - w;
|
||||
|
||||
}
|
||||
|
||||
sea.joint = joint;
|
||||
sea.weight = weight;
|
||||
|
||||
sea.jointPerVertex = 4;
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.compressJoints = function ( sea ) {
|
||||
|
||||
var numJoints = sea.numVertex * 4;
|
||||
|
||||
var joint = sea.isBig ? new Uint32Array( numJoints ) : new Uint16Array( numJoints );
|
||||
var weight = new Float32Array( numJoints );
|
||||
|
||||
var w = 0, jpv = sea.jointPerVertex;
|
||||
|
||||
for ( var i = 0; i < sea.numVertex; i ++ ) {
|
||||
|
||||
var tjsIndex = i * 4;
|
||||
var seaIndex = i * jpv;
|
||||
|
||||
joint[ tjsIndex ] = sea.joint[ seaIndex ];
|
||||
joint[ tjsIndex + 1 ] = sea.joint[ seaIndex + 1 ];
|
||||
joint[ tjsIndex + 2 ] = sea.joint[ seaIndex + 2 ];
|
||||
joint[ tjsIndex + 3 ] = sea.joint[ seaIndex + 3 ];
|
||||
|
||||
weight[ tjsIndex ] = sea.weight[ seaIndex ];
|
||||
weight[ tjsIndex + 1 ] = sea.weight[ seaIndex + 1 ];
|
||||
weight[ tjsIndex + 2 ] = sea.weight[ seaIndex + 2 ];
|
||||
weight[ tjsIndex + 3 ] = sea.weight[ seaIndex + 3 ];
|
||||
|
||||
w = weight[ tjsIndex ] + weight[ tjsIndex + 1 ] + weight[ tjsIndex + 2 ] + weight[ tjsIndex + 3 ];
|
||||
|
||||
weight[ tjsIndex ] += 1 - w;
|
||||
|
||||
}
|
||||
|
||||
sea.joint = joint;
|
||||
sea.weight = weight;
|
||||
|
||||
sea.jointPerVertex = 4;
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.flipIndexes = function ( v ) {
|
||||
|
||||
var i = 1; // y >-< z
|
||||
|
||||
while ( i < v.length ) {
|
||||
|
||||
var idx = v[ i + 1 ];
|
||||
v[ i + 1 ] = v[ i ];
|
||||
v[ i ] = idx;
|
||||
|
||||
i += 3;
|
||||
|
||||
}
|
||||
|
||||
return v;
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.flipBoneMatrix = function () {
|
||||
|
||||
var zero = new THREE.Vector3();
|
||||
|
||||
return function ( mtx ) {
|
||||
|
||||
var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx );
|
||||
pos.z = - pos.z;
|
||||
|
||||
mtx.setPosition( zero );
|
||||
mtx.multiplyMatrices( THREE.SEA3D.MTXBUF.makeRotationZ( THREE.Math.degToRad( 180 ) ), mtx );
|
||||
mtx.setPosition( pos );
|
||||
|
||||
return mtx;
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
THREE.SEA3D.prototype.flipScaleMatrix = function () {
|
||||
|
||||
var pos = new THREE.Vector3();
|
||||
var qua = new THREE.Quaternion();
|
||||
var slc = new THREE.Vector3();
|
||||
|
||||
return function ( local, rotate, parent, parentRotate ) {
|
||||
|
||||
if ( parent ) local.multiplyMatrices( parent, local );
|
||||
|
||||
local.decompose( pos, qua, slc );
|
||||
|
||||
slc.z = - slc.z;
|
||||
|
||||
local.compose( pos, qua, slc );
|
||||
|
||||
if ( rotate ) {
|
||||
|
||||
local.multiplyMatrices( local, THREE.SEA3D.MTXBUF.makeRotationZ( THREE.Math.degToRad( 180 ) ) );
|
||||
|
||||
}
|
||||
|
||||
if ( parent ) {
|
||||
|
||||
parent = parent.clone();
|
||||
|
||||
this.flipScaleMatrix( parent, parentRotate );
|
||||
|
||||
local.multiplyMatrices( parent.getInverse( parent ), local );
|
||||
|
||||
}
|
||||
|
||||
return local;
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
//
|
||||
// Legacy
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.flipDefaultAnimation = function () {
|
||||
|
||||
var buf1 = new THREE.Matrix4();
|
||||
var buf2 = new THREE.Matrix4();
|
||||
|
||||
var pos = new THREE.Vector3();
|
||||
var qua = new THREE.Quaternion();
|
||||
var slc = new THREE.Vector3();
|
||||
|
||||
var to_pos = new THREE.Vector3();
|
||||
var to_qua = new THREE.Quaternion();
|
||||
var to_slc = new THREE.Vector3();
|
||||
|
||||
return function ( animation, obj3d, relative ) {
|
||||
|
||||
if ( animation.isFliped ) return;
|
||||
|
||||
var dataList = animation.dataList,
|
||||
t_anm = [];
|
||||
|
||||
for ( var i = 0; i < dataList.length; i ++ ) {
|
||||
|
||||
var data = dataList[ i ],
|
||||
raw = data.data,
|
||||
kind = data.kind,
|
||||
numFrames = raw.length / data.blockSize;
|
||||
|
||||
switch ( kind ) {
|
||||
|
||||
case SEA3D.Animation.POSITION:
|
||||
case SEA3D.Animation.ROTATION:
|
||||
case SEA3D.Animation.SCALE:
|
||||
|
||||
t_anm.push( {
|
||||
kind: kind,
|
||||
numFrames: numFrames,
|
||||
raw: raw
|
||||
} );
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( t_anm.length > 0 ) {
|
||||
|
||||
var numFrames = t_anm[ 0 ].numFrames,
|
||||
parent = undefined;
|
||||
|
||||
if ( relative ) {
|
||||
|
||||
buf1.identity();
|
||||
parent = this.flipScaleMatrix( buf2.copy( obj3d.matrixWorld ) );
|
||||
|
||||
} else {
|
||||
|
||||
if ( obj3d.parent ) {
|
||||
|
||||
parent = this.flipScaleMatrix( buf2.copy( obj3d.parent.matrixWorld ) );
|
||||
|
||||
}
|
||||
|
||||
this.flipScaleMatrix( buf1.copy( obj3d.matrix ), false, parent );
|
||||
|
||||
}
|
||||
|
||||
buf1.decompose( pos, qua, slc );
|
||||
|
||||
for ( var f = 0, t, c; f < numFrames; f ++ ) {
|
||||
|
||||
for ( t = 0; t < t_anm.length; t ++ ) {
|
||||
|
||||
var raw = t_anm[ t ].raw,
|
||||
kind = t_anm[ t ].kind;
|
||||
|
||||
switch ( kind ) {
|
||||
|
||||
case SEA3D.Animation.POSITION:
|
||||
|
||||
c = f * 3;
|
||||
|
||||
pos.set(
|
||||
raw[ c ],
|
||||
raw[ c + 1 ],
|
||||
raw[ c + 2 ]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case SEA3D.Animation.ROTATION:
|
||||
|
||||
c = f * 4;
|
||||
|
||||
qua.set(
|
||||
raw[ c ],
|
||||
raw[ c + 1 ],
|
||||
raw[ c + 2 ],
|
||||
raw[ c + 3 ]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case SEA3D.Animation.SCALE:
|
||||
|
||||
c = f * 4;
|
||||
|
||||
slc.set(
|
||||
raw[ c ],
|
||||
raw[ c + 1 ],
|
||||
raw[ c + 2 ]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
buf1.compose( pos, qua, slc );
|
||||
|
||||
this.flipScaleMatrix( buf1, false, buf2 );
|
||||
|
||||
buf1.decompose( to_pos, to_qua, to_slc );
|
||||
|
||||
for ( t = 0; t < t_anm.length; t ++ ) {
|
||||
|
||||
var raw = t_anm[ t ].raw,
|
||||
kind = t_anm[ t ].kind;
|
||||
|
||||
switch ( kind ) {
|
||||
|
||||
case SEA3D.Animation.POSITION:
|
||||
|
||||
c = f * 3;
|
||||
|
||||
raw[ c ] = to_pos.x;
|
||||
raw[ c + 1 ] = to_pos.y;
|
||||
raw[ c + 2 ] = to_pos.z;
|
||||
|
||||
break;
|
||||
|
||||
case SEA3D.Animation.ROTATION:
|
||||
|
||||
c = f * 4;
|
||||
|
||||
raw[ c ] = to_qua.x;
|
||||
raw[ c + 1 ] = to_qua.y;
|
||||
raw[ c + 2 ] = to_qua.z;
|
||||
raw[ c + 3 ] = to_qua.w;
|
||||
|
||||
break;
|
||||
|
||||
case SEA3D.Animation.SCALE:
|
||||
|
||||
c = f * 3;
|
||||
|
||||
raw[ c ] = to_slc.x;
|
||||
raw[ c + 1 ] = to_slc.y;
|
||||
raw[ c + 2 ] = to_slc.z;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
animation.isFliped = true;
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
THREE.SEA3D.prototype.readAnimation = function ( sea ) {
|
||||
|
||||
if ( ! this.isLegacy( sea ) ) {
|
||||
|
||||
this._readAnimation( sea );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.getAnimationType = function ( req ) {
|
||||
|
||||
var sea = req.sea;
|
||||
|
||||
if ( this.isLegacy( sea ) ) {
|
||||
|
||||
switch ( sea.type ) {
|
||||
|
||||
case SEA3D.SkeletonAnimation.prototype.type:
|
||||
|
||||
this.readSkeletonAnimationLegacy( sea, req.skeleton );
|
||||
|
||||
return sea.tag;
|
||||
|
||||
break;
|
||||
|
||||
case SEA3D.Animation.prototype.type:
|
||||
|
||||
if ( req.scope instanceof THREE.Object3D ) {
|
||||
|
||||
this.flipDefaultAnimation( sea, req.scope, req.relative );
|
||||
|
||||
}
|
||||
|
||||
this._readAnimation( sea );
|
||||
|
||||
return sea.tag;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this._getAnimationType( req );
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.updateTransform = function () {
|
||||
|
||||
var buf1 = new THREE.Matrix4();
|
||||
var identity = new THREE.Matrix4();
|
||||
|
||||
return function ( obj3d, sea ) {
|
||||
|
||||
if ( this.isLegacy( sea ) ) {
|
||||
|
||||
if ( sea.transform ) buf1.elements.set( sea.transform );
|
||||
else buf1.makeTranslation( sea.position.x, sea.position.y, sea.position.z );
|
||||
|
||||
this.flipScaleMatrix(
|
||||
buf1, false,
|
||||
obj3d.parent ? obj3d.parent.matrixWorld : identity,
|
||||
obj3d.parent instanceof THREE.Bone
|
||||
);
|
||||
|
||||
obj3d.position.setFromMatrixPosition( buf1 );
|
||||
obj3d.scale.setFromMatrixScale( buf1 );
|
||||
|
||||
// ignore rotation scale
|
||||
|
||||
buf1.scale( THREE.SEA3D.VECBUF.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
|
||||
obj3d.rotation.setFromRotationMatrix( buf1 );
|
||||
|
||||
obj3d.updateMatrixWorld();
|
||||
|
||||
} else {
|
||||
|
||||
this._updateTransform( obj3d, sea );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
THREE.SEA3D.prototype.readSkeleton = function () {
|
||||
|
||||
var mtx_tmp_inv = new THREE.Matrix4(),
|
||||
mtx_local = new THREE.Matrix4(),
|
||||
mtx_parent = new THREE.Matrix4(),
|
||||
pos = new THREE.Vector3(),
|
||||
qua = new THREE.Quaternion();
|
||||
|
||||
return function ( sea ) {
|
||||
|
||||
var bones = [],
|
||||
isLegacy = sea.sea3d.config.legacy;
|
||||
|
||||
for ( var i = 0; i < sea.joint.length; i ++ ) {
|
||||
|
||||
var bone = sea.joint[ i ];
|
||||
|
||||
// get world inverse matrix
|
||||
|
||||
mtx_tmp_inv.elements = bone.inverseBindMatrix;
|
||||
|
||||
// convert to world matrix
|
||||
|
||||
mtx_local.getInverse( mtx_tmp_inv );
|
||||
|
||||
// convert to three.js order
|
||||
|
||||
if ( isLegacy ) this.flipBoneMatrix( mtx_local );
|
||||
|
||||
if ( bone.parentIndex > - 1 ) {
|
||||
|
||||
// to world
|
||||
|
||||
mtx_tmp_inv.elements = sea.joint[ bone.parentIndex ].inverseBindMatrix;
|
||||
mtx_parent.getInverse( mtx_tmp_inv );
|
||||
|
||||
// convert parent to three.js order
|
||||
|
||||
if ( isLegacy ) this.flipBoneMatrix( mtx_parent );
|
||||
|
||||
// to local
|
||||
|
||||
mtx_parent.getInverse( mtx_parent );
|
||||
|
||||
mtx_local.multiplyMatrices( mtx_parent, mtx_local );
|
||||
|
||||
}
|
||||
|
||||
// apply matrix
|
||||
|
||||
pos.setFromMatrixPosition( mtx_local );
|
||||
qua.setFromRotationMatrix( mtx_local );
|
||||
|
||||
bones[ i ] = {
|
||||
name: bone.name,
|
||||
pos: [ pos.x, pos.y, pos.z ],
|
||||
rotq: [ qua.x, qua.y, qua.z, qua.w ],
|
||||
parent: bone.parentIndex
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return sea.tag = bones;
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
THREE.SEA3D.prototype.readSkeletonAnimationLegacy = function () {
|
||||
|
||||
var mtx_tmp_inv = new THREE.Matrix4(),
|
||||
mtx_local = new THREE.Matrix4(),
|
||||
mtx_global = new THREE.Matrix4(),
|
||||
mtx_parent = new THREE.Matrix4();
|
||||
|
||||
return function ( sea, skl ) {
|
||||
|
||||
if ( sea.tag ) return sea.tag;
|
||||
|
||||
var animations = [],
|
||||
delta = ( 1000 / sea.frameRate ) / 1000,
|
||||
scale = [ 1, 1, 1 ];
|
||||
|
||||
for ( var i = 0; i < sea.sequence.length; i ++ ) {
|
||||
|
||||
var seq = sea.sequence[ i ];
|
||||
|
||||
var start = seq.start;
|
||||
var end = start + seq.count;
|
||||
|
||||
var animation = {
|
||||
name: seq.name,
|
||||
repeat: seq.repeat,
|
||||
fps: sea.frameRate,
|
||||
JIT: 0,
|
||||
length: delta * seq.count,
|
||||
hierarchy: []
|
||||
};
|
||||
|
||||
var numJoints = sea.numJoints,
|
||||
raw = sea.raw;
|
||||
|
||||
for ( var j = 0; j < numJoints; j ++ ) {
|
||||
|
||||
var bone = skl.joint[ j ],
|
||||
node = { parent: bone.parentIndex, keys: [] },
|
||||
keys = node.keys,
|
||||
time = 0;
|
||||
|
||||
for ( var frame = start; frame < end; frame ++ ) {
|
||||
|
||||
var idx = ( frame * numJoints * 7 ) + ( j * 7 );
|
||||
|
||||
mtx_local.makeRotationFromQuaternion( THREE.SEA3D.QUABUF.set( raw[ idx + 3 ], raw[ idx + 4 ], raw[ idx + 5 ], raw[ idx + 6 ] ) );
|
||||
mtx_local.setPosition( THREE.SEA3D.VECBUF.set( raw[ idx ], raw[ idx + 1 ], raw[ idx + 2 ] ) );
|
||||
|
||||
if ( bone.parentIndex > - 1 ) {
|
||||
|
||||
// to global
|
||||
|
||||
mtx_tmp_inv.elements = skl.joint[ bone.parentIndex ].inverseBindMatrix;
|
||||
|
||||
mtx_parent.getInverse( mtx_tmp_inv );
|
||||
|
||||
mtx_global.multiplyMatrices( mtx_parent, mtx_local );
|
||||
|
||||
// convert to three.js matrix
|
||||
|
||||
this.flipBoneMatrix( mtx_global );
|
||||
|
||||
// flip parent inverse
|
||||
|
||||
this.flipBoneMatrix( mtx_parent );
|
||||
|
||||
// to local
|
||||
|
||||
mtx_parent.getInverse( mtx_parent );
|
||||
|
||||
mtx_local.multiplyMatrices( mtx_parent, mtx_global );
|
||||
|
||||
} else {
|
||||
|
||||
this.flipBoneMatrix( mtx_local );
|
||||
|
||||
}
|
||||
|
||||
var posQ = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx_local );
|
||||
var newQ = THREE.SEA3D.QUABUF.setFromRotationMatrix( mtx_local );
|
||||
|
||||
keys.push( {
|
||||
time: time,
|
||||
pos: [ posQ.x, posQ.y, posQ.z ],
|
||||
rot: [ newQ.x, newQ.y, newQ.z, newQ.w ],
|
||||
scl: scale
|
||||
} );
|
||||
|
||||
time += delta;
|
||||
|
||||
}
|
||||
|
||||
animation.hierarchy[ j ] = node;
|
||||
|
||||
}
|
||||
|
||||
animations.push( THREE.SEA3D.AnimationClip.fromClip( THREE.AnimationClip.parseAnimation( animation, skl.tag ), seq.repeat ) );
|
||||
|
||||
}
|
||||
|
||||
this.domain.clips = this.clips = this.clips || [];
|
||||
this.clips.push( this.objects[ sea.name + '.anm' ] = sea.tag = animations );
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
THREE.SEA3D.prototype.readVertexAnimation = function ( sea ) {
|
||||
|
||||
if ( this.isLegacy( sea ) ) {
|
||||
|
||||
for ( var i = 0, l = sea.frame.length; i < l; i ++ ) {
|
||||
|
||||
var frame = sea.frame[ i ];
|
||||
|
||||
this.flipVec3( frame.vertex );
|
||||
this.flipVec3( frame.normal );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._readVertexAnimation( sea );
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.readGeometryBuffer = function ( sea ) {
|
||||
|
||||
if ( this.isLegacy( sea ) ) {
|
||||
|
||||
this.flipVec3( sea.vertex, true );
|
||||
this.flipVec3( sea.normal, true );
|
||||
|
||||
this.flipIndexes( sea.indexes );
|
||||
|
||||
if ( sea.jointPerVertex > 4 ) this.compressJoints( sea );
|
||||
else if ( sea.jointPerVertex < 4 ) this.expandJoints( sea );
|
||||
|
||||
}
|
||||
|
||||
this._readGeometryBuffer( sea );
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.readLines = function ( sea ) {
|
||||
|
||||
if ( this.isLegacy( sea ) ) {
|
||||
|
||||
this.flipVec3( sea.vertex );
|
||||
|
||||
}
|
||||
|
||||
this._readLines( sea );
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.prototype.onHead = function ( args ) {
|
||||
|
||||
if ( args.sign != "S3D" && args.sign != "TJS" ) {
|
||||
|
||||
throw new Error( "Sign '" + args.sign + "' unknown." );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.EXTENSIONS_LOADER.push( { setTypeRead: function () {
|
||||
|
||||
// CONFIG
|
||||
|
||||
this.config.legacy = this.config.legacy == undefined ? true : this.config.legacy;
|
||||
|
||||
this.file.typeRead[ SEA3D.Skeleton.prototype.type ] = this.readSkeleton;
|
||||
|
||||
} } );
|
||||
3551
node_modules/three/examples/js/loaders/sea3d/SEA3DLoader.js
generated
vendored
Normal file
3551
node_modules/three/examples/js/loaders/sea3d/SEA3DLoader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
154
node_modules/three/examples/js/loaders/sea3d/o3dgc/SEA3DGC.js
generated
vendored
Normal file
154
node_modules/three/examples/js/loaders/sea3d/o3dgc/SEA3DGC.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* SEA3D - o3dgc
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Lossy Compression
|
||||
//
|
||||
|
||||
SEA3D.GeometryGC = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
var i;
|
||||
var attrib = data.readUShort();
|
||||
var uvIDs = [], jointID, weightID;
|
||||
|
||||
this.isBig = ( attrib & 1 ) != 0;
|
||||
|
||||
data.readVInt = this.isBig ? data.readUInt : data.readUShort;
|
||||
|
||||
// Geometry Flags
|
||||
// ..
|
||||
// 1 isBig
|
||||
// 2 groups
|
||||
// 4 uv
|
||||
// 8 tangent
|
||||
// 16 colors
|
||||
// 32 joints
|
||||
// 64 morph
|
||||
// 128 vertex-animation
|
||||
// ..
|
||||
|
||||
if ( attrib & 2 ) {
|
||||
|
||||
this.groups = [];
|
||||
|
||||
var numGroups = data.readUByte(),
|
||||
groupOffset = 0;
|
||||
|
||||
for ( i = 0; i < numGroups; i ++ ) {
|
||||
|
||||
var groupLength = data.readVInt() * 3;
|
||||
|
||||
this.groups.push( {
|
||||
start: groupOffset,
|
||||
count: groupLength,
|
||||
} );
|
||||
|
||||
groupOffset += groupLength;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.groups = [];
|
||||
|
||||
}
|
||||
|
||||
if ( attrib & 4 ) {
|
||||
|
||||
this.uv = [];
|
||||
|
||||
var uvCount = data.readUByte();
|
||||
|
||||
for ( i = 0; i < uvCount; i ++ ) {
|
||||
|
||||
uvIDs[ i ] = data.readUByte();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( attrib & 32 ) {
|
||||
|
||||
jointID = data.readUByte();
|
||||
weightID = data.readUByte();
|
||||
|
||||
}
|
||||
|
||||
var size = data.readUInt();
|
||||
var bytes = data.concat( data.position, size );
|
||||
|
||||
var bstream = new o3dgc.BinaryStream( bytes.buffer );
|
||||
|
||||
var decoder = new o3dgc.SC3DMCDecoder();
|
||||
var ifs = new o3dgc.IndexedFaceSet();
|
||||
|
||||
decoder.DecodeHeader( ifs, bstream );
|
||||
|
||||
var numIndexes = ifs.GetNCoordIndex();
|
||||
var numVertex = ifs.GetNCoord();
|
||||
|
||||
if ( ! this.groups.length ) this.groups.push( { start: 0, count: numIndexes * 3 } );
|
||||
|
||||
this.indexes = this.isBig ? new Uint32Array( numIndexes * 3 ) : new Uint16Array( numIndexes * 3 );
|
||||
this.vertex = new Float32Array( numVertex * 3 );
|
||||
|
||||
ifs.SetCoordIndex( this.indexes );
|
||||
ifs.SetCoord( this.vertex );
|
||||
|
||||
if ( ifs.GetNNormal() > 0 ) {
|
||||
|
||||
this.normal = new Float32Array( numVertex * 3 );
|
||||
ifs.SetNormal( this.normal );
|
||||
|
||||
}
|
||||
|
||||
for ( i = 0; i < uvIDs.length; i ++ ) {
|
||||
|
||||
this.uv[ i ] = new Float32Array( numVertex * 2 );
|
||||
ifs.SetFloatAttribute( uvIDs[ i ], this.uv[ i ] );
|
||||
|
||||
}
|
||||
|
||||
if ( jointID !== undefined ) {
|
||||
|
||||
this.jointPerVertex = ifs.GetIntAttributeDim( jointID );
|
||||
|
||||
this.joint = new Uint16Array( numVertex * this.jointPerVertex );
|
||||
this.weight = new Float32Array( numVertex * this.jointPerVertex );
|
||||
|
||||
ifs.SetIntAttribute( jointID, this.joint );
|
||||
ifs.SetFloatAttribute( weightID, this.weight );
|
||||
|
||||
}
|
||||
|
||||
// decode mesh
|
||||
|
||||
decoder.DecodePlayload( ifs, bstream );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.GeometryGC.prototype.type = "s3D";
|
||||
|
||||
//
|
||||
// Extension
|
||||
//
|
||||
|
||||
THREE.SEA3D.EXTENSIONS_LOADER.push( {
|
||||
|
||||
setTypeRead: function () {
|
||||
|
||||
this.file.addClass( SEA3D.GeometryGC, true );
|
||||
|
||||
this.file.typeRead[ SEA3D.GeometryGC.prototype.type ] = this.readGeometryBuffer;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
409
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DAmmo.js
generated
vendored
Normal file
409
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DAmmo.js
generated
vendored
Normal file
@@ -0,0 +1,409 @@
|
||||
/** _ _ _ _____ __ _______ ______
|
||||
* | |___| |_| |__ /__ | | | | _ | * *
|
||||
* | / _ \ _| | __\ | | \ | _ | U _
|
||||
* |_\___/\__|_||_| _ |____/____ |__ \_|_ |_|_____|
|
||||
*
|
||||
* @author LoTh / http://3dflashlo.wordpress.com/
|
||||
* @author SUNAG / http://www.sunag.com.br/
|
||||
* @author Ammo.lab / https://github.com/lo-th/Ammo.lab/
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
SEA3D.AMMO = {
|
||||
|
||||
world: null,
|
||||
|
||||
rigidBodies: [],
|
||||
rigidBodiesTarget: [],
|
||||
rigidBodiesEnabled: [],
|
||||
|
||||
constraints: [],
|
||||
|
||||
vehicles: [],
|
||||
vehiclesWheels: [],
|
||||
|
||||
ACTIVE: 1,
|
||||
ISLAND_SLEEPING: 2,
|
||||
WANTS_DEACTIVATION: 3,
|
||||
DISABLE_DEACTIVATION: 4,
|
||||
DISABLE_SIMULATION: 5,
|
||||
VERSION: 0.8,
|
||||
|
||||
init: function ( gravity, worldScale, broadphase ) {
|
||||
|
||||
gravity = gravity !== undefined ? gravity : - 90.8;
|
||||
|
||||
this.worldScale = worldScale == undefined ? 1 : worldScale;
|
||||
this.broadphase = broadphase == undefined ? 'bvt' : broadphase;
|
||||
|
||||
this.solver = new Ammo.btSequentialImpulseConstraintSolver();
|
||||
this.collisionConfig = new Ammo.btDefaultCollisionConfiguration();
|
||||
this.dispatcher = new Ammo.btCollisionDispatcher( this.collisionConfig );
|
||||
|
||||
switch ( this.broadphase ) {
|
||||
|
||||
case 'bvt':
|
||||
|
||||
this.broadphase = new Ammo.btDbvtBroadphase();
|
||||
|
||||
break;
|
||||
|
||||
case 'sap':
|
||||
|
||||
this.broadphase = new Ammo.btAxisSweep3(
|
||||
new Ammo.btVector3( - this.worldScale, - this.worldScale, - this.worldScale ),
|
||||
new Ammo.btVector3( this.worldScale, this.worldScale, this.worldScale ),
|
||||
4096
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'simple':
|
||||
|
||||
this.broadphase = new Ammo.btSimpleBroadphase();
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
this.world = new Ammo.btDiscreteDynamicsWorld( this.dispatcher, this.broadphase, this.solver, this.collisionConfig );
|
||||
|
||||
this.setGravity( gravity );
|
||||
|
||||
console.log( "THREE.AMMO " + this.VERSION );
|
||||
|
||||
},
|
||||
|
||||
setGravity: function ( gravity ) {
|
||||
|
||||
this.gravity = gravity;
|
||||
|
||||
this.world.setGravity( new Ammo.btVector3( 0, gravity, 0 ) );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
getGravity: function () {
|
||||
|
||||
return this.gravity;
|
||||
|
||||
},
|
||||
|
||||
setEnabledRigidBody: function ( rb, enabled ) {
|
||||
|
||||
var index = this.rigidBodies.indexOf( rb );
|
||||
|
||||
if ( this.rigidBodiesEnabled[ index ] == enabled ) return;
|
||||
|
||||
if ( enabled ) this.world.addRigidBody( rb );
|
||||
else this.world.removeRigidBody( rb );
|
||||
|
||||
this.rigidBodiesEnabled[ index ] = true;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
getEnabledRigidBody: function ( rb ) {
|
||||
|
||||
return this.rigidBodiesEnabled[ this.rigidBodies.indexOf( rb ) ];
|
||||
|
||||
},
|
||||
addRigidBody: function ( rb, target, enabled ) {
|
||||
|
||||
enabled = enabled !== undefined ? enabled : true;
|
||||
|
||||
this.rigidBodies.push( rb );
|
||||
this.rigidBodiesTarget.push( target );
|
||||
this.rigidBodiesEnabled.push( false );
|
||||
|
||||
this.setEnabledRigidBody( rb, enabled );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
removeRigidBody: function ( rb, destroy ) {
|
||||
|
||||
var index = this.rigidBodies.indexOf( rb );
|
||||
|
||||
this.setEnabledRigidBody( rb, false );
|
||||
|
||||
this.rigidBodies.splice( index, 1 );
|
||||
this.rigidBodiesTarget.splice( index, 1 );
|
||||
this.rigidBodiesEnabled.splice( index, 1 );
|
||||
|
||||
if ( destroy ) Ammo.destroy( rb );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
containsRigidBody: function ( rb ) {
|
||||
|
||||
return this.rigidBodies.indexOf( rb ) > - 1;
|
||||
|
||||
},
|
||||
|
||||
addConstraint: function ( ctrt, disableCollisionsBetweenBodies ) {
|
||||
|
||||
disableCollisionsBetweenBodies = disableCollisionsBetweenBodies == undefined ? true : disableCollisionsBetweenBodies;
|
||||
|
||||
this.constraints.push( ctrt );
|
||||
this.world.addConstraint( ctrt, disableCollisionsBetweenBodies );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
removeConstraint: function ( ctrt, destroy ) {
|
||||
|
||||
this.constraints.splice( this.constraints.indexOf( ctrt ), 1 );
|
||||
this.world.removeConstraint( ctrt );
|
||||
|
||||
if ( destroy ) Ammo.destroy( ctrt );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
containsConstraint: function ( ctrt ) {
|
||||
|
||||
return this.constraints.indexOf( rb ) > - 1;
|
||||
|
||||
},
|
||||
|
||||
addVehicle: function ( vehicle, wheels ) {
|
||||
|
||||
this.vehicles.push( vehicle );
|
||||
this.vehiclesWheels.push( wheels != undefined ? wheels : [] );
|
||||
|
||||
this.world.addAction( vehicle );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
removeVehicle: function ( vehicle, destroy ) {
|
||||
|
||||
var index = this.vehicles.indexOf( vehicle );
|
||||
|
||||
this.vehicles.splice( index, 1 );
|
||||
this.vehiclesWheels.splice( index, 1 );
|
||||
|
||||
this.world.removeAction( vehicle );
|
||||
|
||||
if ( destroy ) Ammo.destroy( vehicle );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
containsVehicle: function ( vehicle ) {
|
||||
|
||||
return this.vehicles.indexOf( vehicle ) > - 1;
|
||||
|
||||
},
|
||||
|
||||
createTriangleMesh: function ( geometry, index, removeDuplicateVertices ) {
|
||||
|
||||
index = index == undefined ? - 1 : index;
|
||||
removeDuplicateVertices = removeDuplicateVertices == undefined ? false : removeDuplicateVertices;
|
||||
|
||||
var mTriMesh = new Ammo.btTriangleMesh();
|
||||
|
||||
var v0 = new Ammo.btVector3( 0, 0, 0 );
|
||||
var v1 = new Ammo.btVector3( 0, 0, 0 );
|
||||
var v2 = new Ammo.btVector3( 0, 0, 0 );
|
||||
|
||||
var vertex = geometry.getAttribute( 'position' ).array;
|
||||
var indexes = geometry.getIndex().array;
|
||||
|
||||
var group = index >= 0 ? geometry.groups[ index ] : undefined,
|
||||
start = group ? group.start : 0,
|
||||
count = group ? group.count : indexes.length;
|
||||
|
||||
var scale = 1 / this.worldScale;
|
||||
|
||||
for ( var idx = start; idx < count; idx += 3 ) {
|
||||
|
||||
var vx1 = indexes[ idx ] * 3,
|
||||
vx2 = indexes[ idx + 1 ] * 3,
|
||||
vx3 = indexes[ idx + 2 ] * 3;
|
||||
|
||||
v0.setValue( vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale );
|
||||
v1.setValue( vertex[ vx2 ] * scale, vertex[ vx2 + 1 ] * scale, vertex[ vx2 + 2 ] * scale );
|
||||
v2.setValue( vertex[ vx3 ] * scale, vertex[ vx3 + 1 ] * scale, vertex[ vx3 + 2 ] * scale );
|
||||
|
||||
mTriMesh.addTriangle( v0, v1, v2, removeDuplicateVertices );
|
||||
|
||||
}
|
||||
|
||||
return mTriMesh;
|
||||
|
||||
},
|
||||
createConvexHull: function ( geometry, index ) {
|
||||
|
||||
index = index == undefined ? - 1 : index;
|
||||
|
||||
var mConvexHull = new Ammo.btConvexHullShape();
|
||||
|
||||
var v0 = new Ammo.btVector3( 0, 0, 0 );
|
||||
|
||||
var vertex = geometry.getAttribute( 'position' ).array;
|
||||
var indexes = geometry.getIndex().array;
|
||||
|
||||
var group = index >= 0 ? geometry.groups[ index ] : undefined,
|
||||
start = group ? group.start : 0,
|
||||
count = group ? group.count : indexes.length;
|
||||
|
||||
var scale = 1 / this.worldScale;
|
||||
|
||||
for ( var idx = start; idx < count; idx += 3 ) {
|
||||
|
||||
var vx1 = indexes[ idx ] * 3;
|
||||
|
||||
var point = new Ammo.btVector3(
|
||||
vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale
|
||||
);
|
||||
|
||||
mConvexHull.addPoint( point );
|
||||
|
||||
}
|
||||
|
||||
return mConvexHull;
|
||||
|
||||
},
|
||||
|
||||
getTargetByRigidBody: function ( rb ) {
|
||||
|
||||
return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ];
|
||||
|
||||
},
|
||||
getRigidBodyByTarget: function ( target ) {
|
||||
|
||||
return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ];
|
||||
|
||||
},
|
||||
getTransformFromMatrix: function ( mtx ) {
|
||||
|
||||
var transform = new Ammo.btTransform();
|
||||
|
||||
var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx );
|
||||
transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
|
||||
|
||||
var scl = THREE.SEA3D.VECBUF.setFromMatrixScale( mtx );
|
||||
mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) );
|
||||
|
||||
var quat = new THREE.Quaternion().setFromRotationMatrix( mtx );
|
||||
|
||||
var q = new Ammo.btQuaternion();
|
||||
q.setValue( quat.x, quat.y, quat.z, quat.w );
|
||||
transform.setRotation( q );
|
||||
|
||||
Ammo.destroy( q );
|
||||
|
||||
return transform;
|
||||
|
||||
},
|
||||
getMatrixFromTransform: function ( transform ) {
|
||||
|
||||
var position = new THREE.Vector3();
|
||||
var quaternion = new THREE.Quaternion();
|
||||
var scale = new THREE.Vector3( 1, 1, 1 );
|
||||
|
||||
return function ( transform, matrix ) {
|
||||
|
||||
matrix = matrix || new THREE.Matrix4();
|
||||
|
||||
var pos = transform.getOrigin(),
|
||||
quat = transform.getRotation();
|
||||
|
||||
position.set( pos.x(), pos.y(), pos.z() );
|
||||
quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
|
||||
|
||||
matrix.compose( position, quaternion, scale );
|
||||
|
||||
return matrix;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
|
||||
updateTargetTransform: function () {
|
||||
|
||||
var matrix = new THREE.Matrix4();
|
||||
|
||||
var position = new THREE.Vector3();
|
||||
var quaternion = new THREE.Quaternion();
|
||||
var scale = new THREE.Vector3( 1, 1, 1 );
|
||||
|
||||
return function ( obj3d, transform, offset ) {
|
||||
|
||||
var pos = transform.getOrigin(),
|
||||
quat = transform.getRotation();
|
||||
|
||||
if ( offset ) {
|
||||
|
||||
position.set( pos.x(), pos.y(), pos.z() );
|
||||
quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
|
||||
|
||||
matrix.compose( position, quaternion, scale );
|
||||
|
||||
matrix.multiplyMatrices( matrix, offset );
|
||||
|
||||
obj3d.position.setFromMatrixPosition( matrix );
|
||||
obj3d.quaternion.setFromRotationMatrix( matrix );
|
||||
|
||||
} else {
|
||||
|
||||
obj3d.position.set( pos.x(), pos.y(), pos.z() );
|
||||
obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
}(),
|
||||
update: function ( delta, iteration, fixedDelta ) {
|
||||
|
||||
this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) );
|
||||
|
||||
var i, j;
|
||||
|
||||
for ( i = 0; i < this.vehicles.length; i ++ ) {
|
||||
|
||||
var vehicle = this.vehicles[ i ],
|
||||
numWheels = vehicle.getNumWheels(),
|
||||
wheels = this.vehiclesWheels[ i ];
|
||||
|
||||
for ( j = 0; j < numWheels; j ++ ) {
|
||||
|
||||
vehicle.updateWheelTransform( j, true );
|
||||
|
||||
var wheelsTransform = vehicle.getWheelTransformWS( j ),
|
||||
wheelTarget = wheels[ j ];
|
||||
|
||||
if ( wheelTarget ) {
|
||||
|
||||
this.updateTargetTransform( wheelTarget, wheelsTransform, wheelTarget.physics ? wheelTarget.physics.offset : null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( i = 0; i < this.rigidBodies.length; i ++ ) {
|
||||
|
||||
var rb = this.rigidBodies[ i ],
|
||||
target = this.rigidBodiesTarget[ i ];
|
||||
|
||||
if ( target && rb.isActive() ) {
|
||||
|
||||
this.updateTargetTransform( target, rb.getWorldTransform(), target.physics ? target.physics.offset : null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
};
|
||||
590
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DAmmoLoader.js
generated
vendored
Normal file
590
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DAmmoLoader.js
generated
vendored
Normal file
@@ -0,0 +1,590 @@
|
||||
/**
|
||||
* SEA3D+AMMO for Three.JS
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
THREE.SEA3D.prototype.toAmmoVec3 = function ( v ) {
|
||||
|
||||
return new Ammo.btVector3( v.x, v.y, v.z );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Sphere
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readSphere = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btSphereShape( sea.radius );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Box
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readBox = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btBoxShape( new Ammo.btVector3( sea.width * .5, sea.height * .5, sea.depth * .5 ) );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Cone
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readCone = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btConeShape( sea.radius, sea.height );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Cylinder
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readCylinder = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btCylinderShape( new Ammo.btVector3( sea.height, sea.radius, sea.radius ) );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Capsule
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readCapsule = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btCapsuleShape( sea.radius, sea.height );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Convex Geometry
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readConvexGeometry = function ( sea ) {
|
||||
|
||||
if ( this.config.convexHull ) {
|
||||
|
||||
var shape = SEA3D.AMMO.createConvexHull( sea.geometry.tag, sea.subGeometryIndex );
|
||||
|
||||
} else {
|
||||
|
||||
var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
|
||||
|
||||
var shape = new Ammo.btConvexTriangleMeshShape( triMesh, true );
|
||||
|
||||
}
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Triangle Geometry
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readTriangleGeometry = function ( sea ) {
|
||||
|
||||
var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
|
||||
|
||||
var shape = new Ammo.btBvhTriangleMeshShape( triMesh, true, true );
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Compound
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readCompound = function ( sea ) {
|
||||
|
||||
var shape = new Ammo.btCompoundShape();
|
||||
|
||||
for ( var i = 0; i < sea.compounds.length; i ++ ) {
|
||||
|
||||
var compound = sea.compounds[ i ];
|
||||
|
||||
THREE.SEA3D.MTXBUF.elements = compound.transform;
|
||||
|
||||
var transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
|
||||
|
||||
shape.addChildShape( transform, compound.shape.tag );
|
||||
|
||||
}
|
||||
|
||||
this.domain.shapes = this.shapes = this.shapes || [];
|
||||
this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Rigid Body Base
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readRigidBodyBase = function ( sea ) {
|
||||
|
||||
var shape = sea.shape.tag,
|
||||
transform, target;
|
||||
|
||||
if ( sea.target ) {
|
||||
|
||||
target = sea.target.tag;
|
||||
|
||||
target.physics = { enabled: true };
|
||||
target.updateMatrix();
|
||||
|
||||
transform = SEA3D.AMMO.getTransformFromMatrix( sea.target.tag.matrix );
|
||||
|
||||
} else {
|
||||
|
||||
THREE.SEA3D.MTXBUF.elements.set( sea.transform );
|
||||
|
||||
transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
|
||||
|
||||
}
|
||||
|
||||
var motionState = new Ammo.btDefaultMotionState( transform );
|
||||
var localInertia = new Ammo.btVector3( 0, 0, 0 );
|
||||
|
||||
shape.calculateLocalInertia( sea.mass, localInertia );
|
||||
|
||||
var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
|
||||
info.set_m_friction( sea.friction );
|
||||
info.set_m_restitution( sea.restitution );
|
||||
info.set_m_linearDamping( sea.linearDamping );
|
||||
info.set_m_angularDamping( sea.angularDamping );
|
||||
|
||||
var rb = new Ammo.btRigidBody( info );
|
||||
|
||||
if ( target ) {
|
||||
|
||||
target.physics.rigidBody = rb;
|
||||
|
||||
if ( sea.offset ) {
|
||||
|
||||
var offset = new THREE.Matrix4();
|
||||
offset.elements.set( sea.offset );
|
||||
|
||||
target.physics.offset = offset;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Ammo.destroy( info );
|
||||
|
||||
this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
|
||||
this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
|
||||
|
||||
return rb;
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Rigid Body
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readRigidBody = function ( sea ) {
|
||||
|
||||
var rb = this.readRigidBodyBase( sea );
|
||||
|
||||
SEA3D.AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Car Controller
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readCarController = function ( sea ) {
|
||||
|
||||
var body = this.readRigidBodyBase( sea );
|
||||
|
||||
body.setActivationState( SEA3D.AMMO.DISABLE_DEACTIVATION );
|
||||
|
||||
// Car
|
||||
|
||||
var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( SEA3D.AMMO.world );
|
||||
|
||||
var tuning = new Ammo.btVehicleTuning();
|
||||
|
||||
tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
|
||||
tuning.set_m_suspensionDamping( sea.suspensionDamping );
|
||||
tuning.set_m_suspensionCompression( sea.suspensionCompression );
|
||||
tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
|
||||
tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
|
||||
tuning.set_m_frictionSlip( sea.frictionSlip );
|
||||
|
||||
var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
|
||||
wheels = [];
|
||||
|
||||
vehicle.setCoordinateSystem( 0, 1, 2 );
|
||||
|
||||
for ( var i = 0; i < sea.wheel.length; i ++ ) {
|
||||
|
||||
var wheel = sea.wheel[ i ];
|
||||
|
||||
var wheelInfo = vehicle.addWheel(
|
||||
this.toAmmoVec3( wheel.pos ),
|
||||
this.toAmmoVec3( wheel.dir ),
|
||||
this.toAmmoVec3( wheel.axle ),
|
||||
wheel.suspensionRestLength,
|
||||
wheel.radius,
|
||||
tuning,
|
||||
wheel.isFront
|
||||
);
|
||||
|
||||
var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
|
||||
|
||||
if ( target ) {
|
||||
|
||||
target.physics = { enabled: true, rigidBody: wheelInfo };
|
||||
|
||||
if ( wheel.offset ) {
|
||||
|
||||
var offset = new THREE.Matrix4();
|
||||
offset.elements.set( wheel.offset );
|
||||
|
||||
target.physics.offset = offset;
|
||||
|
||||
}
|
||||
|
||||
if ( target.parent ) {
|
||||
|
||||
target.parent.remove( target );
|
||||
|
||||
}
|
||||
|
||||
if ( this.container ) {
|
||||
|
||||
this.container.add( target );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
|
||||
wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
|
||||
wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
|
||||
wheelInfo.set_m_frictionSlip( sea.frictionSlip );
|
||||
|
||||
}
|
||||
|
||||
SEA3D.AMMO.addVehicle( vehicle, wheels );
|
||||
SEA3D.AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, this.config.enabledPhysics );
|
||||
|
||||
this.domain.vehicles = this.vehicles = this.vehicles || [];
|
||||
this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// P2P Constraint
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readP2PConstraint = function ( sea ) {
|
||||
|
||||
var ctrt;
|
||||
|
||||
if ( sea.targetB ) {
|
||||
|
||||
ctrt = new Ammo.btPoint2PointConstraint(
|
||||
sea.targetA.tag,
|
||||
sea.targetB.tag,
|
||||
this.toAmmoVec3( sea.pointA ),
|
||||
this.toAmmoVec3( sea.pointB )
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
ctrt = new Ammo.btPoint2PointConstraint(
|
||||
sea.targetA.tag,
|
||||
this.toAmmoVec3( sea.pointA )
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
SEA3D.AMMO.addConstraint( ctrt );
|
||||
|
||||
this.domain.constraints = this.constraints = this.constraints || [];
|
||||
this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Hinge Constraint
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readHingeConstraint = function ( sea ) {
|
||||
|
||||
var ctrt;
|
||||
|
||||
if ( sea.targetB ) {
|
||||
|
||||
ctrt = new Ammo.btHingeConstraint(
|
||||
sea.targetA.tag,
|
||||
sea.targetB.tag,
|
||||
this.toAmmoVec3( sea.pointA ),
|
||||
this.toAmmoVec3( sea.pointB ),
|
||||
this.toAmmoVec3( sea.axisA ),
|
||||
this.toAmmoVec3( sea.axisB ),
|
||||
false
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
ctrt = new Ammo.btHingeConstraint(
|
||||
sea.targetA.tag,
|
||||
this.toAmmoVec3( sea.pointA ),
|
||||
this.toAmmoVec3( sea.axisA ),
|
||||
false
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if ( sea.limit ) {
|
||||
|
||||
ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
|
||||
|
||||
}
|
||||
|
||||
if ( sea.angularMotor ) {
|
||||
|
||||
ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
|
||||
|
||||
}
|
||||
|
||||
SEA3D.AMMO.addConstraint( ctrt );
|
||||
|
||||
this.domain.constraints = this.constraints = this.constraints || [];
|
||||
this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Cone Twist Constraint
|
||||
//
|
||||
|
||||
THREE.SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
|
||||
|
||||
var ctrt;
|
||||
|
||||
if ( sea.targetB ) {
|
||||
|
||||
ctrt = new Ammo.btConeTwistConstraint(
|
||||
sea.targetA.tag,
|
||||
sea.targetB.tag,
|
||||
this.toAmmoVec3( sea.pointA ),
|
||||
this.toAmmoVec3( sea.pointB ),
|
||||
false
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
ctrt = new Ammo.btConeTwistConstraint(
|
||||
sea.targetA.tag,
|
||||
this.toAmmoVec3( sea.pointA ),
|
||||
false
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
SEA3D.AMMO.addConstraint( ctrt );
|
||||
|
||||
this.domain.constraints = this.constraints = this.constraints || [];
|
||||
this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
|
||||
THREE.SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
|
||||
|
||||
var i = this.rigidBodies ? this.rigidBodies.length : 0;
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
SEA3D.AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.Domain.prototype.applyContainerTransform = function () {
|
||||
|
||||
this.container.updateMatrix();
|
||||
|
||||
var matrix = this.container.matrix.clone();
|
||||
|
||||
this.container.position.set( 0, 0, 0 );
|
||||
this.container.rotation.set( 0, 0, 0 );
|
||||
this.container.scale.set( 1, 1, 1 );
|
||||
|
||||
this.applyTransform( matrix );
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
|
||||
|
||||
var mtx = THREE.SEA3D.MTXBUF, vec = THREE.SEA3D.VECBUF;
|
||||
|
||||
var i = this.rigidBodies ? this.rigidBodies.length : 0,
|
||||
childs = this.container ? this.container.children : [],
|
||||
targets = [];
|
||||
|
||||
while ( i -- ) {
|
||||
|
||||
var rb = this.rigidBodies[ i ],
|
||||
target = SEA3D.AMMO.getTargetByRigidBody( rb ),
|
||||
transform = rb.getWorldTransform(),
|
||||
transformMatrix = SEA3D.AMMO.getMatrixFromTransform( transform );
|
||||
|
||||
transformMatrix.multiplyMatrices( transformMatrix, matrix );
|
||||
|
||||
transform = SEA3D.AMMO.getTransformFromMatrix( transformMatrix );
|
||||
|
||||
rb.setWorldTransform( transform );
|
||||
|
||||
if ( target ) targets.push( target );
|
||||
|
||||
}
|
||||
|
||||
for ( i = 0; i < childs.length; i ++ ) {
|
||||
|
||||
var obj3d = childs[ i ];
|
||||
|
||||
if ( targets.indexOf( obj3d ) > - 1 ) continue;
|
||||
|
||||
obj3d.updateMatrix();
|
||||
|
||||
mtx.copy( obj3d.matrix );
|
||||
|
||||
mtx.multiplyMatrices( matrix, mtx );
|
||||
|
||||
obj3d.position.setFromMatrixPosition( mtx );
|
||||
obj3d.scale.setFromMatrixScale( mtx );
|
||||
|
||||
// ignore rotation scale
|
||||
|
||||
mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
|
||||
obj3d.rotation.setFromRotationMatrix( mtx );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Extension
|
||||
//
|
||||
|
||||
THREE.SEA3D.Domain.prototype.getShape = THREE.SEA3D.prototype.getShape = function ( name ) {
|
||||
|
||||
return this.objects[ "shpe/" + name ];
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.Domain.prototype.getRigidBody = THREE.SEA3D.prototype.getRigidBody = function ( name ) {
|
||||
|
||||
return this.objects[ "rb/" + name ];
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.Domain.prototype.getConstraint = THREE.SEA3D.prototype.getConstraint = function ( name ) {
|
||||
|
||||
return this.objects[ "ctnt/" + name ];
|
||||
|
||||
};
|
||||
|
||||
THREE.SEA3D.EXTENSIONS_LOADER.push( {
|
||||
|
||||
parse: function () {
|
||||
|
||||
delete this.shapes;
|
||||
delete this.rigidBodies;
|
||||
delete this.vehicles;
|
||||
delete this.constraints;
|
||||
|
||||
},
|
||||
|
||||
setTypeRead: function () {
|
||||
|
||||
// CONFIG
|
||||
|
||||
this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
|
||||
this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
|
||||
this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
|
||||
|
||||
if ( this.config.physics ) {
|
||||
|
||||
// SHAPES
|
||||
|
||||
this.file.typeRead[ SEA3D.Sphere.prototype.type ] = this.readSphere;
|
||||
this.file.typeRead[ SEA3D.Box.prototype.type ] = this.readBox;
|
||||
this.file.typeRead[ SEA3D.Capsule.prototype.type ] = this.readCapsule;
|
||||
this.file.typeRead[ SEA3D.Cone.prototype.type ] = this.readCone;
|
||||
this.file.typeRead[ SEA3D.Cylinder.prototype.type ] = this.readCylinder;
|
||||
this.file.typeRead[ SEA3D.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
|
||||
this.file.typeRead[ SEA3D.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
|
||||
this.file.typeRead[ SEA3D.Compound.prototype.type ] = this.readCompound;
|
||||
|
||||
// CONSTRAINTS
|
||||
|
||||
this.file.typeRead[ SEA3D.P2PConstraint.prototype.type ] = this.readP2PConstraint;
|
||||
this.file.typeRead[ SEA3D.HingeConstraint.prototype.type ] = this.readHingeConstraint;
|
||||
this.file.typeRead[ SEA3D.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
|
||||
|
||||
// PHYSICS
|
||||
|
||||
this.file.typeRead[ SEA3D.RigidBody.prototype.type ] = this.readRigidBody;
|
||||
this.file.typeRead[ SEA3D.CarController.prototype.type ] = this.readCarController;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
THREE.SEA3D.EXTENSIONS_DOMAIN.push( {
|
||||
|
||||
dispose: function () {
|
||||
|
||||
var i;
|
||||
|
||||
i = this.rigidBodies ? this.rigidBodies.length : 0;
|
||||
while ( i -- ) SEA3D.AMMO.removeRigidBody( this.rigidBodies[ i ], true );
|
||||
|
||||
i = this.vehicles ? this.vehicles.length : 0;
|
||||
while ( i -- ) SEA3D.AMMO.removeVehicle( this.vehicles[ i ], true );
|
||||
|
||||
i = this.constraints ? this.constraints.length : 0;
|
||||
while ( i -- ) SEA3D.AMMO.removeConstraint( this.constraints[ i ], true );
|
||||
|
||||
i = this.shapes ? this.shapes.length : 0;
|
||||
while ( i -- ) Ammo.destroy( this.shapes[ i ] );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
442
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DRigidBody.js
generated
vendored
Normal file
442
node_modules/three/examples/js/loaders/sea3d/physics/SEA3DRigidBody.js
generated
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
* SEA3D - Rigid Body
|
||||
* @author Sunag / http://www.sunag.com.br/
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Sphere
|
||||
//
|
||||
|
||||
SEA3D.Sphere = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.radius = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Sphere.prototype.type = "sph";
|
||||
|
||||
//
|
||||
// Box
|
||||
//
|
||||
|
||||
SEA3D.Box = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.width = data.readFloat();
|
||||
this.height = data.readFloat();
|
||||
this.depth = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Box.prototype.type = "box";
|
||||
|
||||
//
|
||||
// Cone
|
||||
//
|
||||
|
||||
SEA3D.Cone = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.radius = data.readFloat();
|
||||
this.height = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Cone.prototype.type = "cone";
|
||||
|
||||
//
|
||||
// Capsule
|
||||
//
|
||||
|
||||
SEA3D.Capsule = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.radius = data.readFloat();
|
||||
this.height = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Capsule.prototype.type = "cap";
|
||||
|
||||
//
|
||||
// Cylinder
|
||||
//
|
||||
|
||||
SEA3D.Cylinder = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.radius = data.readFloat();
|
||||
this.height = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Cylinder.prototype.type = "cyl";
|
||||
|
||||
//
|
||||
// Convex Geometry
|
||||
//
|
||||
|
||||
SEA3D.ConvexGeometry = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.geometry = sea3d.getObject( data.readUInt() );
|
||||
this.subGeometryIndex = data.readUByte();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.ConvexGeometry.prototype.type = "gs";
|
||||
|
||||
//
|
||||
// Triangle Geometry
|
||||
//
|
||||
|
||||
SEA3D.TriangleGeometry = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.geometry = sea3d.getObject( data.readUInt() );
|
||||
this.subGeometryIndex = data.readUByte();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.TriangleGeometry.prototype.type = "sgs";
|
||||
|
||||
//
|
||||
// Compound
|
||||
//
|
||||
|
||||
SEA3D.Compound = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.compounds = [];
|
||||
|
||||
var count = data.readUByte();
|
||||
|
||||
for ( var i = 0; i < count; i ++ ) {
|
||||
|
||||
this.compounds.push( {
|
||||
shape: sea3d.getObject( data.readUInt() ),
|
||||
transform: data.readMatrix()
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Compound.prototype.type = "cmps";
|
||||
|
||||
//
|
||||
// Physics
|
||||
//
|
||||
|
||||
SEA3D.Physics = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.attrib = data.readUShort();
|
||||
|
||||
this.shape = sea3d.getObject( data.readUInt() );
|
||||
|
||||
if ( this.attrib & 1 ) this.target = sea3d.getObject( data.readUInt() );
|
||||
else this.transform = data.readMatrix();
|
||||
|
||||
if ( this.attrib & 2 ) this.offset = data.readMatrix();
|
||||
|
||||
if ( this.attrib & 4 ) this.scripts = data.readScriptList( sea3d );
|
||||
|
||||
if ( this.attrib & 16 ) this.attributes = sea3d.getObject( data.readUInt() );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.Physics.prototype.readTag = function ( kind, data, size ) {
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Rigidy Body Base
|
||||
//
|
||||
|
||||
SEA3D.RigidBodyBase = function ( name, data, sea3d ) {
|
||||
|
||||
SEA3D.Physics.call( this, name, data, sea3d );
|
||||
|
||||
if ( this.attrib & 32 ) {
|
||||
|
||||
this.linearDamping = data.readFloat();
|
||||
this.angularDamping = data.readFloat();
|
||||
|
||||
} else {
|
||||
|
||||
this.linearDamping = 0;
|
||||
this.angularDamping = 0;
|
||||
|
||||
}
|
||||
|
||||
this.mass = data.readFloat();
|
||||
this.friction = data.readFloat();
|
||||
this.restitution = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.RigidBodyBase.prototype = Object.create( SEA3D.Physics.prototype );
|
||||
SEA3D.RigidBodyBase.prototype.constructor = SEA3D.RigidBodyBase;
|
||||
|
||||
//
|
||||
// Rigidy Body
|
||||
//
|
||||
|
||||
SEA3D.RigidBody = function ( name, data, sea3d ) {
|
||||
|
||||
SEA3D.RigidBodyBase.call( this, name, data, sea3d );
|
||||
|
||||
data.readTags( this.readTag.bind( this ) );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.RigidBody.prototype = Object.create( SEA3D.RigidBodyBase.prototype );
|
||||
SEA3D.RigidBody.prototype.constructor = SEA3D.RigidBody;
|
||||
|
||||
SEA3D.RigidBody.prototype.type = "rb";
|
||||
|
||||
//
|
||||
// Car Controller
|
||||
//
|
||||
|
||||
SEA3D.CarController = function ( name, data, sea3d ) {
|
||||
|
||||
SEA3D.RigidBodyBase.call( this, name, data, sea3d );
|
||||
|
||||
this.suspensionStiffness = data.readFloat();
|
||||
this.suspensionCompression = data.readFloat();
|
||||
this.suspensionDamping = data.readFloat();
|
||||
this.maxSuspensionTravelCm = data.readFloat();
|
||||
this.frictionSlip = data.readFloat();
|
||||
this.maxSuspensionForce = data.readFloat();
|
||||
|
||||
this.dampingCompression = data.readFloat();
|
||||
this.dampingRelaxation = data.readFloat();
|
||||
|
||||
var count = data.readUByte();
|
||||
|
||||
this.wheel = [];
|
||||
|
||||
for ( var i = 0; i < count; i ++ ) {
|
||||
|
||||
this.wheel[ i ] = new SEA3D.CarController.Wheel( data, sea3d );
|
||||
|
||||
}
|
||||
|
||||
data.readTags( this.readTag.bind( this ) );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.CarController.Wheel = function ( data, sea3d ) {
|
||||
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.attrib = data.readUShort();
|
||||
|
||||
this.isFront = ( this.attrib & 1 ) != 0;
|
||||
|
||||
if ( this.attrib & 2 ) {
|
||||
|
||||
this.target = sea3d.getObject( data.readUInt() );
|
||||
|
||||
}
|
||||
|
||||
if ( this.attrib & 4 ) {
|
||||
|
||||
this.offset = data.readMatrix();
|
||||
|
||||
}
|
||||
|
||||
this.pos = data.readVector3();
|
||||
this.dir = data.readVector3();
|
||||
this.axle = data.readVector3();
|
||||
|
||||
this.radius = data.readFloat();
|
||||
this.suspensionRestLength = data.readFloat();
|
||||
|
||||
};
|
||||
|
||||
SEA3D.CarController.prototype = Object.create( SEA3D.RigidBodyBase.prototype );
|
||||
SEA3D.CarController.prototype.constructor = SEA3D.CarController;
|
||||
|
||||
SEA3D.CarController.prototype.type = "carc";
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
|
||||
SEA3D.Constraints = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
this.attrib = data.readUShort();
|
||||
|
||||
this.disableCollisionsBetweenBodies = this.attrib & 1 != 0;
|
||||
|
||||
this.targetA = sea3d.getObject( data.readUInt() );
|
||||
this.pointA = data.readVector3();
|
||||
|
||||
if ( this.attrib & 2 ) {
|
||||
|
||||
this.targetB = sea3d.getObject( data.readUInt() );
|
||||
this.pointB = data.readVector3();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// P2P Constraint
|
||||
//
|
||||
|
||||
SEA3D.P2PConstraint = function ( name, data, sea3d ) {
|
||||
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.sea3d = sea3d;
|
||||
|
||||
SEA3D.Constraints.call( this, name, data, sea3d );
|
||||
|
||||
};
|
||||
|
||||
SEA3D.P2PConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
|
||||
SEA3D.P2PConstraint.prototype.constructor = SEA3D.P2PConstraint;
|
||||
|
||||
SEA3D.P2PConstraint.prototype.type = "p2pc";
|
||||
|
||||
//
|
||||
// Hinge Constraint
|
||||
//
|
||||
|
||||
SEA3D.HingeConstraint = function ( name, data, sea3d ) {
|
||||
|
||||
SEA3D.Constraints.call( this, name, data, sea3d );
|
||||
|
||||
this.axisA = data.readVector3();
|
||||
|
||||
if ( this.attrib & 1 ) {
|
||||
|
||||
this.axisB = data.readVector3();
|
||||
|
||||
}
|
||||
|
||||
if ( this.attrib & 4 ) {
|
||||
|
||||
this.limit = {
|
||||
low: data.readFloat(),
|
||||
high: data.readFloat(),
|
||||
softness: data.readFloat(),
|
||||
biasFactor: data.readFloat(),
|
||||
relaxationFactor: data.readFloat()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
if ( this.attrib & 8 ) {
|
||||
|
||||
this.angularMotor = {
|
||||
velocity: data.readFloat(),
|
||||
impulse: data.readFloat()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SEA3D.HingeConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
|
||||
SEA3D.HingeConstraint.prototype.constructor = SEA3D.HingeConstraint;
|
||||
|
||||
SEA3D.HingeConstraint.prototype.type = "hnec";
|
||||
|
||||
//
|
||||
// Cone Twist Constraint
|
||||
//
|
||||
|
||||
SEA3D.ConeTwistConstraint = function ( name, data, sea3d ) {
|
||||
|
||||
SEA3D.Constraints.call( this, name, data, sea3d );
|
||||
|
||||
this.axisA = data.readVector3();
|
||||
|
||||
if ( this.attrib & 1 ) {
|
||||
|
||||
this.axisB = data.readVector3();
|
||||
|
||||
}
|
||||
|
||||
if ( this.attrib & 4 ) {
|
||||
|
||||
this.limit = {
|
||||
swingSpan1: data.readFloat(),
|
||||
swingSpan2: data.readFloat(),
|
||||
twistSpan: data.readFloat(),
|
||||
softness: data.readFloat(),
|
||||
biasFactor: data.readFloat(),
|
||||
relaxationFactor: data.readFloat()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SEA3D.ConeTwistConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
|
||||
SEA3D.ConeTwistConstraint.prototype.constructor = SEA3D.ConeTwistConstraint;
|
||||
|
||||
SEA3D.ConeTwistConstraint.prototype.type = "ctwc";
|
||||
|
||||
//
|
||||
// Extension
|
||||
//
|
||||
|
||||
SEA3D.File.setExtension( function () {
|
||||
|
||||
// PHYSICS
|
||||
this.addClass( SEA3D.Sphere );
|
||||
this.addClass( SEA3D.Box );
|
||||
this.addClass( SEA3D.Cone );
|
||||
this.addClass( SEA3D.Capsule );
|
||||
this.addClass( SEA3D.Cylinder );
|
||||
this.addClass( SEA3D.ConvexGeometry );
|
||||
this.addClass( SEA3D.TriangleGeometry );
|
||||
this.addClass( SEA3D.Compound );
|
||||
this.addClass( SEA3D.RigidBody );
|
||||
this.addClass( SEA3D.P2PConstraint );
|
||||
this.addClass( SEA3D.HingeConstraint );
|
||||
this.addClass( SEA3D.ConeTwistConstraint );
|
||||
this.addClass( SEA3D.CarController );
|
||||
|
||||
} );
|
||||
Reference in New Issue
Block a user