提交 6db8a5dd 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #10536 from takahirox/UpdateGLTFLoader

Update gltf loader
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* @author Rich Tibbett / https://github.com/richtr * @author Rich Tibbett / https://github.com/richtr
* @author mrdoob / http://mrdoob.com/ * @author mrdoob / http://mrdoob.com/
* @author Tony Parisi / http://www.tonyparisi.com/ * @author Tony Parisi / http://www.tonyparisi.com/
* @author Takahiro / https://github.com/takahirox
*/ */
THREE.GLTFLoader = ( function () { THREE.GLTFLoader = ( function () {
...@@ -315,6 +316,48 @@ THREE.GLTFLoader = ( function () { ...@@ -315,6 +316,48 @@ THREE.GLTFLoader = ( function () {
10497: THREE.RepeatWrapping 10497: THREE.RepeatWrapping
}; };
var WEBGL_SIDES = {
1028: THREE.BackSide, // Culling front
1029: THREE.FrontSide // Culling back
//1032: THREE.NoSide // Culling front and back, what to do?
};
var WEBGL_DEPTH_FUNCS = {
512: THREE.NeverDepth,
513: THREE.LessDepth,
514: THREE.EqualDepth,
515: THREE.LessEqualDepth,
516: THREE.GreaterEqualDepth,
517: THREE.NotEqualDepth,
518: THREE.GreaterEqualDepth,
519: THREE.AlwaysDepth
};
var WEBGL_BLEND_EQUATIONS = {
32774: THREE.AddEquation,
32778: THREE.SubtractEquation,
32779: THREE.ReverseSubtractEquation
};
var WEBGL_BLEND_FUNCS = {
0: THREE.ZeroFactor,
1: THREE.OneFactor,
768: THREE.SrcColorFactor,
769: THREE.OneMinusSrcColorFactor,
770: THREE.SrcAlphaFactor,
771: THREE.OneMinusSrcAlphaFactor,
772: THREE.DstAlphaFactor,
773: THREE.OneMinusDstAlphaFactor,
774: THREE.DstColorFactor,
775: THREE.OneMinusDstColorFactor,
776: THREE.SrcAlphaSaturateFactor
// The followings are not supported by Three.js yet
//32769: CONSTANT_COLOR,
//32770: ONE_MINUS_CONSTANT_COLOR,
//32771: CONSTANT_ALPHA,
//32772: ONE_MINUS_CONSTANT_COLOR
};
var WEBGL_TYPE_SIZES = { var WEBGL_TYPE_SIZES = {
'SCALAR': 1, 'SCALAR': 1,
'VEC2': 2, 'VEC2': 2,
...@@ -336,6 +379,15 @@ THREE.GLTFLoader = ( function () { ...@@ -336,6 +379,15 @@ THREE.GLTFLoader = ( function () {
STEP: THREE.InterpolateDiscrete STEP: THREE.InterpolateDiscrete
}; };
var STATES_ENABLES = {
2884: 'CULL_FACE',
2929: 'DEPTH_TEST',
3042: 'BLEND',
3089: 'SCISSOR_TEST',
32823: 'POLYGON_OFFSET_FILL',
32926: 'SAMPLE_ALPHA_TO_COVERAGE'
};
/* UTILITY FUNCTIONS */ /* UTILITY FUNCTIONS */
function _each( object, callback, thisObj ) { function _each( object, callback, thisObj ) {
...@@ -504,6 +556,20 @@ THREE.GLTFLoader = ( function () { ...@@ -504,6 +556,20 @@ THREE.GLTFLoader = ( function () {
} }
function createDefaultMaterial() {
return new THREE.MeshPhongMaterial( {
color: 0x00000,
emissive: 0x888888,
specular: 0x000000,
shininess: 0,
transparent: false,
depthTest: true,
side: THREE.FrontSide
} );
};
// Deferred constructor for RawShaderMaterial types // Deferred constructor for RawShaderMaterial types
function DeferredShaderMaterial( params ) { function DeferredShaderMaterial( params ) {
...@@ -644,7 +710,7 @@ THREE.GLTFLoader = ( function () { ...@@ -644,7 +710,7 @@ THREE.GLTFLoader = ( function () {
return new Promise( function ( resolve ) { return new Promise( function ( resolve ) {
var loader = new THREE.FileLoader(); var loader = new THREE.FileLoader();
loader.responseType = 'text'; loader.setResponseType( 'text' );
loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) { loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) {
resolve( shaderText ); resolve( shaderText );
...@@ -664,12 +730,12 @@ THREE.GLTFLoader = ( function () { ...@@ -664,12 +730,12 @@ THREE.GLTFLoader = ( function () {
return _each( json.buffers, function ( buffer ) { return _each( json.buffers, function ( buffer ) {
if ( buffer.type === 'arraybuffer' ) { if ( buffer.type === 'arraybuffer' || buffer.type === undefined ) {
return new Promise( function ( resolve ) { return new Promise( function ( resolve ) {
var loader = new THREE.FileLoader(); var loader = new THREE.FileLoader();
loader.responseType = 'arraybuffer'; loader.setResponseType( 'arraybuffer' );
loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) { loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) {
resolve( buffer ); resolve( buffer );
...@@ -678,6 +744,10 @@ THREE.GLTFLoader = ( function () { ...@@ -678,6 +744,10 @@ THREE.GLTFLoader = ( function () {
} ); } );
} else {
console.warn( 'THREE.GLTFLoader: ' + buffer.type + ' buffer type is not supported' );
} }
} ); } );
...@@ -920,7 +990,9 @@ THREE.GLTFLoader = ( function () { ...@@ -920,7 +990,9 @@ THREE.GLTFLoader = ( function () {
if ( WEBGL_TYPE[ ptype ] ) { if ( WEBGL_TYPE[ ptype ] ) {
var pcount = shaderParam.count; var pcount = shaderParam.count;
var value = material.values[ pname ]; var value;
if ( material.values !== undefined ) value = material.values[ pname ];
var uvalue = new WEBGL_TYPE[ ptype ](); var uvalue = new WEBGL_TYPE[ ptype ]();
var usemantic = shaderParam.semantic; var usemantic = shaderParam.semantic;
...@@ -996,7 +1068,7 @@ THREE.GLTFLoader = ( function () { ...@@ -996,7 +1068,7 @@ THREE.GLTFLoader = ( function () {
} }
} else { } else {
if ( shaderParam && shaderParam.value ) { if ( shaderParam && shaderParam.value ) {
...@@ -1017,7 +1089,19 @@ THREE.GLTFLoader = ( function () { ...@@ -1017,7 +1089,19 @@ THREE.GLTFLoader = ( function () {
case WEBGL_CONSTANTS.SAMPLER_2D: case WEBGL_CONSTANTS.SAMPLER_2D:
uvalue = value ? dependencies.textures[ value ] : null; if ( value !== undefined ) {
uvalue = dependencies.textures[ value ];
} else if ( shaderParam.value !== undefined ) {
uvalue = dependencies.textures[ shaderParam.value ];
} else {
uvalue = null;
}
break; break;
...@@ -1037,6 +1121,102 @@ THREE.GLTFLoader = ( function () { ...@@ -1037,6 +1121,102 @@ THREE.GLTFLoader = ( function () {
} }
var states = technique.states || {};
var enables = states.enable || [];
var functions = states.functions || {};
var enableCullFace = false;
var enableDepthTest = false;
var enableBlend = false;
for ( var i = 0, il = enables.length; i < il; i ++ ) {
var enable = enables[ i ];
switch( STATES_ENABLES[ enable ] ) {
case 'CULL_FACE':
enableCullFace = true;
break;
case 'DEPTH_TEST':
enableDepthTest = true;
break;
case 'BLEND':
enableBlend = true;
break;
// TODO: implement
case 'SCISSOR_TEST':
case 'POLYGON_OFFSET_FILL':
case 'SAMPLE_ALPHA_TO_COVERAGE':
break;
default:
throw new Error( "Unknown technique.states.enable: " + enable );
}
}
if ( enableCullFace ) {
materialParams.side = functions.cullFace !== undefined ? WEBGL_SIDES[ functions.cullFace ] : THREE.FrontSide;
} else {
materialParams.side = THREE.DoubleSide;
}
materialParams.depthTest = enableDepthTest;
materialParams.depthFunc = functions.depthFunc !== undefined ? WEBGL_DEPTH_FUNCS[ functions.depthFunc ] : THREE.LessDepth;
materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[ 0 ] : true;
materialParams.blending = enableBlend ? THREE.CustomBlending : THREE.NoBlending;
materialParams.transparent = enableBlend;
var blendEquationSeparate = functions.blendEquationSeparate;
if ( blendEquationSeparate !== undefined ) {
materialParams.blendEquation = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 0 ] ];
materialParams.blendEquationAlpha = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 1 ] ];
} else {
materialParams.blendEquation = THREE.AddEquation;
materialParams.blendEquationAlpha = THREE.AddEquation;
}
var blendFuncSeparate = functions.blendFuncSeparate;
if ( blendFuncSeparate !== undefined ) {
materialParams.blendSrc = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 0 ] ];
materialParams.blendDst = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 1 ] ];
materialParams.blendSrcAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 2 ] ];
materialParams.blendDstAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 3 ] ];
} else {
materialParams.blendSrc = THREE.OneFactor;
materialParams.blendDst = THREE.ZeroFactor;
materialParams.blendSrcAlpha = THREE.OneFactor;
materialParams.blendDstAlpha = THREE.ZeroFactor;
}
} }
} }
...@@ -1108,7 +1288,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1108,7 +1288,7 @@ THREE.GLTFLoader = ( function () {
} }
var _material = new materialType( materialParams ); var _material = new materialType( materialParams );
_material.name = material.name; if ( material.name !== undefined ) _material.name = material.name;
return _material; return _material;
...@@ -1132,7 +1312,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1132,7 +1312,7 @@ THREE.GLTFLoader = ( function () {
return _each( json.meshes, function ( mesh ) { return _each( json.meshes, function ( mesh ) {
var group = new THREE.Object3D(); var group = new THREE.Object3D();
group.name = mesh.name; if ( mesh.name !== undefined ) group.name = mesh.name;
if ( mesh.extras ) group.userData = mesh.extras; if ( mesh.extras ) group.userData = mesh.extras;
...@@ -1190,7 +1370,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1190,7 +1370,7 @@ THREE.GLTFLoader = ( function () {
} }
var material = dependencies.materials[ primitive.material ]; var material = dependencies.materials !== undefined ? dependencies.materials[ primitive.material ] : createDefaultMaterial();
var meshNode = new THREE.Mesh( geometry, material ); var meshNode = new THREE.Mesh( geometry, material );
meshNode.castShadow = true; meshNode.castShadow = true;
...@@ -1282,7 +1462,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1282,7 +1462,7 @@ THREE.GLTFLoader = ( function () {
// yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov; // yfov = ( yfov === undefined && xfov ) ? xfov / aspect_ratio : yfov;
var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspect_ratio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 ); var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspect_ratio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 );
_camera.name = camera.name; if ( camera.name !== undefined ) _camera.name = camera.name;
if ( camera.extras ) _camera.userData = camera.extras; if ( camera.extras ) _camera.userData = camera.extras;
...@@ -1291,7 +1471,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1291,7 +1471,7 @@ THREE.GLTFLoader = ( function () {
} else if ( camera.type == "orthographic" && camera.orthographic ) { } else if ( camera.type == "orthographic" && camera.orthographic ) {
var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar ); var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar );
_camera.name = camera.name; if ( camera.name !== undefined ) _camera.name = camera.name;
if ( camera.extras ) _camera.userData = camera.extras; if ( camera.extras ) _camera.userData = camera.extras;
...@@ -1349,12 +1529,12 @@ THREE.GLTFLoader = ( function () { ...@@ -1349,12 +1529,12 @@ THREE.GLTFLoader = ( function () {
var channel = animation.channels[ channelId ]; var channel = animation.channels[ channelId ];
var sampler = animation.samplers[ channel.sampler ]; var sampler = animation.samplers[ channel.sampler ];
if ( sampler && animation.parameters ) { if ( sampler ) {
var target = channel.target; var target = channel.target;
var name = target.id; var name = target.id;
var input = animation.parameters[ sampler.input ]; var input = animation.parameters !== undefined ? animation.parameters[ sampler.input ] : sampler.input;
var output = animation.parameters[ sampler.output ]; var output = animation.parameters !== undefined ? animation.parameters[ sampler.output ] : sampler.output;
var inputAccessor = dependencies.accessors[ input ]; var inputAccessor = dependencies.accessors[ input ];
var outputAccessor = dependencies.accessors[ output ]; var outputAccessor = dependencies.accessors[ output ];
...@@ -1370,11 +1550,13 @@ THREE.GLTFLoader = ( function () { ...@@ -1370,11 +1550,13 @@ THREE.GLTFLoader = ( function () {
? THREE.QuaternionKeyframeTrack ? THREE.QuaternionKeyframeTrack
: THREE.VectorKeyframeTrack; : THREE.VectorKeyframeTrack;
var targetName = node.name ? node.name : node.uuid;
// KeyframeTrack.optimize() will modify given 'times' and 'values' // KeyframeTrack.optimize() will modify given 'times' and 'values'
// buffers before creating a truncated copy to keep. Because buffers may // buffers before creating a truncated copy to keep. Because buffers may
// be reused by other tracks, make copies here. // be reused by other tracks, make copies here.
tracks.push( new TypedKeyframeTrack( tracks.push( new TypedKeyframeTrack(
node.name + '.' + PATH_PROPERTIES[ target.path ], targetName + '.' + PATH_PROPERTIES[ target.path ],
THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
INTERPOLATION[ sampler.interpolation ] INTERPOLATION[ sampler.interpolation ]
...@@ -1408,20 +1590,18 @@ THREE.GLTFLoader = ( function () { ...@@ -1408,20 +1590,18 @@ THREE.GLTFLoader = ( function () {
if ( node.jointName ) { if ( node.jointName ) {
_node = new THREE.Bone(); _node = new THREE.Bone();
_node.name = node.name !== undefined ? node.name : node.jointName;
_node.jointName = node.jointName; _node.jointName = node.jointName;
} else { } else {
_node = new THREE.Object3D(); _node = new THREE.Object3D();
if ( node.name !== undefined ) _node.name = node.name;
} }
_node.name = node.name;
if ( node.extras ) _node.userData = node.extras; if ( node.extras ) _node.userData = node.extras;
_node.matrixAutoUpdate = false;
if ( node.matrix !== undefined ) { if ( node.matrix !== undefined ) {
matrix.fromArray( node.matrix ); matrix.fromArray( node.matrix );
...@@ -1531,6 +1711,22 @@ THREE.GLTFLoader = ( function () { ...@@ -1531,6 +1711,22 @@ THREE.GLTFLoader = ( function () {
// Replace Mesh with SkinnedMesh in library // Replace Mesh with SkinnedMesh in library
if ( skinEntry ) { if ( skinEntry ) {
var getJointNode = function ( jointId ) {
var keys = Object.keys( __nodes );
for ( var i = 0, il = keys.length; i < il; i ++ ) {
var n = __nodes[ keys[ i ] ];
if ( n.jointName === jointId ) return n;
}
return null;
}
var geometry = originalGeometry; var geometry = originalGeometry;
var material = originalMaterial; var material = originalMaterial;
material.skinning = true; material.skinning = true;
...@@ -1542,30 +1738,13 @@ THREE.GLTFLoader = ( function () { ...@@ -1542,30 +1738,13 @@ THREE.GLTFLoader = ( function () {
var bones = []; var bones = [];
var boneInverses = []; var boneInverses = [];
var keys = Object.keys( __nodes );
for ( var i = 0, l = skinEntry.jointNames.length; i < l; i ++ ) { for ( var i = 0, l = skinEntry.jointNames.length; i < l; i ++ ) {
var jointId = skinEntry.jointNames[ i ]; var jointId = skinEntry.jointNames[ i ];
var jointNode = getJointNode( jointId );
var jointNode;
for ( var j = 0, jl = keys.length; j < jl; j ++ ) {
var n = __nodes[ keys[ j ] ];
if ( n.jointName === jointId ) {
jointNode = n;
break;
}
}
if ( jointNode ) { if ( jointNode ) {
jointNode.skin = child;
bones.push( jointNode ); bones.push( jointNode );
var m = skinEntry.inverseBindMatrices.array; var m = skinEntry.inverseBindMatrices.array;
...@@ -1582,6 +1761,31 @@ THREE.GLTFLoader = ( function () { ...@@ -1582,6 +1761,31 @@ THREE.GLTFLoader = ( function () {
child.bind( new THREE.Skeleton( bones, boneInverses, false ), skinEntry.bindShapeMatrix ); child.bind( new THREE.Skeleton( bones, boneInverses, false ), skinEntry.bindShapeMatrix );
var buildBoneGraph = function ( parentJson, parentObject, property ) {
var children = parentJson[ property ];
if ( children === undefined ) return;
for ( var i = 0, il = children.length; i < il; i ++ ) {
var nodeId = children[ i ];
var bone = __nodes[ nodeId ];
var boneJson = json.nodes[ nodeId ];
if ( bone !== undefined && bone.isBone === true && boneJson !== undefined ) {
parentObject.add( bone );
buildBoneGraph( boneJson, bone, 'children' );
}
}
}
buildBoneGraph( node, child, 'skeletons' );
} }
_node.add( child ); _node.add( child );
...@@ -1653,7 +1857,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1653,7 +1857,7 @@ THREE.GLTFLoader = ( function () {
lightNode = new THREE.PointLight( color ); lightNode = new THREE.PointLight( color );
break; break;
case "spot ": case "spot":
lightNode = new THREE.SpotLight( color ); lightNode = new THREE.SpotLight( color );
lightNode.position.set( 0, 0, 1 ); lightNode.position.set( 0, 0, 1 );
break; break;
...@@ -1719,7 +1923,7 @@ THREE.GLTFLoader = ( function () { ...@@ -1719,7 +1923,7 @@ THREE.GLTFLoader = ( function () {
return _each( json.scenes, function ( scene ) { return _each( json.scenes, function ( scene ) {
var _scene = new THREE.Scene(); var _scene = new THREE.Scene();
_scene.name = scene.name; if ( scene.name !== undefined ) _scene.name = scene.name;
if ( scene.extras ) _scene.userData = scene.extras; if ( scene.extras ) _scene.userData = scene.extras;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册