@@ -1118,8 +1118,17 @@ private bool ExportSkin (SkinnedMeshRenderer skinnedMesh,
1118
1118
/// </summary>
1119
1119
private void SetVertexWeights ( MeshInfo meshInfo , Dictionary < int , FbxCluster > boneCluster )
1120
1120
{
1121
+ HashSet < int > visitedVertices = new HashSet < int > ( ) ;
1122
+
1121
1123
// set the vertex weights for each bone
1122
1124
for ( int i = 0 ; i < meshInfo . BoneWeights . Length ; i ++ ) {
1125
+ var actualIndex = ControlPointToIndex [ meshInfo . Vertices [ i ] ] ;
1126
+
1127
+ if ( visitedVertices . Contains ( actualIndex ) ) {
1128
+ continue ;
1129
+ }
1130
+ visitedVertices . Add ( actualIndex ) ;
1131
+
1123
1132
var boneWeights = meshInfo . BoneWeights ;
1124
1133
int [ ] indices = {
1125
1134
boneWeights [ i ] . boneIndex0 ,
@@ -1141,7 +1150,8 @@ boneWeights [i].weight3
1141
1150
if ( ! boneCluster . ContainsKey ( indices [ j ] ) ) {
1142
1151
continue ;
1143
1152
}
1144
- boneCluster [ indices [ j ] ] . AddControlPointIndex ( ControlPointToIndex [ meshInfo . Vertices [ i ] ] , weights [ j ] ) ;
1153
+ // add vertex and weighting on vertex to this bone's cluster
1154
+ boneCluster [ indices [ j ] ] . AddControlPointIndex ( actualIndex , weights [ j ] ) ;
1145
1155
}
1146
1156
}
1147
1157
}
@@ -1220,6 +1230,30 @@ public static FbxVector4 ConvertQuaternionToXYZEuler (FbxQuaternion quat)
1220
1230
return new FbxVector4 ( vector4 . X , - vector4 . Y , - vector4 . Z , vector4 . W ) ;
1221
1231
}
1222
1232
1233
+ /// <summary>
1234
+ /// Euler to quaternion without axis conversion.
1235
+ /// </summary>
1236
+ /// <returns>a quaternion.</returns>
1237
+ /// <param name="euler">Euler.</param>
1238
+ public static FbxQuaternion EulerToQuaternion ( FbxVector4 euler )
1239
+ {
1240
+ FbxAMatrix m = new FbxAMatrix ( ) ;
1241
+ m . SetR ( euler ) ;
1242
+ return m . GetQ ( ) ;
1243
+ }
1244
+
1245
+ /// <summary>
1246
+ /// Quaternion to euler without axis conversion.
1247
+ /// </summary>
1248
+ /// <returns>a euler.</returns>
1249
+ /// <param name="quat">Quaternion.</param>
1250
+ public static FbxVector4 QuaternionToEuler ( FbxQuaternion quat )
1251
+ {
1252
+ FbxAMatrix m = new FbxAMatrix ( ) ;
1253
+ m . SetQ ( quat ) ;
1254
+ return m . GetR ( ) ;
1255
+ }
1256
+
1223
1257
// get a fbxNode's global default position.
1224
1258
protected bool ExportTransform ( UnityEngine . Transform unityTransform , FbxNode fbxNode , Vector3 newCenter , TransformExportType exportType )
1225
1259
{
@@ -1620,6 +1654,12 @@ public static bool TryGetValue(string uniPropertyName, out FbxPropertyChannelPai
1620
1654
return true ;
1621
1655
}
1622
1656
1657
+ if ( uniPropertyName . StartsWith ( "field of view" , ct ) )
1658
+ {
1659
+ prop = new FbxPropertyChannelPair ( "FieldOfView" , null ) ;
1660
+ return true ;
1661
+ }
1662
+
1623
1663
prop = new FbxPropertyChannelPair ( ) ;
1624
1664
return false ;
1625
1665
}
@@ -1679,8 +1719,9 @@ Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) {
1679
1719
var fbxPreRotationEuler = node . GetRotationActive ( )
1680
1720
? node . GetPreRotation ( FbxNode . EPivotSet . eSourcePivot )
1681
1721
: new FbxVector4 ( ) ;
1682
- var fbxPreRotationInverse = new FbxQuaternion ( ) ;
1683
- fbxPreRotationInverse . ComposeSphericalXYZ ( fbxPreRotationEuler ) ;
1722
+
1723
+ // Get the inverse of the prerotation
1724
+ var fbxPreRotationInverse = ModelExporter . EulerToQuaternion ( fbxPreRotationEuler ) ;
1684
1725
fbxPreRotationInverse . Inverse ( ) ;
1685
1726
1686
1727
// If we're only animating along certain coords for some
@@ -1709,17 +1750,23 @@ Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) {
1709
1750
( z == null ) ? lclQuaternion [ 2 ] : z . Evaluate ( seconds ) ,
1710
1751
( w == null ) ? lclQuaternion [ 3 ] : w . Evaluate ( seconds ) ) ;
1711
1752
1753
+ // convert the final animation to righthanded coords
1754
+ var finalEuler = ModelExporter . ConvertQuaternionToXYZEuler ( fbxFinalAnimation ) ;
1755
+
1756
+ // convert it back to a quaternion for multiplication
1757
+ fbxFinalAnimation = ModelExporter . EulerToQuaternion ( finalEuler ) ;
1758
+
1712
1759
// Cancel out the pre-rotation. Order matters. FBX reads left-to-right.
1713
1760
// When we run animation we will apply:
1714
1761
// pre-rotation
1715
1762
// then pre-rotation inverse
1716
1763
// then animation.
1717
- var fbxQuat = fbxPreRotationInverse * fbxFinalAnimation ;
1764
+ var fbxFinalQuat = fbxPreRotationInverse * fbxFinalAnimation ;
1718
1765
1719
1766
// Store the key so we can sort them later.
1720
1767
Key key ;
1721
1768
key . time = FbxTime . FromSecondDouble ( seconds ) ;
1722
- key . euler = ModelExporter . ConvertQuaternionToXYZEuler ( fbxQuat ) ;
1769
+ key . euler = ModelExporter . QuaternionToEuler ( fbxFinalQuat ) ; ;
1723
1770
keys [ i ++ ] = key ;
1724
1771
}
1725
1772
0 commit comments