Esempio n. 1
0
        public static bool Export_To(string _filepath)
        {
            List <IINode> nodes = GetSelection();

            foreach (IINode _node in nodes)
            {
                IIDerivedObject _gObject = (IIDerivedObject)_node.ObjectRef;
                IClass_ID       classID  = maxGlobal.Class_ID.Create((uint)BuiltInClassIDA.TRIOBJ_CLASS_ID, 0);
                ITriObject      _mObject = (ITriObject)_gObject.ObjRef.ConvertToType(0, classID);
                IMesh           _mMesh   = _mObject.Mesh;
                _mMesh.BuildNormals();
                IIDerivedObject theObj = (IIDerivedObject)_node.ObjectRef;
                for (int m = 0; m < theObj.Modifiers.Count; m++)
                {
                    IModifier theModifier = theObj.GetModifier(m);
                    if (theModifier.ClassName == "Skin")
                    {
                        IISkin            _skin        = (IISkin)theModifier.GetInterface((InterfaceID)(0x00010000));
                        IISkinContextData _skinContext = _skin.GetContextInterface(_node);
                        ComputeVertexData(_mMesh, _skinContext, semantic, _filepath);
                    }
                }
            }
            return(true);
        }
Esempio n. 2
0
        public static void ComputeVertexData(IMesh _mMesh, IISkinContextData _skin, Semantic _semantic, string _filepath)
        {
            Dictionary <int, VertexUndivided> verticesFullData = new Dictionary <int, VertexUndivided>();
            List <FaceData> facesFullData = new List <FaceData>();
            List <List <VertexDivided> > verticesParsedData = new List <List <VertexDivided> >();

            IList <IFace>   faces     = _mMesh.Faces;
            IList <ITVFace> Tfaces    = _mMesh.TvFace;
            IList <IPoint3> vertices  = _mMesh.Verts;
            IList <IPoint3> Tvertices = _mMesh.TVerts;

            /*
             * foreach (IPoint3 _v in vertices)
             * {
             *  float temp = _v.Y;
             *  _v.Y = -_v.Z;
             *  _v.Z = temp;
             * }
             */
            for (int _fID = 0; _fID < faces.Count; _fID++)
            {
                FaceData _face = new FaceData((int)faces[_fID].SmGroup);

                // vectors are inverted to make up for max being clockwise
                Vector3 A_B = vertices[(int)faces[_fID].GetVert(1)].convertToVector3() - vertices[(int)faces[_fID].GetVert(0)].convertToVector3();
                Vector3 A_C = vertices[(int)faces[_fID].GetVert(2)].convertToVector3() - vertices[(int)faces[_fID].GetVert(0)].convertToVector3();
                Vector3 U   = Tvertices[(int)Tfaces[_fID].GetTVert(1)].convertToVector3() - Tvertices[(int)Tfaces[_fID].GetTVert(0)].convertToVector3();
                Vector3 V   = Tvertices[(int)Tfaces[_fID].GetTVert(2)].convertToVector3() - Tvertices[(int)Tfaces[_fID].GetTVert(0)].convertToVector3();

                Vector3 normUnsure = Vector3.Cross(A_B, A_C);
                normUnsure.Normalize();

                float   area    = U.X * V.Y - U.Y * V.X;
                int     sign    = area < 0 ? -1 : 1;
                Vector3 tangent = new Vector3(0, 0, 1);
                tangent.X = A_B.X * V.Y - U.Y * A_C.X;
                tangent.Y = A_B.Y * V.Y - U.Y * A_C.Y;
                tangent.Z = A_B.Z * V.Y - U.Y * A_C.Z;
                tangent.Normalize();
                tangent *= sign;

                for (int i = 0; i < 3; i++)
                {
                    _face.vertices.Add((int)faces[_fID].GetVert(i));


                    if (verticesFullData.ContainsKey((int)faces[_fID].GetVert(i)))
                    {
                        VertexUndivided _v = verticesFullData[(int)faces[_fID].GetVert(i)];
                        _v.faceInfo.Add(new PerFaceInfo(_fID, (int)faces[_fID].SmGroup, (Tvertices[(int)Tfaces[_fID].GetTVert(i)]).convertToVector2(), normUnsure, tangent));
                    }
                    else
                    {
                        VertexUndivided _v = new VertexUndivided();
                        _v.ID = faces[_fID].GetVert(i);
                        int          nbBonesA     = _skin.GetNumAssignedBones((int)_v.ID);
                        List <int>   bonesID      = new List <int>();
                        List <float> bonesWeights = new List <float>();
                        for (int b = 0; b < 4; b++)
                        {
                            if (nbBonesA < b + 1)
                            {
                                bonesID.Add(0);
                                bonesWeights.Add(0);
                            }
                            else
                            {
                                bonesID.Add(_skin.GetAssignedBone((int)_v.ID, b));
                                bonesWeights.Add(_skin.GetBoneWeight((int)_v.ID, b));
                            }
                        }
                        _v.bonesID      = new ROD_core.BoneIndices(bonesID[0], bonesID[1], bonesID[2], bonesID[3]);
                        _v.bonesWeights = new Vector4(bonesWeights[0], bonesWeights[1], bonesWeights[2], bonesWeights[3]);
                        _v.pos          = (vertices[(int)_v.ID]).convertToVector3();
                        _v.faceInfo.Add(new PerFaceInfo(_fID, (int)faces[_fID].SmGroup, (Tvertices[(int)Tfaces[_fID].GetTVert(i)]).convertToVector2(), normUnsure, tangent));
                        verticesFullData.Add((int)faces[_fID].GetVert(i), _v);
                    }
                }

                facesFullData.Add(_face);
            }
            List <int>           IndexBuffer  = new List <int>();
            List <VertexDivided> VertexBuffer = new List <VertexDivided>();
            // vertex index in vertexfullData "undivided" et sa valeur en fonction du SMG
            Dictionary <int, Dictionary <int, int> > VertexDictionary = new Dictionary <int, Dictionary <int, int> >();

            Mesh mesh = new Mesh();


            for (int _faceID = 0; _faceID < facesFullData.Count; _faceID++)
            {
                facesFullData[_faceID].vertices.Reverse();
                foreach (int _vertex in facesFullData[_faceID].vertices)
                {
                    Dictionary <int, int> vertexTranslation;
                    int _vID = (int)verticesFullData[_vertex].ID;
                    List <PerFaceInfo> unitedVertex = verticesFullData[_vertex].faceInfo.Where(x => x.SMG == facesFullData[_faceID].SMG).ToList();
                    if (!VertexDictionary.ContainsKey(_vID))
                    {
                        VertexDictionary.Add(_vID, new Dictionary <int, int>());
                    }
                    vertexTranslation = VertexDictionary[_vID];
                    VertexDivided _newVertex = new VertexDivided();
                    _newVertex.pos = verticesFullData[_vertex].pos;

                    _newVertex.UV.X = verticesFullData[_vertex].faceInfo.Where(x => x.ID == _faceID).FirstOrDefault().UV.X;
                    _newVertex.UV.Y = 1 - verticesFullData[_vertex].faceInfo.Where(x => x.ID == _faceID).FirstOrDefault().UV.Y;
                    Vector3 _normal_aggreagate  = new Vector3(0, 0, 0);
                    Vector3 _tangent_aggreagate = new Vector3(0, 0, 0);
                    foreach (PerFaceInfo _FI in unitedVertex)
                    {
                        _normal_aggreagate  += _FI.normal;
                        _tangent_aggreagate += _FI.tangent;
                    }
                    _normal_aggreagate.Normalize();
                    _tangent_aggreagate.Normalize();
                    _newVertex.normal       = _normal_aggreagate;
                    _newVertex.tangent      = _tangent_aggreagate;
                    _newVertex.binormal     = Vector3.Cross(_normal_aggreagate, _tangent_aggreagate);
                    _newVertex.bonesID      = verticesFullData[_vertex].bonesID;
                    _newVertex.bonesWeights = verticesFullData[_vertex].bonesWeights;
                    IndexBuffer.Add(VertexBuffer.Count);
                    VertexBuffer.Add(_newVertex);
                }
            }
            mesh._indexStream  = new IndexStream(IndexBuffer.Count, typeof(UInt16), true, true);
            mesh._vertexStream = new VertexStream(VertexBuffer.Count, true, true, _semantic);
            foreach (int id in IndexBuffer)
            {
                UInt16        _id = Convert.ToUInt16(id);
                VertexDivided res = VertexBuffer[_id];
                mesh._indexStream.WriteIndex(_id);
            }
            Type dv = DynamicVertex.CreateVertex(_semantic);

            FieldInfo[] PI = dv.GetFields();

            foreach (VertexDivided vd in VertexBuffer)
            {
                if (mesh._boundingBox.Minimum == null)
                {
                    mesh._boundingBox.Minimum = new Vector3(vd.pos.X, vd.pos.Y, vd.pos.Z);
                    mesh._boundingBox.Maximum = new Vector3(vd.pos.X, vd.pos.Y, vd.pos.Z);
                }
                mesh._boundingBox.Minimum.X = Math.Min(mesh._boundingBox.Minimum.X, vd.pos.X);
                mesh._boundingBox.Minimum.Y = Math.Min(mesh._boundingBox.Minimum.Y, vd.pos.Y);
                mesh._boundingBox.Minimum.Z = Math.Min(mesh._boundingBox.Minimum.Z, vd.pos.Z);
                mesh._boundingBox.Maximum.X = Math.Max(mesh._boundingBox.Maximum.X, vd.pos.X);
                mesh._boundingBox.Maximum.Y = Math.Max(mesh._boundingBox.Maximum.Y, vd.pos.Y);
                mesh._boundingBox.Maximum.Z = Math.Max(mesh._boundingBox.Maximum.Z, vd.pos.Z);
                List <object> vertexData = new List <object>();
                for (int i = 0; i < PI.Length; i++)
                {
                    string fieldSemantic = ((InputElementAttribute)PI[i].GetCustomAttributes(true).First()).Semantic;
                    vertexData.Add(vd.GetSemanticObject(fieldSemantic));
                }
                object[] obj = vertexData.ToArray();
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV, vd.binormal, vd.bonesID, vd.bonesWeights, vd.tangent };
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV, vd.binormal, vd.tangent };
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV};
                mesh._vertexStream.WriteVertex(obj);
            }
            Mesh.saveToFile(mesh, _filepath);
        }
