Skip to content

Commit 87d89d2

Browse files
JBoyeJonas Boye
andauthored
3ds Max: 8 UV Channels (#1129)
Increased number of UV Channels in the 3DS Max exporter, to match the Maya Exporter --------- Co-authored-by: Jonas Boye <Jonas.Boye@Lindberg.com>
1 parent a1a1d82 commit 87d89d2

File tree

2 files changed

+198
-17
lines changed

2 files changed

+198
-17
lines changed

3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

Lines changed: 156 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ private BabylonNode ExportMasterMesh(IIGameScene scene, IIGameNode meshNode, Bab
371371
var mappingChannels = unskinnedMesh.ActiveMapChannelNum;
372372
bool hasUV = false;
373373
bool hasUV2 = false;
374+
bool hasUV3 = false;
375+
bool hasUV4 = false;
376+
bool hasUV5 = false;
377+
bool hasUV6 = false;
378+
bool hasUV7 = false;
379+
bool hasUV8 = false;
374380
for (int i = 0; i < mappingChannels.Count; ++i)
375381
{
376382
#if MAX2017 || MAX2018 || MAX2019 || MAX2020 || MAX2021 || MAX2022 || MAX2023 || MAX2024 || MAX2025 || MAX2026
@@ -386,7 +392,33 @@ private BabylonNode ExportMasterMesh(IIGameScene scene, IIGameNode meshNode, Bab
386392
{
387393
hasUV2 = true;
388394
}
395+
else if (channelNum == 3)
396+
{
397+
hasUV3 = true;
398+
}
399+
else if (channelNum == 4)
400+
{
401+
hasUV4 = true;
402+
}
403+
else if (channelNum == 5)
404+
{
405+
hasUV5 = true;
406+
}
407+
else if (channelNum == 6)
408+
{
409+
hasUV6 = true;
410+
}
411+
else if (channelNum == 7)
412+
{
413+
hasUV7 = true;
414+
}
415+
else if (channelNum == 8)
416+
{
417+
hasUV8 = true;
418+
}
389419
}
420+
421+
390422
var hasColor = unskinnedMesh.NumberOfColorVerts > 0;
391423
var hasAlpha = unskinnedMesh.GetNumberOfMapVerts(-2) > 0;
392424

@@ -399,7 +431,7 @@ private BabylonNode ExportMasterMesh(IIGameScene scene, IIGameNode meshNode, Bab
399431
// Compute normals
400432
var subMeshes = new List<BabylonSubMesh>();
401433
List<int> faceIndexes = null;
402-
ExtractGeometry(babylonMesh, vertices, indices, subMeshes, boneIds, skin, unskinnedMesh, invertedWorldMatrix, offsetTM, hasUV, hasUV2, hasColor, hasAlpha, optimizeVertices, multiMatsCount, meshNode, ref faceIndexes);
434+
ExtractGeometry(babylonMesh, vertices, indices, subMeshes, boneIds, skin, unskinnedMesh, invertedWorldMatrix, offsetTM, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, optimizeVertices, multiMatsCount, meshNode, ref faceIndexes);
403435

404436
if (vertices.Count >= 65536)
405437
{
@@ -434,8 +466,32 @@ private BabylonNode ExportMasterMesh(IIGameScene scene, IIGameNode meshNode, Bab
434466
{
435467
babylonMesh.uvs2 = vertices.SelectMany(v => new[] { v.UV2.X, 1 - v.UV2.Y }).ToArray();
436468
}
469+
if (hasUV3)
470+
{
471+
babylonMesh.uvs3 = vertices.SelectMany(v => new[] { v.UV3.X, 1 - v.UV3.Y }).ToArray();
472+
}
473+
if (hasUV4)
474+
{
475+
babylonMesh.uvs4 = vertices.SelectMany(v => new[] { v.UV4.X, 1 - v.UV4.Y }).ToArray();
476+
}
477+
if (hasUV5)
478+
{
479+
babylonMesh.uvs5 = vertices.SelectMany(v => new[] { v.UV5.X, 1 - v.UV5.Y }).ToArray();
480+
}
481+
if (hasUV6)
482+
{
483+
babylonMesh.uvs6 = vertices.SelectMany(v => new[] { v.UV6.X, 1 - v.UV6.Y }).ToArray();
484+
}
485+
if (hasUV7)
486+
{
487+
babylonMesh.uvs7 = vertices.SelectMany(v => new[] { v.UV7.X, 1 - v.UV7.Y }).ToArray();
488+
}
489+
if (hasUV8)
490+
{
491+
babylonMesh.uvs8 = vertices.SelectMany(v => new[] { v.UV8.X, 1 - v.UV8.Y }).ToArray();
492+
}
437493

438-
if (skin != null)
494+
if (skin != null)
439495
{
440496
babylonMesh.matricesWeights = vertices.SelectMany(v => v.Weights.ToArray()).ToArray();
441497
babylonMesh.matricesIndices = vertices.Select(v => v.BonesIndices).ToArray();
@@ -888,11 +944,11 @@ private List<GlobalVertex> ExtractVertices(BabylonAbstractMesh babylonAbstractMe
888944
var offsetTM = GetOffsetTM(maxMorphTarget, 0);
889945

890946
var vertices = new List<GlobalVertex>();
891-
ExtractGeometry(babylonAbstractMesh, vertices, new List<int>(), new List<BabylonSubMesh>(), null, null, gameMesh, invertedWorldMatrix, offsetTM, false, false, false, false, optimizeVertices, multiMatsCount, maxMorphTarget, ref faceIndexes);
947+
ExtractGeometry(babylonAbstractMesh, vertices, new List<int>(), new List<BabylonSubMesh>(), null, null, gameMesh, invertedWorldMatrix, offsetTM, false, false, false, false, false, false, false, false, false, false, optimizeVertices, multiMatsCount, maxMorphTarget, ref faceIndexes);
892948
return vertices;
893949
}
894950

895-
private void ExtractGeometry(BabylonAbstractMesh babylonAbstractMesh, List<GlobalVertex> vertices, List<int> indices, List<BabylonSubMesh> subMeshes, List<int> boneIds, IIGameSkin skin, IIGameMesh unskinnedMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, bool optimizeVertices, int multiMatsCount, IIGameNode meshNode, ref List<int> faceIndexes)
951+
private void ExtractGeometry(BabylonAbstractMesh babylonAbstractMesh, List<GlobalVertex> vertices, List<int> indices, List<BabylonSubMesh> subMeshes, List<int> boneIds, IIGameSkin skin, IIGameMesh unskinnedMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, bool hasUV, bool hasUV2, bool hasUV3, bool hasUV4, bool hasUV5, bool hasUV6, bool hasUV7, bool hasUV8, bool hasColor, bool hasAlpha, bool optimizeVertices, int multiMatsCount, IIGameNode meshNode, ref List<int> faceIndexes)
896952
{
897953
Dictionary<GlobalVertex, List<GlobalVertex>> verticesAlreadyExported = null;
898954

@@ -937,7 +993,7 @@ private void ExtractGeometry(BabylonAbstractMesh babylonAbstractMesh, List<Globa
937993
{
938994
face = unskinnedMesh.GetFace(faceIndexes[indexInFaceIndexesArray++]);
939995
}
940-
ExtractFace(skin, unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
996+
ExtractFace(skin, unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, vertices, indices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
941997
}
942998
}
943999
else
@@ -964,7 +1020,7 @@ private void ExtractGeometry(BabylonAbstractMesh babylonAbstractMesh, List<Globa
9641020
{
9651021
face = unskinnedMesh.GetFace(faceIndexes[indexInFaceIndexesArray++]);
9661022
}
967-
ExtractFace(skin, unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
1023+
ExtractFace(skin, unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, vertices, indices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
9681024
}
9691025
}
9701026
else
@@ -1018,24 +1074,23 @@ private void ExtractGeometry(BabylonAbstractMesh babylonAbstractMesh, List<Globa
10181074
}
10191075
}
10201076
}
1021-
1022-
private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, BabylonAbstractMesh babylonAbstractMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, List<GlobalVertex> vertices, List<int> indices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, Dictionary<GlobalVertex, List<GlobalVertex>> verticesAlreadyExported, ref int indexCount, ref int minVertexIndex, ref int maxVertexIndex, IFaceEx face, List<int> boneIds)
1077+
private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, BabylonAbstractMesh babylonAbstractMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, List<GlobalVertex> vertices, List<int> indices, bool hasUV, bool hasUV2, bool hasUV3, bool hasUV4, bool hasUV5, bool hasUV6, bool hasUV7, bool hasUV8, bool hasColor, bool hasAlpha, Dictionary<GlobalVertex, List<GlobalVertex>> verticesAlreadyExported, ref int indexCount, ref int minVertexIndex, ref int maxVertexIndex, IFaceEx face, List<int> boneIds)
10231078
{
10241079
int a, b, c;
10251080
// parity is TRUE, if determinant negative ( counter-intuitive convention of 3ds max, see docs... :/ )
10261081
if (invertedWorldMatrix.Parity)
10271082
{
1028-
// flipped case: reverse winding order
1029-
a = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1030-
b = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1031-
c = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1083+
// flipped case: reverse winding order
1084+
a = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 0, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1085+
b = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 1, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1086+
c = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 2, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
10321087
}
10331088
else
10341089
{
1035-
// normal case
1036-
a = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1037-
b = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1038-
c = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1090+
// normal case
1091+
a = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 0, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1092+
b = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 2, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
1093+
c = CreateGlobalVertex(unskinnedMesh, babylonAbstractMesh, invertedWorldMatrix, offsetTM, face, 1, vertices, hasUV, hasUV2, hasUV3, hasUV4, hasUV5, hasUV6, hasUV7, hasUV8, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
10391094
}
10401095

10411096
indices.Add(a);
@@ -1077,7 +1132,7 @@ private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, BabylonAbstr
10771132
CheckCancelled();
10781133
}
10791134

1080-
int CreateGlobalVertex(IIGameMesh mesh, BabylonAbstractMesh babylonAbstractMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, Dictionary<GlobalVertex, List<GlobalVertex>> verticesAlreadyExported, IIGameSkin skin, List<int> boneIds)
1135+
int CreateGlobalVertex(IIGameMesh mesh, BabylonAbstractMesh babylonAbstractMesh, IMatrix3 invertedWorldMatrix, IMatrix3 offsetTM, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasUV3, bool hasUV4, bool hasUV5, bool hasUV6, bool hasUV7, bool hasUV8, bool hasColor, bool hasAlpha, Dictionary<GlobalVertex, List<GlobalVertex>> verticesAlreadyExported, IIGameSkin skin, List<int> boneIds)
10811136
{
10821137
var vertexIndex = (int)face.Vert[facePart];
10831138

@@ -1152,6 +1207,90 @@ int CreateGlobalVertex(IIGameMesh mesh, BabylonAbstractMesh babylonAbstractMesh,
11521207
vertex.UV2 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
11531208
}
11541209

1210+
if (hasUV3)
1211+
{
1212+
var indices = new int[3];
1213+
unsafe
1214+
{
1215+
fixed (int* indicesPtr = indices)
1216+
{
1217+
mesh.GetMapFaceIndex(3, face.MeshFaceIndex, new IntPtr(indicesPtr));
1218+
}
1219+
}
1220+
var texCoord = mesh.GetMapVertex(3, indices[facePart]);
1221+
vertex.UV3 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1222+
}
1223+
1224+
if (hasUV4)
1225+
{
1226+
var indices = new int[3];
1227+
unsafe
1228+
{
1229+
fixed (int* indicesPtr = indices)
1230+
{
1231+
mesh.GetMapFaceIndex(4, face.MeshFaceIndex, new IntPtr(indicesPtr));
1232+
}
1233+
}
1234+
var texCoord = mesh.GetMapVertex(4, indices[facePart]);
1235+
vertex.UV4 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1236+
}
1237+
1238+
if (hasUV5)
1239+
{
1240+
var indices = new int[3];
1241+
unsafe
1242+
{
1243+
fixed (int* indicesPtr = indices)
1244+
{
1245+
mesh.GetMapFaceIndex(5, face.MeshFaceIndex, new IntPtr(indicesPtr));
1246+
}
1247+
}
1248+
var texCoord = mesh.GetMapVertex(5, indices[facePart]);
1249+
vertex.UV5 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1250+
}
1251+
1252+
if (hasUV6)
1253+
{
1254+
var indices = new int[3];
1255+
unsafe
1256+
{
1257+
fixed (int* indicesPtr = indices)
1258+
{
1259+
mesh.GetMapFaceIndex(6, face.MeshFaceIndex, new IntPtr(indicesPtr));
1260+
}
1261+
}
1262+
var texCoord = mesh.GetMapVertex(6, indices[facePart]);
1263+
vertex.UV6 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1264+
}
1265+
1266+
if (hasUV7)
1267+
{
1268+
var indices = new int[3];
1269+
unsafe
1270+
{
1271+
fixed (int* indicesPtr = indices)
1272+
{
1273+
mesh.GetMapFaceIndex(7, face.MeshFaceIndex, new IntPtr(indicesPtr));
1274+
}
1275+
}
1276+
var texCoord = mesh.GetMapVertex(7, indices[facePart]);
1277+
vertex.UV7 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1278+
}
1279+
1280+
if (hasUV8)
1281+
{
1282+
var indices = new int[3];
1283+
unsafe
1284+
{
1285+
fixed (int* indicesPtr = indices)
1286+
{
1287+
mesh.GetMapFaceIndex(8, face.MeshFaceIndex, new IntPtr(indicesPtr));
1288+
}
1289+
}
1290+
var texCoord = mesh.GetMapVertex(8, indices[facePart]);
1291+
vertex.UV8 = Loader.Global.Point2.Create(texCoord.X, 1 - texCoord.Y);
1292+
}
1293+
11551294
if (hasColor)
11561295
{
11571296
var vertexColorIndex = (int)face.Color[facePart];

3ds Max/Max2Babylon/Exporter/GlobalVertex.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ public struct GlobalVertex
1313
public float[] Tangent { get; set; }
1414
public IPoint2 UV { get; set; }
1515
public IPoint2 UV2 { get; set; }
16+
public IPoint2 UV3 { get; set; }
17+
public IPoint2 UV4 { get; set; }
18+
public IPoint2 UV5 { get; set; }
19+
public IPoint2 UV6 { get; set; }
20+
public IPoint2 UV7 { get; set; }
21+
public IPoint2 UV8 { get; set; }
1622
public int BonesIndices { get; set; }
1723
public IPoint4 Weights { get; set; }
1824
public int BonesIndicesExtra { get; set; }
@@ -28,6 +34,12 @@ public GlobalVertex(GlobalVertex other)
2834
this.Tangent = other.Tangent != null ? other.Tangent.Clone2() : null;
2935
this.UV = other.UV != null ? other.UV.Clone() : null;
3036
this.UV2 = other.UV2 != null ? other.UV2.Clone() : null;
37+
this.UV3 = other.UV3 != null ? other.UV3.Clone() : null;
38+
this.UV4 = other.UV4 != null ? other.UV4.Clone() : null;
39+
this.UV5 = other.UV5 != null ? other.UV5.Clone() : null;
40+
this.UV6 = other.UV6 != null ? other.UV6.Clone() : null;
41+
this.UV7 = other.UV7 != null ? other.UV7.Clone() : null;
42+
this.UV8 = other.UV8 != null ? other.UV8.Clone() : null;
3143
this.BonesIndices = other.BonesIndices;
3244
this.Weights = other.Weights != null ? other.Weights.Clone() : null;
3345
this.BonesIndicesExtra = other.BonesIndicesExtra;
@@ -88,6 +100,36 @@ public override bool Equals(object obj)
88100
return false;
89101
}
90102

103+
if (UV3 != null && !other.UV3.IsAlmostEqualTo(UV3, Tools.Epsilon))
104+
{
105+
return false;
106+
}
107+
108+
if (UV4 != null && !other.UV4.IsAlmostEqualTo(UV4, Tools.Epsilon))
109+
{
110+
return false;
111+
}
112+
113+
if (UV5 != null && !other.UV5.IsAlmostEqualTo(UV5, Tools.Epsilon))
114+
{
115+
return false;
116+
}
117+
118+
if (UV6 != null && !other.UV6.IsAlmostEqualTo(UV6, Tools.Epsilon))
119+
{
120+
return false;
121+
}
122+
123+
if (UV7 != null && !other.UV7.IsAlmostEqualTo(UV7, Tools.Epsilon))
124+
{
125+
return false;
126+
}
127+
128+
if (UV8 != null && !other.UV8.IsAlmostEqualTo(UV8, Tools.Epsilon))
129+
{
130+
return false;
131+
}
132+
91133
if (Weights != null && !other.Weights.IsAlmostEqualTo(Weights, Tools.Epsilon))
92134
{
93135
return false;

0 commit comments

Comments
 (0)