Skip to content

Commit 9ca7cc5

Browse files
authored
Merge pull request #545 from BabylonJS/drigax/3dsMaxInstancesWithUniqueMaterials
Naively support 3dsMax mesh instances with different materials.
2 parents c01bf9f + f132925 commit 9ca7cc5

File tree

1 file changed

+77
-52
lines changed

1 file changed

+77
-52
lines changed

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

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -51,87 +51,56 @@ private BabylonNode ExportMesh(IIGameScene scene, IIGameNode meshNode, BabylonSc
5151
// - an instance mesh only stores the info of the node (transform, hierarchy, animations)
5252

5353
// Check if this mesh has already been exported
54-
BabylonMesh babylonMasterMesh = null;
54+
List<BabylonMesh> babylonMasterMeshes = new List<BabylonMesh>();
5555
var index = 0;
56-
while (babylonMasterMesh == null &&
57-
index < tabs.Count)
56+
while (index < tabs.Count)
5857
{
5958
#if MAX2017 || MAX2018 || MAX2019
6059
var tab = tabs[index];
6160
#else
6261
var tab = tabs[new IntPtr(index)];
6362
#endif
6463

65-
babylonMasterMesh = babylonScene.MeshesList.Find(_babylonMesh => {
64+
babylonMasterMeshes.AddRange(babylonScene.MeshesList.FindAll(_babylonMesh => {
6665
// Same id
6766
return _babylonMesh.id == tab.GetGuid().ToString() &&
6867
// Mesh is not a dummy
6968
_babylonMesh.isDummy == false;
70-
});
69+
}));
7170

7271
index++;
7372
}
7473

75-
if (babylonMasterMesh != null)
74+
if (babylonMasterMeshes.Count > 0)
7675
{
7776
// Mesh already exported
7877
// Export this node as instance
7978

80-
meshNode.MaxNode.MarkAsInstance();
81-
82-
var babylonInstanceMesh = new BabylonAbstractMesh
83-
{
84-
id = meshNode.MaxNode.GetGuid().ToString(),
85-
name = meshNode.Name,
86-
pickable = meshNode.MaxNode.GetBoolProperty("babylonjs_checkpickable"),
87-
checkCollisions = meshNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"),
88-
showBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showboundingbox"),
89-
showSubMeshesBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showsubmeshesboundingbox"),
90-
alphaIndex = (int)meshNode.MaxNode.GetFloatProperty("babylonjs_alphaindex", 1000)
91-
};
92-
93-
// Physics
94-
var impostorText = meshNode.MaxNode.GetStringProperty("babylonjs_impostor", "None");
95-
96-
if (impostorText != "None")
79+
// Check if we need to export this instance as an instance mesh.
80+
// If there is already an exported mesh in the scene that shares this mesh's material, then export it as an instance.
81+
BabylonMesh babylonMasterMesh = null;
82+
foreach (var mesh in babylonMasterMeshes)
9783
{
98-
switch (impostorText)
84+
if (meshNode.NodeMaterial.MaxMaterial.GetGuid().ToString().Equals(mesh.materialId))
9985
{
100-
case "Sphere":
101-
babylonInstanceMesh.physicsImpostor = 1;
102-
break;
103-
case "Box":
104-
babylonInstanceMesh.physicsImpostor = 2;
105-
break;
106-
case "Plane":
107-
babylonInstanceMesh.physicsImpostor = 3;
108-
break;
109-
default:
110-
babylonInstanceMesh.physicsImpostor = 0;
111-
break;
86+
babylonMasterMesh = mesh;
11287
}
113-
114-
babylonInstanceMesh.physicsMass = meshNode.MaxNode.GetFloatProperty("babylonjs_mass");
115-
babylonInstanceMesh.physicsFriction = meshNode.MaxNode.GetFloatProperty("babylonjs_friction", 0.2f);
116-
babylonInstanceMesh.physicsRestitution = meshNode.MaxNode.GetFloatProperty("babylonjs_restitution", 0.2f);
11788
}
11889

90+
if (babylonMasterMesh != null)
91+
{
92+
return ExportInstanceMesh(scene, meshNode, babylonScene, babylonMasterMesh);
93+
}
11994

120-
// Add instance to master mesh
121-
List<BabylonAbstractMesh> list = babylonMasterMesh.instances != null ? babylonMasterMesh.instances.ToList() : new List<BabylonAbstractMesh>();
122-
list.Add(babylonInstanceMesh);
123-
babylonMasterMesh.instances = list.ToArray();
124-
125-
// Export transform / hierarchy / animations
126-
exportNode(babylonInstanceMesh, meshNode, scene, babylonScene);
127-
128-
// Animations
129-
exportAnimation(babylonInstanceMesh, meshNode);
130-
131-
return babylonInstanceMesh;
95+
return ExportMasterMesh(scene, meshNode, babylonScene);
13296
}
13397
}
13498