Esempio n. 3
0
        int CreateGlobalVertex(IMesh mesh, int face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, VNormal[] vnorms, List<GlobalVertex>[] verticesAlreadyExported, IISkinContextData skinContextData)
        {
            var faceObject = mesh.Faces[face];
            var vertexIndex = (int)faceObject.V[facePart];

            var vertex = new GlobalVertex
            {
                BaseIndex = vertexIndex,
                Position = mesh.Verts[vertexIndex],
                Normal = vnorms[vertexIndex].GetNormal(verticesAlreadyExported != null ? 1 : faceObject.SmGroup)
            };

            if (hasUV)
            {
                var tvertexIndex = (int)mesh.TvFace[face].T[facePart];
                vertex.UV = Loader.Global.Point2.Create(mesh.TVerts[tvertexIndex].X, mesh.TVerts[tvertexIndex].Y);
            }

            if (hasUV2)
            {
                var tvertexIndex = (int)mesh.MapFaces(2)[face].T[facePart];
                vertex.UV2 = Loader.Global.Point2.Create(mesh.MapVerts(2)[tvertexIndex].X, mesh.MapVerts(2)[tvertexIndex].Y);
            }

            if (skinContextData != null)
            {
                float weight0 = 0;
                float weight1 = 0;
                float weight2 = 0;
                int bone0 = bonesCount;
                int bone1 = bonesCount;
                int bone2 = bonesCount;
                int bone3 = bonesCount;
                int nbBones = skinContextData.GetNumAssignedBones(vertexIndex);

                if (nbBones > 0)
                {
                    bone0 = skinContextData.GetAssignedBone(vertexIndex, 0);
                    weight0 = skinContextData.GetBoneWeight(vertexIndex, 0);
                }

                if (nbBones > 1)
                {
                    bone1 = skinContextData.GetAssignedBone(vertexIndex, 1);
                    weight1 = skinContextData.GetBoneWeight(vertexIndex, 1);
                }

                if (nbBones > 2)
                {
                    bone2 = skinContextData.GetAssignedBone(vertexIndex, 2);
                    weight2 = skinContextData.GetBoneWeight(vertexIndex, 2);
                }

                if (nbBones > 3)
                {
                    bone3 = skinContextData.GetAssignedBone(vertexIndex, 3);
                }

                if (nbBones == 0)
                {
                    weight0 = 1.0f;
                    bone0 = bonesCount;
                }

                if (nbBones > 4)
                {
                    RaiseError("Too many bones influences per vertex: " + nbBones + ". Babylon.js only support 4 bones influences per vertex.", 2);
                }

                vertex.Weights = Loader.Global.Point4.Create(weight0, weight1, weight2, 1.0 - weight0 - weight1 - weight2);
                vertex.BonesIndices = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
            }

            if (verticesAlreadyExported != null)
            {
                if (verticesAlreadyExported[vertexIndex] != null)
                {
                    var index = verticesAlreadyExported[vertexIndex].IndexOf(vertex);

                    if (index > -1)
                    {
                        return verticesAlreadyExported[vertexIndex][index].CurrentIndex;
                    }
                }
                else
                {
                    verticesAlreadyExported[vertexIndex] = new List<GlobalVertex>();
                }

                vertex.CurrentIndex = vertices.Count;
                verticesAlreadyExported[vertexIndex].Add(vertex);
            }

            vertices.Add(vertex);

            return vertices.Count - 1;
        }
