Beispiel #1
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);
        }
Beispiel #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);
        }