提交 e4dc8cfe 编写于 作者: M Mr.doob

GeometryLoader working (ex JSONLoader)

Tried to make it as straight foward as possible. Kept the extrac base url thingie :)
Thinking of moving BinaryLoader to examples/js/loaders.... what do you think @alteredq?
上级 8bbd61b1
......@@ -41,7 +41,7 @@
var container, stats;
var camera, scene, renderer;
var mesh;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
......@@ -60,6 +60,9 @@
camera.position.z = 500;
scene.add( camera );
group = new THREE.Object3D();
scene.add( group );
// earth
var earthTexture = new THREE.Texture();
......@@ -77,8 +80,8 @@
var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var material = new THREE.MeshBasicMaterial( { map: earthTexture, overdraw: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
// shadow
......@@ -97,9 +100,9 @@
var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: shadowTexture, overdraw: true } );
mesh = new THREE.Mesh( geometry, material );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
scene.add( mesh );
group.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
......@@ -139,7 +142,7 @@
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
mesh.rotation.y -= 0.005;
group.rotation.y -= 0.005;
renderer.render( scene, camera );
......
......@@ -34,6 +34,8 @@
<script src="../build/Three.js"></script>
<script src="../src/loaders/GeometryLoader.js"></script>
<script src="js/loaders/ColladaLoader.js"></script>
<script src="js/Detector.js"></script>
......@@ -85,8 +87,10 @@
// Add Blender exported Collada model
var loader = new THREE.JSONLoader();
loader.load( "models/animated/monster/monster.js", function ( geometry ) {
var loader = new THREE.GeometryLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
// adjust color a bit
......@@ -134,6 +138,7 @@
}
} );
loader.load( 'models/animated/monster/monster.js' );
// Add the COLLADA
......
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/
THREE.GeometryLoader = function () {
THREE.EventTarget.call( this );
};
THREE.GeometryLoader.prototype = {
constructor: THREE.GeometryLoader,
crossOrigin: null,
path: null,
load: function ( url ) {
var scope = this;
if ( scope.path === null ) {
var parts = url.split( '/' ); parts.pop();
scope.path = ( parts.length < 1 ? '.' : parts.join( '/' ) );
}
var xhr = new XMLHttpRequest();
xhr.addEventListener( 'load', function ( event ) {
if ( event.target.responseText ) {
scope.dispatchEvent( { type: 'load', content: scope.parse( JSON.parse( event.target.responseText ) ) } );
} else {
scope.dispatchEvent( { type: 'error', message: 'URL unreachable or empty file [' + url + ']' } );
}
}, false );
xhr.addEventListener( 'progress', function ( event ) {
scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
}, false );
xhr.addEventListener( 'error', function () {
scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
}, false );
xhr.open( 'GET', url, true );
xhr.send( null );
},
parse: function ( data ) {
var scope = this;
var geometry = new THREE.Geometry();
var scale = ( data.scale !== undefined ) ? 1 / data.scale : 1;
// materials
geometry.materials = [];
for ( var i = 0; i < data.materials.length; ++ i ) {
var m = data.materials[ i ];
function isPow2( n ) {
var l = Math.log( n ) / Math.LN2;
return Math.floor( l ) == l;
}
function nearestPow2( n ) {
var l = Math.log( n ) / Math.LN2;
return Math.pow( 2, Math.round( l ) );
}
function createTexture( where, name, sourceFile, repeat, offset, wrap ) {
where[ name ] = new THREE.Texture();
where[ name ].sourceFile = sourceFile;
if ( repeat ) {
where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
if ( repeat[ 0 ] != 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
if ( repeat[ 1 ] != 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
}
if ( offset ) {
where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
}
if ( wrap ) {
var wrapMap = {
"repeat": THREE.RepeatWrapping,
"mirror": THREE.MirroredRepeatWrapping
}
if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
}
// load image
var texture = where[ name ];
var loader = new THREE.ImageLoader();
loader.addEventListener( 'load', function ( event ) {
var image = event.content;
if ( !isPow2( image.width ) || !isPow2( image.height ) ) {
var width = nearestPow2( image.width );
var height = nearestPow2( image.height );
texture.image = document.createElement( 'canvas' );
texture.image.width = width;
texture.image.height = height;
texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
} else {
texture.image = image;
}
texture.needsUpdate = true;
} );
loader.crossOrigin = scope.crossOrigin;
loader.load( scope.path + '/' + sourceFile );
}
function rgb2hex( rgb ) {
return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
}
// defaults
var mtype = "MeshLambertMaterial";
var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, wireframe: m.wireframe };
// parameters from model file
if ( m.shading ) {
var shading = m.shading.toLowerCase();
if ( shading === "phong" ) mtype = "MeshPhongMaterial";
else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
}
if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
mpars.blending = THREE[ m.blending ];
}
if ( m.transparent !== undefined || m.opacity < 1.0 ) {
mpars.transparent = m.transparent;
}
if ( m.depthTest !== undefined ) {
mpars.depthTest = m.depthTest;
}
if ( m.depthWrite !== undefined ) {
mpars.depthWrite = m.depthWrite;
}
if ( m.vertexColors !== undefined ) {
if ( m.vertexColors == "face" ) {
mpars.vertexColors = THREE.FaceColors;
} else if ( m.vertexColors ) {
mpars.vertexColors = THREE.VertexColors;
}
}
// colors
if ( m.colorDiffuse ) {
mpars.color = rgb2hex( m.colorDiffuse );
} else if ( m.DbgColor ) {
mpars.color = m.DbgColor;
}
if ( m.colorSpecular ) {
mpars.specular = rgb2hex( m.colorSpecular );
}
if ( m.colorAmbient ) {
mpars.ambient = rgb2hex( m.colorAmbient );
}
// modifiers
if ( m.transparency ) {
mpars.opacity = m.transparency;
}
if ( m.specularCoef ) {
mpars.shininess = m.specularCoef;
}
// textures
if ( m.mapDiffuse ) {
createTexture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap );
}
if ( m.mapLight ) {
createTexture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap );
}
if ( m.mapNormal ) {
createTexture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap );
}
if ( m.mapSpecular ) {
createTexture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap );
}
// special case for normal mapped material
if ( m.mapNormal ) {
var shader = THREE.ShaderUtils.lib[ "normal" ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms[ "tNormal" ].texture = mpars.normalMap;
if ( m.mapNormalFactor ) {
uniforms[ "uNormalScale" ].value = m.mapNormalFactor;
}
if ( mpars.map ) {
uniforms[ "tDiffuse" ].texture = mpars.map;
uniforms[ "enableDiffuse" ].value = true;
}
if ( mpars.specularMap ) {
uniforms[ "tSpecular" ].texture = mpars.specularMap;
uniforms[ "enableSpecular" ].value = true;
}
if ( mpars.lightMap ) {
uniforms[ "tAO" ].texture = mpars.lightMap;
uniforms[ "enableAO" ].value = true;
}
// for the moment don't handle displacement texture
uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
uniforms[ "uShininess" ].value = mpars.shininess;
if ( mpars.opacity !== undefined ) {
uniforms[ "uOpacity" ].value = mpars.opacity;
}
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
var material = new THREE.ShaderMaterial( parameters );
} else {
var material = new THREE[ mtype ]( mpars );
}
if ( m.DbgName !== undefined ) material.name = m.DbgName;
geometry.materials[ i ] = material;
}
// geometry
function isBitSet( value, position ) {
return value & ( 1 << position );
}
var faces = data.faces;
var vertices = data.vertices;
var normals = data.normals;
var colors = data.colors;
var nUvLayers = 0;
// disregard empty arrays
for ( var i = 0; i < data.uvs.length; i ++ ) {
if ( data.uvs[ i ].length ) nUvLayers ++;
}
for ( var i = 0; i < nUvLayers; i ++ ) {
geometry.faceUvs[ i ] = [];
geometry.faceVertexUvs[ i ] = [];
}
var offset = 0;
var zLength = vertices.length;
while ( offset < zLength ) {
var vertex = new THREE.Vector3();
vertex.x = vertices[ offset ++ ] * scale;
vertex.y = vertices[ offset ++ ] * scale;
vertex.z = vertices[ offset ++ ] * scale;
geometry.vertices.push( vertex );
}
offset = 0;
zLength = faces.length;
while ( offset < zLength ) {
var type = faces[ offset ++ ];
var isQuad = isBitSet( type, 0 );
var hasMaterial = isBitSet( type, 1 );
var hasFaceUv = isBitSet( type, 2 );
var hasFaceVertexUv = isBitSet( type, 3 );
var hasFaceNormal = isBitSet( type, 4 );
var hasFaceVertexNormal = isBitSet( type, 5 );
var hasFaceColor = isBitSet( type, 6 );
var hasFaceVertexColor = isBitSet( type, 7 );
// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
if ( isQuad ) {
var face = new THREE.Face4();
face.a = faces[ offset ++ ];
face.b = faces[ offset ++ ];
face.c = faces[ offset ++ ];
face.d = faces[ offset ++ ];
var nVertices = 4;
} else {
var face = new THREE.Face3();
face.a = faces[ offset ++ ];
face.b = faces[ offset ++ ];
face.c = faces[ offset ++ ];
var nVertices = 3;
}
if ( hasMaterial ) {
var materialIndex = faces[ offset ++ ];
face.materialIndex = materialIndex;
}
// to get face <=> uv index correspondence
var fi = geometry.faces.length;
if ( hasFaceUv ) {
for ( var i = 0; i < nUvLayers; i ++ ) {
var uvLayer = data.uvs[ i ];
var uvIndex = faces[ offset ++ ];
var u = uvLayer[ uvIndex * 2 ];
var v = uvLayer[ uvIndex * 2 + 1 ];
geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
}
}
if ( hasFaceVertexUv ) {
for ( var i = 0; i < nUvLayers; i ++ ) {
var uvLayer = data.uvs[ i ];
var uvs = [];
for ( var j = 0; j < nVertices; j ++ ) {
var uvIndex = faces[ offset ++ ];
var u = uvLayer[ uvIndex * 2 ];
var v = uvLayer[ uvIndex * 2 + 1 ];
uvs[ j ] = new THREE.UV( u, v );
}
geometry.faceVertexUvs[ i ][ fi ] = uvs;
}
}
if ( hasFaceNormal ) {
var normalIndex = faces[ offset ++ ] * 3;
var normal = new THREE.Vector3();
normal.x = normals[ normalIndex ++ ];
normal.y = normals[ normalIndex ++ ];
normal.z = normals[ normalIndex ];
face.normal = normal;
}
if ( hasFaceVertexNormal ) {
for ( i = 0; i < nVertices; i ++ ) {
var normalIndex = faces[ offset ++ ] * 3;
var normal = new THREE.Vector3();
normal.x = normals[ normalIndex ++ ];
normal.y = normals[ normalIndex ++ ];
normal.z = normals[ normalIndex ];
face.vertexNormals.push( normal );
}
}
if ( hasFaceColor ) {
var colorIndex = faces[ offset ++ ];
face.color = new THREE.Color( colors[ colorIndex ] );
}
if ( hasFaceVertexColor ) {
for ( var i = 0; i < nVertices; i ++ ) {
var colorIndex = faces[ offset ++ ];
face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
}
}
geometry.faces.push( face );
}
// skin
if ( data.skinWeights ) {
for ( var i = 0, l = data.skinWeights.length; i < l; i += 2 ) {
var x = data.skinWeights[ i ];
var y = data.skinWeights[ i + 1 ];
var z = 0;
var w = 0;
geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
}
}
if ( data.skinIndices ) {
for ( var i = 0, l = data.skinIndices.length; i < l; i += 2 ) {
var a = data.skinIndices[ i ];
var b = data.skinIndices[ i + 1 ];
var c = 0;
var d = 0;
geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
}
}
geometry.bones = data.bones;
geometry.animation = data.animation;
// morphing
if ( data.morphTargets !== undefined ) {
for ( var i = 0, l = data.morphTargets.length; i < l; i ++ ) {
geometry.morphTargets[ i ] = {};
geometry.morphTargets[ i ].name = data.morphTargets[ i ].name;
geometry.morphTargets[ i ].vertices = [];
var dstVertices = geometry.morphTargets[ i ].vertices;
var srcVertices = data.morphTargets [ i ].vertices;
for( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
var vertex = new THREE.Vector3();
vertex.x = srcVertices[ v ] * scale;
vertex.y = srcVertices[ v + 1 ] * scale;
vertex.z = srcVertices[ v + 2 ] * scale;
dstVertices.push( vertex );
}
}
}
if ( data.morphColors !== undefined ) {
for ( var i = 0, l = data.morphColors.length; i < l; i++ ) {
geometry.morphColors[ i ] = {};
geometry.morphColors[ i ].name = data.morphColors[ i ].name;
geometry.morphColors[ i ].colors = [];
var dstColors = geometry.morphColors[ i ].colors;
var srcColors = data.morphColors [ i ].colors;
for ( var c = 0, cl = srcColors.length; c < cl; c += 3 ) {
var color = new THREE.Color( 0xffaa00 );
color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
dstColors.push( color );
}
}
}
geometry.computeCentroids();
geometry.computeFaceNormals();
return geometry;
}
};
......@@ -12,7 +12,7 @@ THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader,
crossOrigin: 'anonymous',
crossOrigin: null,
load: function ( url ) {
......@@ -31,7 +31,7 @@ THREE.ImageLoader.prototype = {
}, false );
image.crossOrigin = this.crossOrigin;
if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
image.src = url;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册