Esempio n. 4
0
        int CreateGlobalVertex(IMesh mesh, int face, int facePart, List <GlobalVertex> vertices, bool hasUV, bool hasUV2, VNormal[] vnorms, List <GlobalVertex>[] verticesAlreadyExported, IISkinContextData skinContextData)
        {
            var faceObject  = mesh.Faces[face];
            var vertexIndex = (int)faceObject.V[facePart];

            var vertex = new GlobalVertex
            {
                BaseIndex = vertexIndex,
                Position  = mesh.Verts[vertexIndex],
                Normal    = vnorms[vertexIndex].GetNormal(verticesAlreadyExported != null ? 1 : faceObject.SmGroup)
            };

            if (hasUV)
            {
                var tvertexIndex = (int)mesh.TvFace[face].T[facePart];
                vertex.UV = Loader.Global.Point2.Create(mesh.TVerts[tvertexIndex].X, mesh.TVerts[tvertexIndex].Y);
            }

            if (hasUV2)
            {
                var tvertexIndex = (int)mesh.MapFaces(2)[face].T[facePart];
                vertex.UV2 = Loader.Global.Point2.Create(mesh.MapVerts(2)[tvertexIndex].X, mesh.MapVerts(2)[tvertexIndex].Y);
            }

            if (skinContextData != null)
            {
                float weight0 = 0;
                float weight1 = 0;
                float weight2 = 0;
                int   bone0   = bonesCount;
                int   bone1   = bonesCount;
                int   bone2   = bonesCount;
                int   bone3   = bonesCount;
                int   nbBones = skinContextData.GetNumAssignedBones(vertexIndex);

                if (nbBones > 0)
                {
                    bone0   = skinContextData.GetAssignedBone(vertexIndex, 0);
                    weight0 = skinContextData.GetBoneWeight(vertexIndex, 0);
                }

                if (nbBones > 1)
                {
                    bone1   = skinContextData.GetAssignedBone(vertexIndex, 1);
                    weight1 = skinContextData.GetBoneWeight(vertexIndex, 1);
                }

                if (nbBones > 2)
                {
                    bone2   = skinContextData.GetAssignedBone(vertexIndex, 2);
                    weight2 = skinContextData.GetBoneWeight(vertexIndex, 2);
                }

                if (nbBones > 3)
                {
                    bone3 = skinContextData.GetAssignedBone(vertexIndex, 3);
                }

                if (nbBones == 0)
                {
                    weight0 = 1.0f;
                    bone0   = bonesCount;
                }

                if (nbBones > 4)
                {
                    RaiseError("Too many bones influences per vertex: " + nbBones + ". Babylon.js only support 4 bones influences per vertex.", 2);
                }

                vertex.Weights      = Loader.Global.Point4.Create(weight0, weight1, weight2, 1.0 - weight0 - weight1 - weight2);
                vertex.BonesIndices = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
            }

            if (verticesAlreadyExported != null)
            {
                if (verticesAlreadyExported[vertexIndex] != null)
                {
                    var index = verticesAlreadyExported[vertexIndex].IndexOf(vertex);

                    if (index > -1)
                    {
                        return(verticesAlreadyExported[vertexIndex][index].CurrentIndex);
                    }
                }
                else
                {
                    verticesAlreadyExported[vertexIndex] = new List <GlobalVertex>();
                }

                vertex.CurrentIndex = vertices.Count;
                verticesAlreadyExported[vertexIndex].Add(vertex);
            }

            vertices.Add(vertex);

            return(vertices.Count - 1);
        }
