|
@@ -1,6 +1,7 @@
|
|
|
/**
|
|
|
* @author Kyle-Larson https://github.com/Kyle-Larson
|
|
|
* @author Takahiro https://github.com/takahirox
|
|
|
+ * @author Lewy Blue https://github.com/looeee
|
|
|
*
|
|
|
* Loader loads FBX file and generates Group representing FBX scene.
|
|
|
* Requires FBX file to be >= 7.0 and in ASCII or to be any version in Binary format.
|
|
@@ -605,8 +606,8 @@
|
|
|
|
|
|
if ( deformerNode.attrType === 'Skin' ) {
|
|
|
|
|
|
- var conns = connections.get( parseInt( nodeID ) );
|
|
|
- var skeleton = parseSkeleton( conns, DeformerNodes );
|
|
|
+ var relationships = connections.get( parseInt( nodeID ) );
|
|
|
+ var skeleton = parseSkeleton( relationships, DeformerNodes );
|
|
|
skeleton.FBX_ID = parseInt( nodeID );
|
|
|
|
|
|
deformers[ nodeID ] = skeleton;
|
|
@@ -709,7 +710,9 @@
|
|
|
|
|
|
var deformer = relationships.children.reduce( function ( deformer, child ) {
|
|
|
|
|
|
- if ( deformers[ child.ID ] !== undefined ) return deformers[ child.ID ];
|
|
|
+ if ( deformers[ child.ID ] !== undefined ) deformer = deformers[ child.ID ];
|
|
|
+
|
|
|
+ return deformer;
|
|
|
|
|
|
}, null );
|
|
|
|
|
@@ -1498,23 +1501,12 @@
|
|
|
|
|
|
setModelTransforms( FBXTree, model, modelNode, connections, sceneGraph );
|
|
|
|
|
|
- var parents = connections.get( model.FBX_ID ).parents;
|
|
|
-
|
|
|
- parents.forEach( function ( parent ) {
|
|
|
-
|
|
|
- var modelArray = Array.from( modelMap.values() );
|
|
|
-
|
|
|
- var pIndex = modelArray.map( function ( model ) {
|
|
|
-
|
|
|
- return model.FBX_ID;
|
|
|
-
|
|
|
- } ).indexOf( parent.ID );
|
|
|
+ var parentConnections = connections.get( model.FBX_ID ).parents;
|
|
|
|
|
|
- if ( pIndex > - 1 ) {
|
|
|
+ parentConnections.forEach( function ( connection ) {
|
|
|
|
|
|
- modelArray[ pIndex ].add( model );
|
|
|
-
|
|
|
- }
|
|
|
+ var parent = modelMap.get( connection.ID );
|
|
|
+ if ( parent !== undefined ) parent.add( model );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -1546,10 +1538,11 @@
|
|
|
|
|
|
var id = parseInt( nodeID );
|
|
|
var node = modelNodes[ nodeID ];
|
|
|
- var conns = connections.get( id );
|
|
|
+ var relationships = connections.get( id );
|
|
|
var model = null;
|
|
|
|
|
|
- conns.parents.forEach( function ( parent ) {
|
|
|
+ // create bones
|
|
|
+ relationships.parents.forEach( function ( parent ) {
|
|
|
|
|
|
for ( var FBX_ID in deformers ) {
|
|
|
|
|
@@ -1563,9 +1556,14 @@
|
|
|
model = new THREE.Bone();
|
|
|
deformer.bones[ subDeformer.index ] = model;
|
|
|
|
|
|
- // seems like we need this not to make non-connected bone, maybe?
|
|
|
- // TODO: confirm
|
|
|
- if ( model2 !== null ) model.add( model2 );
|
|
|
+ // In cases where a bone is shared between multiple meshes
|
|
|
+ // model will already be defined and we'll hit this case
|
|
|
+ // TODO: currently doesn't work correctly
|
|
|
+ if ( model2 !== null ) {
|
|
|
+
|
|
|
+ model.add( model2 );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1578,16 +1576,16 @@
|
|
|
switch ( node.attrType ) {
|
|
|
|
|
|
case 'Camera':
|
|
|
- model = createCamera( FBXTree, conns );
|
|
|
+ model = createCamera( FBXTree, relationships );
|
|
|
break;
|
|
|
case 'Light':
|
|
|
- model = createLight( FBXTree, conns );
|
|
|
+ model = createLight( FBXTree, relationships );
|
|
|
break;
|
|
|
case 'Mesh':
|
|
|
- model = createMesh( FBXTree, conns, geometryMap, materialMap );
|
|
|
+ model = createMesh( FBXTree, relationships, geometryMap, materialMap );
|
|
|
break;
|
|
|
case 'NurbsCurve':
|
|
|
- model = createCurve( conns, geometryMap );
|
|
|
+ model = createCurve( relationships, geometryMap );
|
|
|
break;
|
|
|
default:
|
|
|
model = new THREE.Group();
|
|
@@ -1609,12 +1607,12 @@
|
|
|
}
|
|
|
|
|
|
// create a THREE.PerspectiveCamera or THREE.OrthographicCamera
|
|
|
- function createCamera( FBXTree, conns ) {
|
|
|
+ function createCamera( FBXTree, relationships ) {
|
|
|
|
|
|
var model;
|
|
|
var cameraAttribute;
|
|
|
|
|
|
- conns.children.forEach( function ( child ) {
|
|
|
+ relationships.children.forEach( function ( child ) {
|
|
|
|
|
|
var attr = FBXTree.Objects.subNodes.NodeAttribute[ child.ID ];
|
|
|
|
|
@@ -1697,12 +1695,12 @@
|
|
|
}
|
|
|
|
|
|
// Create a THREE.DirectionalLight, THREE.PointLight or THREE.SpotLight
|
|
|
- function createLight( FBXTree, conns ) {
|
|
|
+ function createLight( FBXTree, relationships ) {
|
|
|
|
|
|
var model;
|
|
|
var lightAttribute;
|
|
|
|
|
|
- conns.children.forEach( function ( child ) {
|
|
|
+ relationships.children.forEach( function ( child ) {
|
|
|
|
|
|
var attr = FBXTree.Objects.subNodes.NodeAttribute[ child.ID ];
|
|
|
|
|
@@ -1820,14 +1818,15 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- function createMesh( FBXTree, conns, geometryMap, materialMap ) {
|
|
|
+ function createMesh( FBXTree, relationships, geometryMap, materialMap ) {
|
|
|
|
|
|
var model;
|
|
|
var geometry = null;
|
|
|
var material = null;
|
|
|
var materials = [];
|
|
|
|
|
|
- conns.children.forEach( function ( child ) {
|
|
|
+ // get geometry and materials(s) from connections
|
|
|
+ relationships.children.forEach( function ( child ) {
|
|
|
|
|
|
if ( geometryMap.has( child.ID ) ) {
|
|
|
|
|
@@ -1888,15 +1887,13 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
- function createCurve( conns, geometryMap ) {
|
|
|
+ function createCurve( relationships, geometryMap ) {
|
|
|
|
|
|
- var geometry = conns.children.reduce( function ( geo, child ) {
|
|
|
+ var geometry = relationships.children.reduce( function ( geo, child ) {
|
|
|
|
|
|
- if ( geometryMap.has( child.ID ) ) {
|
|
|
+ if ( geometryMap.has( child.ID ) ) geo = geometryMap.get( child.ID );
|
|
|
|
|
|
- return geometryMap.get( child.ID );
|
|
|
-
|
|
|
- }
|
|
|
+ return geo;
|
|
|
|
|
|
}, null );
|
|
|
|
|
@@ -2046,13 +2043,23 @@
|
|
|
|
|
|
if ( BindPoseNode[ nodeID ].attrType === 'BindPose' ) {
|
|
|
|
|
|
- BindPoseNode[ nodeID ].subNodes.PoseNode.forEach( function ( poseNode ) {
|
|
|
+ var poseNodes = BindPoseNode[ nodeID ].subNodes.PoseNode;
|
|
|
|
|
|
- var rawMatWrd = new THREE.Matrix4().fromArray( poseNode.subNodes.Matrix.properties.a );
|
|
|
+ if ( Array.isArray( poseNodes ) ) {
|
|
|
|
|
|
- worldMatrices.set( parseInt( poseNode.properties.Node ), rawMatWrd );
|
|
|
+ poseNodes.forEach( function ( node ) {
|
|
|
|
|
|
- } );
|
|
|
+ var rawMatWrd = new THREE.Matrix4().fromArray( node.subNodes.Matrix.properties.a );
|
|
|
+ worldMatrices.set( parseInt( node.properties.Node ), rawMatWrd );
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var rawMatWrd = new THREE.Matrix4().fromArray( poseNodes.subNodes.Matrix.properties.a );
|
|
|
+ worldMatrices.set( parseInt( poseNodes.properties.Node ), rawMatWrd );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -2084,21 +2091,22 @@
|
|
|
// Now that skeleton is in bind pose, bind to model.
|
|
|
deformer.skeleton = new THREE.Skeleton( deformer.bones );
|
|
|
|
|
|
- var conns = connections.get( deformer.FBX_ID );
|
|
|
- var parents = conns.parents;
|
|
|
+ var relationships = connections.get( deformer.FBX_ID );
|
|
|
+ var parents = relationships.parents;
|
|
|
|
|
|
parents.forEach( function ( parent ) {
|
|
|
|
|
|
if ( geometryMap.has( parent.ID ) ) {
|
|
|
|
|
|
var geoID = parent.ID;
|
|
|
- var geoConns = connections.get( geoID );
|
|
|
+ var georelationships = connections.get( geoID );
|
|
|
|
|
|
- geoConns.parents.forEach( function ( geoConnParent ) {
|
|
|
+ georelationships.parents.forEach( function ( geoConnParent ) {
|
|
|
|
|
|
if ( modelMap.has( geoConnParent.ID ) ) {
|
|
|
|
|
|
var model = modelMap.get( geoConnParent.ID );
|
|
|
+
|
|
|
model.bind( deformer.skeleton, model.matrixWorld );
|
|
|
|
|
|
}
|
|
@@ -2183,12 +2191,12 @@
|
|
|
|
|
|
};
|
|
|
|
|
|
- var conns = connections.get( animationCurve.id );
|
|
|
+ var relationships = connections.get( animationCurve.id );
|
|
|
|
|
|
- if ( conns !== undefined ) {
|
|
|
+ if ( relationships !== undefined ) {
|
|
|
|
|
|
- var animationCurveID = conns.parents[ 0 ].ID;
|
|
|
- var animationCurveRelationship = conns.parents[ 0 ].relationship;
|
|
|
+ var animationCurveID = relationships.parents[ 0 ].ID;
|
|
|
+ var animationCurveRelationship = relationships.parents[ 0 ].relationship;
|
|
|
var axis = '';
|
|
|
|
|
|
if ( animationCurveRelationship.match( /X/ ) ) {
|
|
@@ -2245,7 +2253,13 @@
|
|
|
|
|
|
if ( layerCurveNodes[ i ] === undefined ) {
|
|
|
|
|
|
- var modelID = connections.get( child.ID ).parents[ 1 ].ID;
|
|
|
+ var modelID;
|
|
|
+
|
|
|
+ connections.get( child.ID ).parents.forEach( function ( parent ) {
|
|
|
+
|
|
|
+ if ( parent.relationship !== undefined ) modelID = parent.ID;
|
|
|
+
|
|
|
+ } );
|
|
|
|
|
|
var rawModel = FBXTree.Objects.subNodes.Model[ modelID.toString() ];
|
|
|
|