提交 13dd7b09 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #10212 from Kyle-Larson/feature/FBX-Material-Import

FBX Material Import
/**
* @author yamahigashi https://github.com/yamahigashi
* @author Kyle-Larson https://github.com/Kyle-Larson
*
* This loader loads FBX file in *ASCII and version 7 format*.
*
......@@ -121,6 +122,7 @@
scope.weights = ( new Weights() ).parse( nodes, scope.hierarchy );
scope.animations = ( new Animation() ).parse( nodes, scope.hierarchy );
scope.textures = ( new Textures() ).parse( nodes, scope.hierarchy );
scope.materials = ( new Materials() ).parse( nodes, scope.hierarchy );
console.timeEnd( 'FBXLoader: ObjectParser' );
console.time( 'FBXLoader: GeometryParser' );
......@@ -237,7 +239,6 @@
geometry.computeBoundingSphere();
geometry.computeBoundingBox();
// TODO: texture & material support
var texture;
var texs = this.textures.getById( nodes.searchConnectionParent( geo.id ) );
if ( texs !== undefined && texs.length > 0 ) {
......@@ -251,15 +252,68 @@
}
var materials = [];
var material;
if ( texture !== undefined ) {
var mats = this.materials.getById( nodes.searchConnectionParent( geo.id ) );
if ( mats !== undefined && mats.length > 0) {
for(var i = 0; i < mats.length; ++i) {
var mat_data = mats[i];
var tmpMat;
// TODO:
// Cannot find a list of possible ShadingModel values.
// If someone finds a list, please add additional cases
// and map to appropriate materials.
switch(mat_data.type) {
case "phong":
tmpMat = new THREE.MeshPhongMaterial();
break;
case "Lambert":
tmpMat = new THREE.MeshLambertMaterial();
break;
default:
console.warn("No implementation given for material type " + mat_data.type + " in FBXLoader.js. Defaulting to basic material")
tmpMat = new THREE.MeshBasicMaterial({ color: 0x3300ff });
break;
}
if (texture !== undefined) {
mat_data.parameters.map = texture;
}
tmpMat.setValues(mat_data.parameters);
materials.push(tmpMat);
}
if(materials.length === 1) {
material = materials[0];
} else {
//Set up for multi-material
material = new THREE.MultiMaterial(materials);
var material_groupings = [];
var last_material_group = -1;
var material_index_list = toInt(node.subNodes.LayerElementMaterial.subNodes.Materials.properties.a.split( ',' ));
for(var i = 0; i < geo.polyIndices.length; ++i) {
if(last_material_group !== material_index_list[geo.polyIndices[i]]) {
material_groupings.push({start: i * 3, count: 0, materialIndex: material_index_list[geo.polyIndices[i]]});
last_material_group = material_index_list[geo.polyIndices[i]];
}
material_groupings[material_groupings.length - 1].count += 3;
}
geometry.groups = material_groupings;
}
material = new THREE.MeshBasicMaterial( { map: texture } );
} else {
//No material found for this geometry, create default
if (texture !== undefined) {
material = new THREE.MeshBasicMaterial({ map: texture });
} else {
material = new THREE.MeshBasicMaterial( { color: 0x3300ff } );
material = new THREE.MeshBasicMaterial({ color: 0x3300ff });
}
}
geometry = new THREE.Geometry().fromBufferGeometry( geometry );
......@@ -480,51 +534,6 @@
};
THREE.FBXLoader.prototype.parseMaterials = function ( node ) {
// has not mat, return []
if ( ! ( 'Material' in node.subNodes ) ) {
return [];
}
// has many
var matCount = 0;
for ( var mat in node.subNodes.Materials ) {
if ( mat.match( /^\d+$/ ) ) {
matCount ++;
}
}
var res = [];
if ( matCount > 0 ) {
for ( mat in node.subNodes.Material ) {
res.push( parseMaterial( node.subNodes.Material[ mat ] ) );
}
} else {
res.push( parseMaterial( node.subNodes.Material ) );
}
return res;
};
// TODO
THREE.FBXLoader.prototype.parseMaterial = function ( node ) {
};
THREE.FBXLoader.prototype.loadFile = function ( url, onLoad, onProgress, onError, responseType ) {
......@@ -1564,8 +1573,10 @@
if ( this.getPolygonTopologyMax() > 3 ) {
this.indices = this.convertPolyIndicesToTri(
var indexInfo = this.convertPolyIndicesToTri(
this.indices, this.getPolygonTopologyArray() );
this.indices = indexInfo.res;
this.polyIndices = indexInfo.polyIndices;
}
......@@ -1709,14 +1720,16 @@
//
// [( a, b, c, d ) ...........
// [( a, b, c ), (a, c, d )....
// Also keep track of original poly index.
Geometry.prototype.convertPolyIndicesToTri = function ( indices, strides ) {
var res = [];
var i = 0;
var tmp = [];
var currentPolyNum = 0;
var currentStride = 0;
var polyIndices = [];
while ( i < indices.length ) {
......@@ -1729,14 +1742,14 @@
res.push( indices[ i + ( currentStride - 2 - j ) ] );
res.push( indices[ i + ( currentStride - 1 - j ) ] );
polyIndices.push(currentPolyNum);
}
currentPolyNum ++;
i += currentStride;
}
return res;
return {res: res, polyIndices: polyIndices};
};
......@@ -2503,6 +2516,114 @@
};
function Materials() {
this.materials = [];
this.perGeoMap = {};
}
Materials.prototype.add = function ( mat ) {
if ( this.materials === undefined ) {
this.materials = [];
}
this.materials.push( mat );
for ( var i = 0; i < mat.parentIds.length; ++ i ) {
if ( this.perGeoMap[ mat.parentIds[ i ] ] === undefined ) {
this.perGeoMap[ mat.parentIds[ i ] ] = [];
}
this.perGeoMap[ mat.parentIds[ i ] ].push( this.materials[ this.materials.length - 1 ] );
}
};
Materials.prototype.parse = function ( node, bones ) {
var rawNodes = node.Objects.subNodes.Material;
for ( var n in rawNodes ) {
var mat = ( new Material() ).parse( rawNodes[ n ], node );
this.add( mat );
}
return this;
};
Materials.prototype.getById = function ( id ) {
return this.perGeoMap[ id ];
};
function Material() {
this.fileName = "";
this.name = "";
this.id = null;
this.parentIds = [];
}
Material.prototype.parse = function ( node, nodes ) {
this.id = node.id;
this.name = node.attrName;
this.type = node.properties.ShadingModel;
this.parameters = this.getParameters( node.properties );
this.parentIds = this.searchParents( this.id, nodes );
return this;
};
Material.prototype.getParameters = function( properties ) {
var parameters = {};
//TODO: Missing parameters:
// - Ambient
// - AmbientColor
// - (Diffuse?) Using DiffuseColor, which has same value, so I dunno.
// - (Emissive?) Same as above)
// - MultiLayer
// - ShininessExponent (Same vals as Shininess)
// - Specular (Same vals as SpecularColor)
// - TransparencyFactor (Maybe same as Opacity?).
parameters.color = new THREE.Color().fromArray(toFloat([properties.DiffuseColor.value.x, properties.DiffuseColor.value.y, properties.DiffuseColor.value.z]));
parameters.specular = new THREE.Color().fromArray(toFloat([properties.SpecularColor.value.x, properties.SpecularColor.value.y, properties.SpecularColor.value.z]));
parameters.shininess = properties.Shininess.value;
parameters.emissive = new THREE.Color().fromArray(toFloat([properties.EmissiveColor.value.x, properties.EmissiveColor.value.y, properties.EmissiveColor.value.z]));
parameters.emissiveIntensity = properties.EmissiveFactor.value;
parameters.reflectivity = properties.Reflectivity.value;
parameters.opacity = properties.Opacity.value;
if(parameters.opacity < 1.0) {
parameters.transparent = true;
}
return parameters;
};
Material.prototype.searchParents = function ( id, nodes ) {
var p = nodes.searchConnectionParent( id );
return p;
};
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
......
......@@ -44,7 +44,7 @@
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats, controls;
var camera, scene, renderer;
var camera, scene, renderer, light;
var clock = new THREE.Clock();
......@@ -93,7 +93,7 @@
};
var loader = new THREE.FBXLoader( manager );
loader.load( 'models/fbx/xsi_man_skinning.fbx', function( object ) {
loader.load( 'models/fbx/xsi_man.fbx', function( object ) {
object.traverse( function( child ) {
......@@ -138,6 +138,10 @@
window.addEventListener( 'resize', onWindowResize, false );
light = new THREE.DirectionalLight(0xffffff, 1.0);
light.position.set(0, 1, 0);
scene.add(light);
animate();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册