private BabylonShadowGenerator ExportShadowGenerator(Node lightNode, BabylonScene babylonScene) { var maxLight = (lightNode.Object as Light); var babylonShadowGenerator = new BabylonShadowGenerator(); RaiseMessage("Exporting shadow map", true, false, true); babylonShadowGenerator.lightId = lightNode.GetGuid().ToString(); babylonShadowGenerator.mapSize = maxLight.GetMapSize(0, Interval.Forever); var maxScene = Kernel.Scene; var list = new List<string>(); var inclusion = maxLight._Light.ExclList.TestFlag(1); //NT_INCLUDE var checkExclusionList = maxLight._Light.ExclList.TestFlag(4); //NT_AFFECT_SHADOWCAST foreach (var meshNode in maxScene.NodesListBySuperClass(SuperClassID.GeometricObject)) { if (meshNode._Node.CastShadows == 1) { var inList = maxLight._Light.ExclList.FindNode(meshNode._Node) != -1; if (!checkExclusionList || (inList && inclusion) || (!inList && !inclusion)) { list.Add(meshNode.GetGuid().ToString()); } } } babylonShadowGenerator.renderList = list.ToArray(); babylonScene.ShadowGeneratorsList.Add(babylonShadowGenerator); return babylonShadowGenerator; }
public SerializableModel(Node node, TimeValue t, bool bMeshData, bool bReferencedData) { color = node.Color; bone = node.IsBone; if (bMeshData) // && node.Visibility.Render) mesh = node.GetMesh(t); transform = node.GetNodeTransform(t); name = node.Name; foreach (Node child in node.Nodes) models.Add(new SerializableModel(child, t, bMeshData)); if (bReferencedData) foreach (SceneObject obj in node.TargetTree.FilterType<SceneObject>()) submeshes.Add(obj.GetMesh(t)); }
public void Remove(Node n) { n.DeleteModifier(this); }
public void Apply(Node n) { n.AddModifier(this); }
public SerializableModel(Node node, TimeValue t, bool bMeshData) : this(node, t, bMeshData, false) { }
public SerializableModel(Node node) : this(node, Kernel.Now) { }
public SerializableModel(Node node, TimeValue t) : this(node, t, true) { }
private BabylonMesh ExportMesh(Node meshNode, BabylonScene babylonScene, CancellationToken token) { var babylonMesh = new BabylonMesh(); int vx1, vx2, vx3; RaiseMessage(meshNode.Name, true); babylonMesh.name = meshNode.Name; babylonMesh.id = meshNode.GetGuid().ToString(); if (meshNode.HasParent()) { babylonMesh.parentId = meshNode.Parent.GetGuid().ToString(); } // Misc. babylonMesh.isVisible = meshNode._Node.Renderable == 1; babylonMesh.pickable = meshNode._Node.GetBoolProperty("babylonjs_checkpickable"); babylonMesh.receiveShadows = meshNode._Node.RcvShadows == 1; babylonMesh.showBoundingBox = meshNode._Node.GetBoolProperty("babylonjs_showboundingbox"); babylonMesh.showSubMeshesBoundingBox = meshNode._Node.GetBoolProperty("babylonjs_showsubmeshesboundingbox"); // Collisions babylonMesh.checkCollisions = meshNode._Node.GetBoolProperty("babylonjs_checkcollisions"); // Position / rotation / scaling var wm = meshNode.GetWorldMatrix(0, meshNode.HasParent()); babylonMesh.position = wm.Trans.ToArraySwitched(); var parts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(wm, parts); //var rotate = new float[3]; //IntPtr xPtr = Marshal.AllocHGlobal(sizeof(float)); //IntPtr yPtr = Marshal.AllocHGlobal(sizeof(float)); //IntPtr zPtr = Marshal.AllocHGlobal(sizeof(float)); //parts.Q.GetEuler(xPtr, yPtr, zPtr); //Marshal.Copy(xPtr, rotate, 0, 1); //Marshal.Copy(yPtr, rotate, 1, 1); //Marshal.Copy(zPtr, rotate, 2, 1); //var temp = -rotate[1]; //rotate[0] = rotate[0] * parts.F; //rotate[1] = -rotate[2] * parts.F; //rotate[2] = temp * parts.F; //babylonMesh.rotation = rotate; babylonMesh.rotationQuaternion = parts.Q.ToArray(); babylonMesh.scaling = parts.K.ToArraySwitched(); if (wm.Parity) { vx1 = 2; vx2 = 1; vx3 = 0; } else { vx1 = 0; vx2 = 1; vx3 = 2; } // Pivot var pivotMatrix = Matrix3.Identity._IMatrix3; pivotMatrix.PreTranslate(meshNode._Node.ObjOffsetPos); Loader.Global.PreRotateMatrix(pivotMatrix, meshNode._Node.ObjOffsetRot); Loader.Global.ApplyScaling(pivotMatrix, meshNode._Node.ObjOffsetScale); babylonMesh.pivotMatrix = pivotMatrix.ToArray(); // Mesh var objectState = meshNode._Node.EvalWorldState(0, false); var mesh = objectState.Obj.GetMesh(); var computedMesh = meshNode.GetMesh(); if (mesh != null) { mesh.BuildNormals(); if (mesh.NumFaces < 1) { RaiseError(string.Format("Mesh {0} has no face", babylonMesh.name)); } if (mesh.NumVerts < 3) { RaiseError(string.Format("Mesh {0} has not enough vertices", babylonMesh.name)); } if (mesh.NumVerts >= 65536) { RaiseError(string.Format("Mesh {0} has too many vertices (more than 65535)", babylonMesh.name)); } // Material var mtl = meshNode.Material; var multiMatsCount = 1; if (mtl != null) { babylonMesh.materialId = mtl.GetGuid().ToString(); if (!referencedMaterials.Contains(mtl)) { referencedMaterials.Add(mtl); } multiMatsCount = Math.Max(mtl.NumSubMaterials, 1); } babylonMesh.visibility = meshNode._Node.GetVisibility(0, Interval.Forever._IInterval); var vertices = new List<GlobalVertex>(); var indices = new List<int>(); var matIDs = new List<int>(); var hasUV = mesh.NumTVerts > 0; var hasUV2 = mesh.GetNumMapVerts(2) > 0; var noOptimize = meshNode._Node.GetBoolProperty("babylonjs_nooptimize"); for (var face = 0; face < mesh.NumFaces; face++) { indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx1, vertices, hasUV, hasUV2, noOptimize)); indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx2, vertices, hasUV, hasUV2, noOptimize)); indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx3, vertices, hasUV, hasUV2, noOptimize)); matIDs.Add(mesh.Faces[face].MatID % multiMatsCount); if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); } if (vertices.Count >= 65536) { RaiseError(string.Format("Mesh {0} has too many vertices: {1} (limit is 65535)", babylonMesh.name, vertices.Count)); } // Buffers babylonMesh.positions = vertices.SelectMany(v => v.Position.ToArraySwitched()).ToArray(); babylonMesh.normals = vertices.SelectMany(v => v.Normal.ToArraySwitched()).ToArray(); if (hasUV) { babylonMesh.uvs = vertices.SelectMany(v => v.UV.ToArray()).ToArray(); } if (hasUV2) { babylonMesh.uvs2 = vertices.SelectMany(v => v.UV2.ToArray()).ToArray(); } // Submeshes var sortedIndices = new List<int>(); var subMeshes = new List<BabylonSubMesh>(); var indexStart = 0; for (var index = 0; index < multiMatsCount; index++) { var subMesh = new BabylonSubMesh(); var indexCount = 0; var minVertexIndex = int.MaxValue; var maxVertexIndex = int.MinValue; subMesh.indexStart = indexStart; subMesh.materialIndex = index; for (var face = 0; face < matIDs.Count; face++) { if (matIDs[face] == index) { var a = indices[3 * face]; var b = indices[3 * face + 1]; var c = indices[3 * face + 2]; sortedIndices.Add(a); sortedIndices.Add(b); sortedIndices.Add(c); indexCount += 3; if (a < minVertexIndex) { minVertexIndex = a; } if (b < minVertexIndex) { minVertexIndex = b; } if (c < minVertexIndex) { minVertexIndex = c; } if (a > maxVertexIndex) { maxVertexIndex = a; } if (b > maxVertexIndex) { maxVertexIndex = b; } if (c > maxVertexIndex) { maxVertexIndex = c; } } } if (indexCount != 0) { subMesh.indexCount = indexCount; subMesh.verticesStart = minVertexIndex; subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1; indexStart += indexCount; subMeshes.Add(subMesh); } if (token.IsCancellationRequested) token.ThrowIfCancellationRequested(); } babylonMesh.subMeshes = subMeshes.ToArray(); // Buffers - Indices babylonMesh.indices = sortedIndices.ToArray(); } // Animations var animations = new List<BabylonAnimation>(); ExportVector3Animation("position", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); return worldMatrix.Trans.ToArraySwitched(); }); ExportQuaternionAnimation("rotationQuaternion", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); var affineParts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(worldMatrix, affineParts); return affineParts.Q.ToArray(); }); ExportVector3Animation("scaling", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); var affineParts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(worldMatrix, affineParts); return affineParts.K.ToArraySwitched(); }); ExportFloatAnimation("visibility", animations, key => new []{meshNode._Node.GetVisibility(key, Interval.Forever._IInterval)}); babylonMesh.animations = animations.ToArray(); if (meshNode._Node.GetBoolProperty("babylonjs_autoanimate")) { babylonMesh.autoAnimate = true; babylonMesh.autoAnimateFrom = (int)meshNode._Node.GetFloatProperty("babylonjs_autoanimate_from"); babylonMesh.autoAnimateTo = (int)meshNode._Node.GetFloatProperty("babylonjs_autoanimate_to"); babylonMesh.autoAnimateLoop = meshNode._Node.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.MeshesList.Add(babylonMesh); return babylonMesh; }
private BabylonLight ExportLight(Node lightNode, BabylonScene babylonScene) { var maxLight = (lightNode.Object as Light); var babylonLight = new BabylonLight(); RaiseMessage(maxLight.Name, true); babylonLight.name = lightNode.Name; babylonLight.id = lightNode.GetGuid().ToString(); // Type var lightState = Loader.Global.LightState.Create(); maxLight._Light.EvalLightState(0, Interval.Forever._IInterval, lightState); var directionScale = -1; switch (lightState.Type) { case LightType.OmniLgt: babylonLight.type = 0; break; case LightType.SpotLgt: babylonLight.type = 2; babylonLight.angle = (float)(maxLight.GetFallOffSize(0, Interval.Forever) * Math.PI / 180.0f); babylonLight.exponent = 1; break; case LightType.DirectLgt: babylonLight.type = 1; // Shadows if (maxLight.ShadowMethod == 1) { ExportShadowGenerator(lightNode, babylonScene); } break; case LightType.AmbientLgt: babylonLight.type = 3; babylonLight.groundColor = new float[] { 0, 0, 0 }; directionScale = 1; break; } // Position var wm = lightNode.GetWorldMatrix(0, false); var position = wm.Trans; babylonLight.position = position.ToArraySwitched(); // Direction var target = lightNode._Node.Target; if (target != null) { var targetWm = target.GetObjTMBeforeWSM(0, Interval.Forever._IInterval); var targetPosition = targetWm.Trans; var direction = targetPosition.Subtract(position); babylonLight.direction = direction.ToArraySwitched(); } else { var dir = wm.GetRow(2).MultiplyBy(directionScale); babylonLight.direction = dir.ToArraySwitched(); } // Exclusion var maxScene = Kernel.Scene; var inclusion = maxLight._Light.ExclList.TestFlag(1); //NT_INCLUDE var checkExclusionList = maxLight._Light.ExclList.TestFlag(2); //NT_AFFECT_ILLUM if (checkExclusionList) { var list = new List<string>(); foreach (var meshNode in maxScene.NodesListBySuperClass(SuperClassID.GeometricObject)) { if (meshNode._Node.CastShadows == 1) { var inList = maxLight._Light.ExclList.FindNode(meshNode._Node) != -1; if ((!inList && inclusion) || (inList && !inclusion)) { list.Add(meshNode.GetGuid().ToString()); } } } babylonLight.excludedMeshesIds = list.ToArray(); } // Other fields babylonLight.intensity = maxLight.GetIntensity(0, Interval.Forever); babylonLight.diffuse = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Interval.Forever).ToArray() : new float[] { 0, 0, 0 }; babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Interval.Forever).ToArray() : new float[] { 0, 0, 0 }; if (maxLight.UseAttenuation) { babylonLight.range = maxLight.GetAttenuation(0, 1, Interval.Forever); } // Animations var animations = new List<BabylonAnimation>(); ExportVector3Animation("position", animations, key => { var worldMatrix = lightNode.GetWorldMatrix(key, lightNode.HasParent()); return worldMatrix.Trans.ToArraySwitched(); }); ExportVector3Animation("direction", animations, key => { var targetNode = lightNode._Node.Target; if (targetNode != null) { var targetWm = target.GetObjTMBeforeWSM(0, Interval.Forever._IInterval); var targetPosition = targetWm.Trans; var direction = targetPosition.Subtract(position); return direction.ToArraySwitched(); } var dir = wm.GetRow(2).MultiplyBy(directionScale); return dir.ToArraySwitched(); }); ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Interval.Forever) }); babylonLight.animations = animations.ToArray(); if (lightNode._Node.GetBoolProperty("babylonjs_autoanimate")) { babylonLight.autoAnimate = true; babylonLight.autoAnimateFrom = (int)lightNode._Node.GetFloatProperty("babylonjs_autoanimate_from"); babylonLight.autoAnimateTo = (int)lightNode._Node.GetFloatProperty("babylonjs_autoanimate_to"); babylonLight.autoAnimateLoop = lightNode._Node.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.LightsList.Add(babylonLight); return babylonLight; }
public Node AddNewNode(SceneObject o) { Node n = new Node(Kernel._Interface.CreateObjectNode(o._Object)); _Node.AttachChild(n._Node, true); return n; }
private BabylonCamera ExportCamera(Node cameraNode, BabylonScene babylonScene) { var maxCamera = (cameraNode.Object as Camera)._Camera; var babylonCamera = new BabylonCamera(); RaiseMessage(cameraNode.Name, true); babylonCamera.name = cameraNode.Name; babylonCamera.id = cameraNode.GetGuid().ToString(); if (cameraNode.HasParent()) { babylonCamera.parentId = cameraNode.Parent.GetGuid().ToString(); } babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Interval.Forever._IInterval)); babylonCamera.minZ = maxCamera.GetEnvRange(0, 0, Interval.Forever._IInterval); babylonCamera.maxZ = maxCamera.GetEnvRange(0, 1, Interval.Forever._IInterval); if (babylonCamera.minZ == 0.0f) { babylonCamera.minZ = 0.1f; } // Control babylonCamera.speed = cameraNode._Node.GetFloatProperty("babylonjs_speed"); babylonCamera.inertia = cameraNode._Node.GetFloatProperty("babylonjs_inertia"); // Collisions babylonCamera.checkCollisions = cameraNode._Node.GetBoolProperty("babylonjs_checkcollisions"); babylonCamera.applyGravity = cameraNode._Node.GetBoolProperty("babylonjs_applygravity"); babylonCamera.ellipsoid = cameraNode._Node.GetVector3Property("babylonjs_ellipsoid"); // Position var wm = cameraNode.GetWorldMatrix(0, cameraNode.HasParent()); var position = wm.Trans; babylonCamera.position = position.ToArraySwitched(); // Target var target = cameraNode._Node.Target; if (target != null) { babylonCamera.lockedTargetId = target.GetGuid().ToString(); } else { var dir = wm.GetRow(2).MultiplyBy(-1); babylonCamera.target = position.Add(dir).ToArraySwitched(); } // Animations var animations = new List<BabylonAnimation>(); ExportVector3Animation("position", animations, key => { var worldMatrix = cameraNode.GetWorldMatrix(key, cameraNode.HasParent()); return worldMatrix.Trans.ToArraySwitched(); }); ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov(maxCamera.GetFOV(key, Interval.Forever._IInterval)) }); babylonCamera.animations = animations.ToArray(); if (cameraNode._Node.GetBoolProperty("babylonjs_autoanimate")) { babylonCamera.autoAnimate = true; babylonCamera.autoAnimateFrom = (int)cameraNode._Node.GetFloatProperty("babylonjs_autoanimate_from"); babylonCamera.autoAnimateTo = (int)cameraNode._Node.GetFloatProperty("babylonjs_autoanimate_to"); babylonCamera.autoAnimateLoop = cameraNode._Node.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.CamerasList.Add(babylonCamera); return babylonCamera; }
public void Attach(Node n, bool keepTM) { _Node.AttachChild(n._Node, keepTM); }
public void Attach(Node n) { Attach(n, true); }
public SerializableScene(MaxSharp.Node x) { root = new Node(x); Dictionary<UIntPtr, MaxSharp.Animatable> lookup = new Dictionary<UIntPtr, MaxSharp.Animatable>(); var pluginList = new List<Plugin>(); foreach (var rt in x.NodeReferenceTree) { // Make sure we don't repeat anything. if (!lookup.ContainsKey(rt.AnimHandle)) { if (rt is MaxSharp.Node || rt is MaxSharp.ParameterBlock1 || rt is MaxSharp.ParameterBlock2) { // do nothing these } else { pluginList.Add(new Plugin(rt)); } lookup.Add(rt.AnimHandle, rt); } } this.plugins = pluginList.ToArray(); }
public void UpdateTargetDistance(TimeValue t, Node inode) { _Light.UpdateTargDistance(t, inode._Node); }
private void ExportMesh(Node meshNode, BabylonScene babylonScene) { if (meshNode._Node.GetBoolProperty("babylonjs_noexport")) { return; } var babylonMesh = new BabylonMesh(); int vx1, vx2, vx3; babylonMesh.name = meshNode.Name; babylonMesh.id = meshNode.GetGuid().ToString(); if (meshNode.HasParent()) { babylonMesh.parentId = meshNode.Parent.GetGuid().ToString(); } // Misc. babylonMesh.isVisible = meshNode._Node.Renderable == 1; babylonMesh.pickable = meshNode._Node.GetBoolProperty("babylonjs_checkpickable"); babylonMesh.receiveShadows = meshNode._Node.RcvShadows == 1; babylonMesh.showBoundingBox = meshNode._Node.GetBoolProperty("babylonjs_showboundingbox"); babylonMesh.showSubMeshesBoundingBox = meshNode._Node.GetBoolProperty("babylonjs_showsubmeshesboundingbox"); // Collisions babylonMesh.checkCollisions = meshNode._Node.GetBoolProperty("babylonjs_checkcollisions"); // Skin var skin = GetSkinModifier(meshNode._Node); if (skin != null) { babylonMesh.skeletonId = skins.IndexOf(skin); bonesCount = skin.NumBones; } // Position / rotation / scaling var wm = meshNode.GetWorldMatrix(0, meshNode.HasParent()); babylonMesh.position = wm.Trans.ToArraySwitched(); var parts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(wm, parts); //var rotate = new float[3]; //IntPtr xPtr = Marshal.AllocHGlobal(sizeof(float)); //IntPtr yPtr = Marshal.AllocHGlobal(sizeof(float)); //IntPtr zPtr = Marshal.AllocHGlobal(sizeof(float)); //parts.Q.GetEuler(xPtr, yPtr, zPtr); //Marshal.Copy(xPtr, rotate, 0, 1); //Marshal.Copy(yPtr, rotate, 1, 1); //Marshal.Copy(zPtr, rotate, 2, 1); //var temp = rotate[1]; //rotate[0] = -rotate[0] * parts.F; //rotate[1] = -rotate[2] * parts.F; //rotate[2] = -temp * parts.F; //babylonMesh.rotation = rotate; babylonMesh.rotationQuaternion = parts.Q.ToArray(); babylonMesh.scaling = parts.K.ToArraySwitched(); if (wm.Parity) { vx1 = 2; vx2 = 1; vx3 = 0; } else { vx1 = 0; vx2 = 1; vx3 = 2; } // Pivot var pivotMatrix = Matrix3.Identity._IMatrix3; pivotMatrix.PreTranslate(meshNode._Node.ObjOffsetPos); Loader.Global.PreRotateMatrix(pivotMatrix, meshNode._Node.ObjOffsetRot); Loader.Global.ApplyScaling(pivotMatrix, meshNode._Node.ObjOffsetScale); babylonMesh.pivotMatrix = pivotMatrix.ToArray(); // Mesh var objectState = meshNode._Node.EvalWorldState(0, false); bool mustBeDeleted; var triObject = objectState.Obj.GetMesh(out mustBeDeleted); var mesh = triObject != null ? triObject.Mesh : null; var computedMesh = meshNode.GetMesh(); RaiseMessage(meshNode.Name, mesh == null ? System.Drawing.Color.Gray : System.Drawing.Color.Black, true); if (mesh != null) { mesh.BuildNormals(); if (mesh.NumFaces < 1) { RaiseError(string.Format("Mesh {0} has no face", babylonMesh.name)); } if (mesh.NumVerts < 3) { RaiseError(string.Format("Mesh {0} has not enough vertices", babylonMesh.name)); } if (mesh.NumVerts >= 65536) { RaiseError(string.Format("Mesh {0} has too many vertices (more than 65535)", babylonMesh.name)); } // Material var mtl = meshNode.Material; var multiMatsCount = 1; if (mtl != null) { babylonMesh.materialId = mtl.GetGuid().ToString(); if (!referencedMaterials.Contains(mtl)) { referencedMaterials.Add(mtl); } multiMatsCount = Math.Max(mtl.NumSubMaterials, 1); } babylonMesh.visibility = meshNode._Node.GetVisibility(0, Interval.Forever._IInterval); var vertices = new List<GlobalVertex>(); var indices = new List<int>(); var matIDs = new List<int>(); var hasUV = mesh.NumTVerts > 0; var hasUV2 = mesh.GetNumMapVerts(2) > 0; var optimizeVertices = meshNode._Node.GetBoolProperty("babylonjs_optimizevertices"); // Skin IISkinContextData skinContext = null; if (skin != null) { skinContext = skin.GetContextInterface(meshNode._Node); } // Compute normals VNormal[] vnorms = null; List<GlobalVertex>[] verticesAlreadyExported = null; if (!optimizeVertices) { vnorms = Tools.ComputeNormals(mesh); } else { verticesAlreadyExported = new List<GlobalVertex>[mesh.NumVerts]; } for (var face = 0; face < mesh.NumFaces; face++) { indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx1, vertices, hasUV, hasUV2, vnorms, verticesAlreadyExported, skinContext)); indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx2, vertices, hasUV, hasUV2, vnorms, verticesAlreadyExported, skinContext)); indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx3, vertices, hasUV, hasUV2, vnorms, verticesAlreadyExported, skinContext)); matIDs.Add(mesh.Faces[face].MatID % multiMatsCount); CheckCancelled(); } if (vertices.Count >= 65536) { RaiseError(string.Format("Mesh {0} has too many vertices: {1} (limit is 65535)", babylonMesh.name, vertices.Count)); if (!optimizeVertices) { RaiseError("You can try to optimize your object using [Try to optimize vertices] option"); } } RaiseMessage(string.Format("{0} vertices, {1} faces", vertices.Count, indices.Count / 3), true, false, true); // Buffers babylonMesh.positions = vertices.SelectMany(v => v.Position.ToArraySwitched()).ToArray(); babylonMesh.normals = vertices.SelectMany(v => v.Normal.ToArraySwitched()).ToArray(); if (hasUV) { babylonMesh.uvs = vertices.SelectMany(v => v.UV.ToArray()).ToArray(); } if (hasUV2) { babylonMesh.uvs2 = vertices.SelectMany(v => v.UV2.ToArray()).ToArray(); } if (skin != null) { babylonMesh.matricesWeights = vertices.SelectMany(v => v.Weights.ToArray()).ToArray(); babylonMesh.matricesIndices = vertices.Select(v => v.BonesIndices).ToArray(); } // Submeshes var sortedIndices = new List<int>(); var subMeshes = new List<BabylonSubMesh>(); var indexStart = 0; for (var index = 0; index < multiMatsCount; index++) { var subMesh = new BabylonSubMesh(); var indexCount = 0; var minVertexIndex = int.MaxValue; var maxVertexIndex = int.MinValue; subMesh.indexStart = indexStart; subMesh.materialIndex = index; for (var face = 0; face < matIDs.Count; face++) { if (matIDs[face] == index) { var a = indices[3 * face]; var b = indices[3 * face + 1]; var c = indices[3 * face + 2]; sortedIndices.Add(a); sortedIndices.Add(b); sortedIndices.Add(c); indexCount += 3; if (a < minVertexIndex) { minVertexIndex = a; } if (b < minVertexIndex) { minVertexIndex = b; } if (c < minVertexIndex) { minVertexIndex = c; } if (a > maxVertexIndex) { maxVertexIndex = a; } if (b > maxVertexIndex) { maxVertexIndex = b; } if (c > maxVertexIndex) { maxVertexIndex = c; } } } if (indexCount != 0) { subMesh.indexCount = indexCount; subMesh.verticesStart = minVertexIndex; subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1; indexStart += indexCount; subMeshes.Add(subMesh); } CheckCancelled(); } babylonMesh.subMeshes = subMeshes.ToArray(); // Buffers - Indices babylonMesh.indices = sortedIndices.ToArray(); if (mustBeDeleted) { triObject.DeleteMe(); } } // Animations var animations = new List<BabylonAnimation>(); if (!ExportVector3Controller(meshNode._Node.TMController.PositionController, "position", animations)) { ExportVector3Animation("position", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); return worldMatrix.Trans.ToArraySwitched(); }); } if (!ExportQuaternionController(meshNode._Node.TMController.RotationController, "rotationQuaternion", animations)) { ExportQuaternionAnimation("rotationQuaternion", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); var affineParts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(worldMatrix, affineParts); return affineParts.Q.ToArray(); }); } if (!ExportVector3Controller(meshNode._Node.TMController.ScaleController, "scaling", animations)) { ExportVector3Animation("scaling", animations, key => { var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent()); var affineParts = Loader.Global.AffineParts.Create(); Loader.Global.DecompAffine(worldMatrix, affineParts); return affineParts.K.ToArraySwitched(); }); } if (!ExportFloatController(meshNode._Node.VisController, "visibility", animations)) { ExportFloatAnimation("visibility", animations, key => new[] {meshNode._Node.GetVisibility(key, Interval.Forever._IInterval)}); } babylonMesh.animations = animations.ToArray(); if (meshNode._Node.GetBoolProperty("babylonjs_autoanimate")) { babylonMesh.autoAnimate = true; babylonMesh.autoAnimateFrom = (int)meshNode._Node.GetFloatProperty("babylonjs_autoanimate_from"); babylonMesh.autoAnimateTo = (int)meshNode._Node.GetFloatProperty("babylonjs_autoanimate_to"); babylonMesh.autoAnimateLoop = meshNode._Node.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.MeshesList.Add(babylonMesh); }