|
@@ -463,7 +463,6 @@
|
|
// Also parse the texture map and return any textures associated with the material
|
|
// Also parse the texture map and return any textures associated with the material
|
|
function parseParameters( FBXTree, properties, textureMap, ID, connections ) {
|
|
function parseParameters( FBXTree, properties, textureMap, ID, connections ) {
|
|
|
|
|
|
-
|
|
|
|
var parameters = {};
|
|
var parameters = {};
|
|
|
|
|
|
if ( properties.BumpFactor ) {
|
|
if ( properties.BumpFactor ) {
|
|
@@ -644,10 +643,12 @@
|
|
ID: child.ID,
|
|
ID: child.ID,
|
|
indices: [],
|
|
indices: [],
|
|
weights: [],
|
|
weights: [],
|
|
|
|
+
|
|
|
|
+ // the global initial transform of the geometry node this bone is connected to
|
|
transform: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.Transform.properties.a ),
|
|
transform: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.Transform.properties.a ),
|
|
|
|
|
|
- //currently not used
|
|
|
|
- // transformLink: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.TransformLink.properties.a ),
|
|
|
|
|
|
+ // the global initial transform of this bone
|
|
|
|
+ transformLink: new THREE.Matrix4().fromArray( subDeformerNode.subNodes.TransformLink.properties.a ),
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
@@ -1540,7 +1541,7 @@
|
|
var node = modelNodes[ nodeID ];
|
|
var node = modelNodes[ nodeID ];
|
|
var relationships = connections.get( id );
|
|
var relationships = connections.get( id );
|
|
|
|
|
|
- var model = buildSkeleton( relationships, skeletons );
|
|
|
|
|
|
+ var model = buildSkeleton( relationships, skeletons, id, node.attrName );
|
|
|
|
|
|
if ( ! model ) {
|
|
if ( ! model ) {
|
|
|
|
|
|
@@ -1558,7 +1559,7 @@
|
|
case 'NurbsCurve':
|
|
case 'NurbsCurve':
|
|
model = createCurve( relationships, geometryMap );
|
|
model = createCurve( relationships, geometryMap );
|
|
break;
|
|
break;
|
|
- case 'LimbNode':
|
|
|
|
|
|
+ case 'LimbNode': // usually associated with a bone, however if one was not created we'll make a Group instead
|
|
case 'Null':
|
|
case 'Null':
|
|
default:
|
|
default:
|
|
model = new THREE.Group();
|
|
model = new THREE.Group();
|
|
@@ -1566,28 +1567,23 @@
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( model ) {
|
|
|
|
-
|
|
|
|
- setModelTransforms( FBXTree, model, node );
|
|
|
|
-
|
|
|
|
model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
|
|
model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName );
|
|
model.ID = id;
|
|
model.ID = id;
|
|
|
|
|
|
- modelMap.set( id, model );
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ setModelTransforms( FBXTree, model, node );
|
|
|
|
+ modelMap.set( id, model );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
return modelMap;
|
|
return modelMap;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function buildSkeleton( relationships, skeletons ) {
|
|
|
|
|
|
+ function buildSkeleton( relationships, skeletons, id, name ) {
|
|
|
|
|
|
- var model = null;
|
|
|
|
|
|
+ var bone = null;
|
|
|
|
|
|
relationships.parents.forEach( function ( parent ) {
|
|
relationships.parents.forEach( function ( parent ) {
|
|
|
|
|
|
@@ -1599,16 +1595,20 @@
|
|
|
|
|
|
if ( rawBone.ID === parent.ID ) {
|
|
if ( rawBone.ID === parent.ID ) {
|
|
|
|
|
|
- var model2 = model;
|
|
|
|
- model = new THREE.Bone();
|
|
|
|
- skeleton.bones[ i ] = model;
|
|
|
|
|
|
+ var subBone = bone;
|
|
|
|
+ bone = new THREE.Bone();
|
|
|
|
+
|
|
|
|
+ // set name and id here - otherwise in cases where "subBone" is created it will not have a name / id
|
|
|
|
+ bone.name = THREE.PropertyBinding.sanitizeNodeName( name );
|
|
|
|
+ bone.ID = id;
|
|
|
|
+
|
|
|
|
+ skeleton.bones[ i ] = bone;
|
|
|
|
|
|
// In cases where a bone is shared between multiple meshes
|
|
// 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 ) {
|
|
|
|
|
|
+ // duplicate the bone here and and it as a child of the first bone
|
|
|
|
+ if ( subBone !== null ) {
|
|
|
|
|
|
- model.add( model2 );
|
|
|
|
|
|
+ bone.add( subBone );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1620,7 +1620,7 @@
|
|
|
|
|
|
} );
|
|
} );
|
|
|
|
|
|
- return model;
|
|
|
|
|
|
+ return bone;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1983,6 +1983,8 @@
|
|
// parse the model node for transform details and apply them to the model
|
|
// parse the model node for transform details and apply them to the model
|
|
function setModelTransforms( FBXTree, model, modelNode ) {
|
|
function setModelTransforms( FBXTree, model, modelNode ) {
|
|
|
|
|
|
|
|
+ // console.log( modelNode, model )
|
|
|
|
+
|
|
// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
|
|
// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html
|
|
if ( 'RotationOrder' in modelNode.properties ) {
|
|
if ( 'RotationOrder' in modelNode.properties ) {
|
|
|
|
|
|
@@ -2093,14 +2095,21 @@
|
|
|
|
|
|
var skeleton = skeletons[ ID ];
|
|
var skeleton = skeletons[ ID ];
|
|
|
|
|
|
- skeleton.bones.forEach( function ( bone ) {
|
|
|
|
|
|
+ skeleton.bones.forEach( function ( bone, i ) {
|
|
|
|
|
|
|
|
+ // if the bone's initial transform is set in a poseNode, copy that
|
|
if ( worldMatrices.has( bone.ID ) ) {
|
|
if ( worldMatrices.has( bone.ID ) ) {
|
|
|
|
|
|
var mat = worldMatrices.get( bone.ID );
|
|
var mat = worldMatrices.get( bone.ID );
|
|
bone.matrixWorld.copy( mat );
|
|
bone.matrixWorld.copy( mat );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
+ // otherwise use the transform from the rawBone
|
|
|
|
+ else {
|
|
|
|
+
|
|
|
|
+ bone.matrixWorld.copy( skeleton.rawBones[ i ].transformLink )
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
} );
|
|
} );
|
|
|
|
|