99+
return ExportMasterMesh(scene, meshNode, babylonScene);
100+
}
101+
102+
private BabylonNode ExportMasterMesh(IIGameScene scene, IIGameNode meshNode, BabylonScene babylonScene)
103+
{
135104
var gameMesh = meshNode.IGameObject.AsGameMesh();
136105
try
137106
{
@@ -536,6 +505,62 @@ private BabylonNode ExportMesh(IIGameScene scene, IIGameNode meshNode, BabylonSc
536505
return babylonMesh;
537506
}
538507

508+
private BabylonNode ExportInstanceMesh(IIGameScene scene, IIGameNode meshNode, BabylonScene babylonScene, BabylonMesh babylonMasterMesh)
509+
{
510+
meshNode.MaxNode.MarkAsInstance();
511+
512+
var babylonInstanceMesh = new BabylonAbstractMesh
513+
{
514+
id = meshNode.MaxNode.GetGuid().ToString(),
515+
name = meshNode.Name,
516+
pickable = meshNode.MaxNode.GetBoolProperty("babylonjs_checkpickable"),
517+
checkCollisions = meshNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"),
518+
showBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showboundingbox"),
519+
showSubMeshesBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showsubmeshesboundingbox"),
520+
alphaIndex = (int)meshNode.MaxNode.GetFloatProperty("babylonjs_alphaindex", 1000)
521+
};
522+
523+
// Physics
524+
var impostorText = meshNode.MaxNode.GetStringProperty("babylonjs_impostor", "None");
525+
526+
if (impostorText != "None")
527+
{
528+
switch (impostorText)
529+
{
530+
case "Sphere":
531+
babylonInstanceMesh.physicsImpostor = 1;
532+
break;
533+
case "Box":
534+
babylonInstanceMesh.physicsImpostor = 2;
535+
break;
536+
case "Plane":
537+
babylonInstanceMesh.physicsImpostor = 3;
538+
break;
539+
default:
540+
babylonInstanceMesh.physicsImpostor = 0;
541+
break;
542+
}
543+
544+
babylonInstanceMesh.physicsMass = meshNode.MaxNode.GetFloatProperty("babylonjs_mass");
545+
babylonInstanceMesh.physicsFriction = meshNode.MaxNode.GetFloatProperty("babylonjs_friction", 0.2f);
546+
babylonInstanceMesh.physicsRestitution = meshNode.MaxNode.GetFloatProperty("babylonjs_restitution", 0.2f);
547+
}
548+
549+
550+
// Add instance to master mesh
551+
List<BabylonAbstractMesh> list = babylonMasterMesh.instances != null ? babylonMasterMesh.instances.ToList() : new List<BabylonAbstractMesh>();
552+
list.Add(babylonInstanceMesh);
553+
babylonMasterMesh.instances = list.ToArray();
554+
555+
// Export transform / hierarchy / animations
556+
exportNode(babylonInstanceMesh, meshNode, scene, babylonScene);
557+
558+
// Animations
559+
exportAnimation(babylonInstanceMesh, meshNode);
560+
561+
return babylonInstanceMesh;
562+
}
563+
539564
private List<GlobalVertex> ExtractVertices(BabylonAbstractMesh babylonAbstractMesh, IIGameNode maxMorphTarget, bool optimizeVertices, List<int> faceIndexes)
540565
{
541566
var gameMesh = maxMorphTarget.IGameObject.AsGameMesh();

0 commit comments

Comments
 (0)