Esempio n. 5
0
        private void ExportMesh(IINode meshNode, BabylonScene babylonScene)
        {
            if (meshNode.IsInstance())
            {
                return;
            }

            if (meshNode.GetBoolProperty("babylonjs_noexport"))
            {
                return;
            }

            if (!ExportHiddenObjects && meshNode.IsHidden(NodeHideFlags.None, false))
            {
                return;
            }

            var babylonMesh = new BabylonMesh();
            int vx1, vx2, vx3;

            babylonMesh.name = meshNode.Name;
            babylonMesh.id   = meshNode.GetGuid().ToString();
            if (meshNode.HasParent())
            {
                babylonMesh.parentId = meshNode.ParentNode.GetGuid().ToString();
            }

            // Misc.
            babylonMesh.isVisible                = meshNode.Renderable == 1;
            babylonMesh.pickable                 = meshNode.GetBoolProperty("babylonjs_checkpickable");
            babylonMesh.receiveShadows           = meshNode.RcvShadows == 1;
            babylonMesh.showBoundingBox          = meshNode.GetBoolProperty("babylonjs_showboundingbox");
            babylonMesh.showSubMeshesBoundingBox = meshNode.GetBoolProperty("babylonjs_showsubmeshesboundingbox");

            // Collisions
            babylonMesh.checkCollisions = meshNode.GetBoolProperty("babylonjs_checkcollisions");

            // Skin
            var skin = GetSkinModifier(meshNode);

            if (skin != null)
            {
                babylonMesh.skeletonId = skins.IndexOf(skin);
                bonesCount             = skin.NumBones;
            }

            // Position / rotation / scaling
            var wm = Tools.ExtractCoordinates(meshNode, babylonMesh, exportQuaternionsInsteadOfEulers);

            if (wm.Parity)
            {
                vx1 = 2;
                vx2 = 1;
                vx3 = 0;
            }
            else
            {
                vx1 = 0;
                vx2 = 1;
                vx3 = 2;
            }

            // Pivot
            var pivotMatrix = Tools.Identity;

            pivotMatrix.PreTranslate(meshNode.ObjOffsetPos);
            Loader.Global.PreRotateMatrix(pivotMatrix, meshNode.ObjOffsetRot);
            Loader.Global.ApplyScaling(pivotMatrix, meshNode.ObjOffsetScale);
            babylonMesh.pivotMatrix = pivotMatrix.ToArray();

            // Mesh
            var objectState = meshNode.EvalWorldState(0, false);
            var triObject   = objectState.Obj.GetMesh();
            var mesh        = triObject != null ? triObject.Mesh : null;

            RaiseMessage(meshNode.Name, 1);

            if (mesh != null)
            {
                mesh.BuildNormals();

                if (mesh.NumFaces < 1)
                {
                    RaiseError(string.Format("Mesh {0} has no face", babylonMesh.name), 2);
                }

                if (mesh.NumVerts < 3)
                {
                    RaiseError(string.Format("Mesh {0} has not enough vertices", babylonMesh.name), 2);
                }

                if (mesh.NumVerts >= 65536)
                {
                    RaiseError(string.Format("Mesh {0} has too many vertices (more than 65535)", babylonMesh.name), 2);
                }

                // Material
                var mtl            = meshNode.Mtl;
                var multiMatsCount = 1;

                if (mtl != null)
                {
                    babylonMesh.materialId = mtl.GetGuid().ToString();

                    if (!referencedMaterials.Contains(mtl))
                    {
                        referencedMaterials.Add(mtl);
                    }

                    multiMatsCount = Math.Max(mtl.NumSubMtls, 1);
                }

                babylonMesh.visibility = meshNode.GetVisibility(0, Tools.Forever);

                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.GetBoolProperty("babylonjs_optimizevertices");

                // Skin
                IISkinContextData skinContext = null;

                if (skin != null)
                {
                    skinContext = skin.GetContextInterface(meshNode);
                }

                // Compute normals
                VNormal[]             vnorms = Tools.ComputeNormals(mesh, optimizeVertices);
                List <GlobalVertex>[] verticesAlreadyExported = null;

                if (optimizeVertices)
                {
                    verticesAlreadyExported = new List <GlobalVertex> [mesh.NumVerts];
                }

                for (var face = 0; face < mesh.NumFaces; face++)
                {
                    indices.Add(CreateGlobalVertex(mesh, face, vx1, vertices, hasUV, hasUV2, vnorms, verticesAlreadyExported, skinContext));
                    indices.Add(CreateGlobalVertex(mesh, face, vx2, vertices, hasUV, hasUV2, vnorms, verticesAlreadyExported, skinContext));
                    indices.Add(CreateGlobalVertex(mesh, 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), 2);

                    if (!optimizeVertices)
                    {
                        RaiseError("You can try to optimize your object using [Try to optimize vertices] option", 2);
                    }
                }

                RaiseMessage(string.Format("{0} vertices, {1} faces", vertices.Count, indices.Count / 3), 2);

                // 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();

                triObject.Dispose();
            }

            // Instances
            var tabs = Loader.Global.NodeTab.Create();

            Loader.Global.IInstanceMgr.InstanceMgr.GetInstances(meshNode, tabs);
            var instances = new List <BabylonAbstractMesh>();

            for (var index = 0; index < tabs.Count; index++)
            {
                var indexer = new IntPtr(index);
                var tab     = tabs[indexer];

                Marshal.FreeHGlobal(indexer);

                if (meshNode.GetGuid() == tab.GetGuid())
                {
                    continue;
                }

                tab.MarkAsInstance();

                var instance = new BabylonAbstractMesh {
                    name = tab.Name
                };

                Tools.ExtractCoordinates(tab, instance, exportQuaternionsInsteadOfEulers);
                var instanceAnimations = new List <BabylonAnimation>();
                GenerateCoordinatesAnimations(tab, instanceAnimations);
                instance.animations = instanceAnimations.ToArray();

                instances.Add(instance);
            }

            babylonMesh.instances = instances.ToArray();

            // Animations
            var animations = new List <BabylonAnimation>();

            GenerateCoordinatesAnimations(meshNode, animations);


            if (!ExportFloatController(meshNode.VisController, "visibility", animations))
            {
                ExportFloatAnimation("visibility", animations, key => new[] { meshNode.GetVisibility(key, Tools.Forever) });
            }

            babylonMesh.animations = animations.ToArray();

            if (meshNode.GetBoolProperty("babylonjs_autoanimate", 1))
            {
                babylonMesh.autoAnimate     = true;
                babylonMesh.autoAnimateFrom = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_from");
                babylonMesh.autoAnimateTo   = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_to", 100);
                babylonMesh.autoAnimateLoop = meshNode.GetBoolProperty("babylonjs_autoanimateloop", 1);
            }

            babylonScene.MeshesList.Add(babylonMesh);
        }
