|
@@ -4,6 +4,7 @@ using System.Linq;
|
|
|
using Autodesk.Max;
|
|
|
using BabylonExport.Entities;
|
|
|
using System.Runtime.InteropServices;
|
|
|
+using System.Threading.Tasks;
|
|
|
|
|
|
namespace Max2Babylon
|
|
|
{
|
|
@@ -35,12 +36,12 @@ namespace Max2Babylon
|
|
|
for (int i = 0; i < boneIds.Count; ++i)
|
|
|
{
|
|
|
var id = boneIds[i];
|
|
|
- if(id == -2)
|
|
|
+ if (id == -2)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
var parent = boneIndex[id].NodeParent;
|
|
|
- if(parent != null)
|
|
|
+ if (parent != null)
|
|
|
{
|
|
|
var parentId = parent.NodeID;
|
|
|
if (boneIds.IndexOf(parentId) > i)
|
|
@@ -52,7 +53,7 @@ namespace Max2Babylon
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if(!foundMisMatch)
|
|
|
+ if (!foundMisMatch)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
@@ -89,7 +90,26 @@ namespace Max2Babylon
|
|
|
babylonMesh.id = meshNode.MaxNode.GetGuid().ToString();
|
|
|
if (meshNode.NodeParent != null)
|
|
|
{
|
|
|
- babylonMesh.parentId = meshNode.NodeParent.MaxNode.GetGuid().ToString();
|
|
|
+
|
|
|
+ // parent node type (if a known object type, export it as an empty mesh, so it can be in the scene hierarchy)
|
|
|
+ var parentType = meshNode.NodeParent.IGameObject.IGameType;
|
|
|
+ var parentId = meshNode.NodeParent.MaxNode.GetGuid().ToString();
|
|
|
+ switch (parentType)
|
|
|
+ {
|
|
|
+ case Autodesk.Max.IGameObject.ObjectTypes.Light:
|
|
|
+ case Autodesk.Max.IGameObject.ObjectTypes.Mesh:
|
|
|
+ case Autodesk.Max.IGameObject.ObjectTypes.Camera:
|
|
|
+ break;
|
|
|
+
|
|
|
+
|
|
|
+ default:
|
|
|
+ if (!babylonScene.MeshesList.Where(m => m.id == parentId).Any())
|
|
|
+ {
|
|
|
+ ExportMesh(scene, meshNode.NodeParent, babylonScene);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ babylonMesh.parentId = parentId;
|
|
|
}
|
|
|
|
|
|
// Misc.
|
|
@@ -124,6 +144,11 @@ namespace Max2Babylon
|
|
|
// Position / rotation / scaling
|
|
|
{
|
|
|
var localTM = meshNode.GetObjectTM(0);
|
|
|
+ if (meshNode.NodeParent != null)
|
|
|
+ {
|
|
|
+ var parentWorld = meshNode.NodeParent.GetObjectTM(0);
|
|
|
+ localTM.MultiplyBy(parentWorld.Inverse);
|
|
|
+ }
|
|
|
|
|
|
var meshTrans = localTM.Translation;
|
|
|
var meshRotation = localTM.Rotation;
|
|
@@ -181,13 +206,13 @@ namespace Max2Babylon
|
|
|
IntPtr indexer = new IntPtr(i);
|
|
|
var channelNum = mappingChannels[indexer];
|
|
|
if (channelNum == 1)
|
|
|
- {
|
|
|
+ {
|
|
|
hasUV = true;
|
|
|
- }
|
|
|
+ }
|
|
|
else if (channelNum == 2)
|
|
|
- {
|
|
|
+ {
|
|
|
hasUV2 = true;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
var hasColor = unskinnedMesh.NumberOfColorVerts > 0;
|
|
|
var hasAlpha = unskinnedMesh.GetNumberOfMapVerts(-2) > 0;
|
|
@@ -207,7 +232,7 @@ namespace Max2Babylon
|
|
|
var subMeshes = new List<BabylonSubMesh>();
|
|
|
var indexStart = 0;
|
|
|
|
|
|
-
|
|
|
+
|
|
|
for (int i = 0; i < multiMatsCount; ++i)
|
|
|
{
|
|
|
if (meshNode.NodeMaterial == null)
|
|
@@ -244,7 +269,7 @@ namespace Max2Babylon
|
|
|
ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (indexCount != 0)
|
|
|
{
|
|
|
|
|
@@ -354,7 +379,7 @@ namespace Max2Babylon
|
|
|
// Animations
|
|
|
var animations = new List<BabylonAnimation>();
|
|
|
GenerateCoordinatesAnimations(meshNode, animations);
|
|
|
-
|
|
|
+
|
|
|
|
|
|
if (!ExportFloatController(meshNode.MaxNode.VisController, "visibility", animations))
|
|
|
{
|
|
@@ -419,31 +444,49 @@ namespace Max2Babylon
|
|
|
}
|
|
|
|
|
|
public static void GenerateCoordinatesAnimations(IIGameNode meshNode, List<BabylonAnimation> animations)
|
|
|
+ {
|
|
|
+
|
|
|
+ ExportVector3Animation("position", animations, key =>
|
|
|
{
|
|
|
- ExportVector3Animation("position", animations, key =>
|
|
|
- {
|
|
|
var worldMatrix = meshNode.GetObjectTM(key);
|
|
|
+ if (meshNode.NodeParent != null)
|
|
|
+ {
|
|
|
+ var parentWorld = meshNode.NodeParent.GetObjectTM(key);
|
|
|
+ worldMatrix.MultiplyBy(parentWorld.Inverse);
|
|
|
+ }
|
|
|
var trans = worldMatrix.Translation;
|
|
|
return new float[] { trans.X, trans.Y, trans.Z };
|
|
|
- });
|
|
|
+ });
|
|
|
|
|
|
- ExportQuaternionAnimation("rotationQuaternion", animations, key =>
|
|
|
+
|
|
|
+ ExportQuaternionAnimation("rotationQuaternion", animations, key =>
|
|
|
+ {
|
|
|
+ var worldMatrix = meshNode.GetObjectTM(key);
|
|
|
+ if (meshNode.NodeParent != null)
|
|
|
{
|
|
|
- var worldMatrix = meshNode.GetObjectTM(key);
|
|
|
+ var parentWorld = meshNode.NodeParent.GetObjectTM(key);
|
|
|
+ worldMatrix.MultiplyBy(parentWorld.Inverse);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
+ var rot = worldMatrix.Rotation;
|
|
|
+ return new float[] { rot.X, rot.Y, rot.Z, -rot.W };
|
|
|
+ });
|
|
|
|
|
|
- var rot = worldMatrix.Rotation;
|
|
|
- return new float[] { rot.X, rot.Y, rot.Z, -rot.W };
|
|
|
- });
|
|
|
|
|
|
- ExportVector3Animation("scaling", animations, key =>
|
|
|
+ ExportVector3Animation("scaling", animations, key =>
|
|
|
+ {
|
|
|
+ var worldMatrix = meshNode.GetObjectTM(key);
|
|
|
+ if (meshNode.NodeParent != null)
|
|
|
{
|
|
|
- var worldMatrix = meshNode.GetObjectTM(key);
|
|
|
- var scale = worldMatrix.Scaling;
|
|
|
+ var parentWorld = meshNode.NodeParent.GetObjectTM(key);
|
|
|
+ worldMatrix.MultiplyBy(parentWorld.Inverse);
|
|
|
+ }
|
|
|
+ var scale = worldMatrix.Scaling;
|
|
|
+
|
|
|
+ return new float[] { scale.X, scale.Y, scale.Z };
|
|
|
+ });
|
|
|
|
|
|
- return new float[] { scale.X, scale.Y, scale.Z };
|
|
|
- });
|
|
|
}
|
|
|
|
|
|
|