Esempio n. 6
0
        public static void ComputeVertexData(IMesh _mMesh, IISkinContextData _skin, Semantic _semantic, string _filepath)
        {
            Dictionary<int, VertexUndivided> verticesFullData = new Dictionary<int, VertexUndivided>();
            List<FaceData> facesFullData = new List<FaceData>();
            List<List<VertexDivided>> verticesParsedData = new List<List<VertexDivided>>();

            IList<IFace> faces = _mMesh.Faces;
            IList<ITVFace> Tfaces = _mMesh.TvFace;
            IList<IPoint3> vertices = _mMesh.Verts;
            IList<IPoint3> Tvertices = _mMesh.TVerts;

            /*
            foreach (IPoint3 _v in vertices)
            {
                float temp = _v.Y;
                _v.Y = -_v.Z;
                _v.Z = temp;
            }
            */
            for (int _fID = 0; _fID < faces.Count; _fID++)
            {
                FaceData _face = new FaceData((int)faces[_fID].SmGroup);

                // vectors are inverted to make up for max being clockwise
                Vector3 A_B = vertices[(int)faces[_fID].GetVert(1)].convertToVector3() - vertices[(int)faces[_fID].GetVert(0)].convertToVector3();
                Vector3 A_C = vertices[(int)faces[_fID].GetVert(2)].convertToVector3() - vertices[(int)faces[_fID].GetVert(0)].convertToVector3();
                Vector3 U = Tvertices[(int)Tfaces[_fID].GetTVert(1)].convertToVector3() - Tvertices[(int)Tfaces[_fID].GetTVert(0)].convertToVector3();
                Vector3 V = Tvertices[(int)Tfaces[_fID].GetTVert(2)].convertToVector3() - Tvertices[(int)Tfaces[_fID].GetTVert(0)].convertToVector3();

                Vector3 normUnsure = Vector3.Cross(A_B, A_C);
                normUnsure.Normalize();

                float area = U.X * V.Y - U.Y * V.X;
                int sign = area < 0 ? -1 : 1;
                Vector3 tangent = new Vector3(0, 0, 1);
                tangent.X = A_B.X * V.Y - U.Y * A_C.X;
                tangent.Y = A_B.Y * V.Y - U.Y * A_C.Y;
                tangent.Z = A_B.Z * V.Y - U.Y * A_C.Z;
                tangent.Normalize();
                tangent *= sign;

                for (int i = 0; i < 3; i++)
                {
                    _face.vertices.Add((int)faces[_fID].GetVert(i));

                    if (verticesFullData.ContainsKey((int)faces[_fID].GetVert(i)))
                    {
                        VertexUndivided _v = verticesFullData[(int)faces[_fID].GetVert(i)];
                        _v.faceInfo.Add(new PerFaceInfo(_fID, (int)faces[_fID].SmGroup, (Tvertices[(int)Tfaces[_fID].GetTVert(i)]).convertToVector2(), normUnsure, tangent));
                    }
                    else
                    {
                        VertexUndivided _v = new VertexUndivided();
                        _v.ID = faces[_fID].GetVert(i);
                        int nbBonesA=_skin.GetNumAssignedBones((int)_v.ID);
                        List<int> bonesID = new List<int>();
                        List<float> bonesWeights = new List<float>();
                        for (int b = 0; b < 4; b++)
                        {
                            if(nbBonesA<b+1)
                            {
                                bonesID.Add(0);
                                bonesWeights.Add(0);
                            }
                            else
                            {
                                bonesID.Add(_skin.GetAssignedBone((int)_v.ID, b));
                                bonesWeights.Add(_skin.GetBoneWeight((int)_v.ID, b));
                            }
                        }
                        _v.bonesID = new ROD_core.BoneIndices(bonesID[0], bonesID[1], bonesID[2], bonesID[3]);
                        _v.bonesWeights = new Vector4(bonesWeights[0], bonesWeights[1], bonesWeights[2], bonesWeights[3]);
                        _v.pos = (vertices[(int)_v.ID]).convertToVector3();
                        _v.faceInfo.Add(new PerFaceInfo(_fID, (int)faces[_fID].SmGroup, (Tvertices[(int)Tfaces[_fID].GetTVert(i)]).convertToVector2(), normUnsure, tangent));
                        verticesFullData.Add((int)faces[_fID].GetVert(i), _v);
                    }
                }

                facesFullData.Add(_face);
            }
            List<int> IndexBuffer = new List<int>();
            List<VertexDivided> VertexBuffer = new List<VertexDivided>();
            // vertex index in vertexfullData "undivided" et sa valeur en fonction du SMG
            Dictionary<int, Dictionary<int, int>> VertexDictionary = new Dictionary<int, Dictionary<int, int>>();

            Mesh mesh = new Mesh();

            for (int _faceID = 0; _faceID < facesFullData.Count; _faceID++)
            {
                facesFullData[_faceID].vertices.Reverse();
                foreach (int _vertex in facesFullData[_faceID].vertices)
                {
                    Dictionary<int, int> vertexTranslation;
                    int _vID = (int)verticesFullData[_vertex].ID;
                    List<PerFaceInfo> unitedVertex = verticesFullData[_vertex].faceInfo.Where(x => x.SMG == facesFullData[_faceID].SMG).ToList();
                    if (!VertexDictionary.ContainsKey(_vID))
                    {
                        VertexDictionary.Add(_vID, new Dictionary<int, int>());
                    }
                    vertexTranslation = VertexDictionary[_vID];
                    VertexDivided _newVertex = new VertexDivided();
                    _newVertex.pos = verticesFullData[_vertex].pos;

                    _newVertex.UV.X = verticesFullData[_vertex].faceInfo.Where(x => x.ID == _faceID).FirstOrDefault().UV.X;
                    _newVertex.UV.Y = 1 - verticesFullData[_vertex].faceInfo.Where(x => x.ID == _faceID).FirstOrDefault().UV.Y;
                    Vector3 _normal_aggreagate = new Vector3(0, 0, 0);
                    Vector3 _tangent_aggreagate = new Vector3(0, 0, 0);
                    foreach (PerFaceInfo _FI in unitedVertex)
                    {
                        _normal_aggreagate += _FI.normal;
                        _tangent_aggreagate += _FI.tangent;
                    }
                    _normal_aggreagate.Normalize();
                    _tangent_aggreagate.Normalize();
                    _newVertex.normal = _normal_aggreagate;
                    _newVertex.tangent = _tangent_aggreagate;
                    _newVertex.binormal = Vector3.Cross(_normal_aggreagate, _tangent_aggreagate);
                    _newVertex.bonesID = verticesFullData[_vertex].bonesID;
                    _newVertex.bonesWeights = verticesFullData[_vertex].bonesWeights;
                    IndexBuffer.Add(VertexBuffer.Count);
                    VertexBuffer.Add(_newVertex);
                }
            }
            mesh._indexStream = new IndexStream(IndexBuffer.Count, typeof(UInt16), true, true);
            mesh._vertexStream = new VertexStream(VertexBuffer.Count, true, true, _semantic);
            foreach (int id in IndexBuffer)
            {

                UInt16 _id = Convert.ToUInt16(id);
                VertexDivided res = VertexBuffer[_id];
                mesh._indexStream.WriteIndex(_id);
            }
            Type dv = DynamicVertex.CreateVertex(_semantic);
            FieldInfo[] PI = dv.GetFields();

            foreach (VertexDivided vd in VertexBuffer)
            {
                if (mesh._boundingBox.Minimum == null)
                {
                    mesh._boundingBox.Minimum = new Vector3(vd.pos.X, vd.pos.Y, vd.pos.Z);
                    mesh._boundingBox.Maximum = new Vector3(vd.pos.X, vd.pos.Y, vd.pos.Z);
                }
                mesh._boundingBox.Minimum.X = Math.Min(mesh._boundingBox.Minimum.X, vd.pos.X);
                mesh._boundingBox.Minimum.Y = Math.Min(mesh._boundingBox.Minimum.Y, vd.pos.Y);
                mesh._boundingBox.Minimum.Z = Math.Min(mesh._boundingBox.Minimum.Z, vd.pos.Z);
                mesh._boundingBox.Maximum.X = Math.Max(mesh._boundingBox.Maximum.X, vd.pos.X);
                mesh._boundingBox.Maximum.Y = Math.Max(mesh._boundingBox.Maximum.Y, vd.pos.Y);
                mesh._boundingBox.Maximum.Z = Math.Max(mesh._boundingBox.Maximum.Z, vd.pos.Z);
                List<object> vertexData = new List<object>();
                for (int i = 0; i < PI.Length; i++)
                {
                    string fieldSemantic = ((InputElementAttribute)PI[i].GetCustomAttributes(true).First()).Semantic;
                    vertexData.Add(vd.GetSemanticObject(fieldSemantic));
                }
                object[] obj = vertexData.ToArray();
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV, vd.binormal, vd.bonesID, vd.bonesWeights, vd.tangent };
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV, vd.binormal, vd.tangent };
                //object[] obj = new object[] { vd.pos, vd.normal, vd.UV};
                mesh._vertexStream.WriteVertex(obj);
            }
            Mesh.saveToFile(mesh, _filepath);
        }