Exemplo n.º 1
0
        void AddFacesFromPolyList(polylist list, mesh mesh, ModelPrim prim, Matrix4 transform)
        {
            string material = list.material;
            source posSrc = null;
            source normalSrc = null;
            source uvSrc = null;

            ulong stride = 0;
            int posOffset = -1;
            int norOffset = -1;
            int uvOffset = -1;

            foreach (var inp in list.input)
            {
                stride = Math.Max(stride, inp.offset);

                if (inp.semantic == "VERTEX")
                {
                    posSrc = FindSource(mesh.source, mesh.vertices.input[0].source);
                    posOffset = (int)inp.offset;
                }
                else if (inp.semantic == "NORMAL")
                {
                    normalSrc = FindSource(mesh.source, inp.source);
                    norOffset = (int)inp.offset;
                }
                else if (inp.semantic == "TEXCOORD")
                {
                    uvSrc = FindSource(mesh.source, inp.source);
                    uvOffset = (int)inp.offset;
                }
            }

            stride += 1;

            if (posSrc == null) return;

            var vcount = StrToArray(list.vcount);
            var idx = StrToArray(list.p);

            Vector3[] normals = null;
            if (normalSrc != null)
            {
                var norVal = ((float_array)normalSrc.Item).Values;
                normals = new Vector3[norVal.Length / 3];

                for (int i = 0; i < normals.Length; i++)
                {
                    normals[i] = new Vector3((float)norVal[i * 3 + 0], (float)norVal[i * 3 + 1], (float)norVal[i * 3 + 2]);
                    normals[i] = Vector3.TransformNormal(normals[i], transform);
                    normals[i].Normalize();
                }
            }

            Vector2[] uvs = null;
            if (uvSrc != null)
            {
                var uvVal = ((float_array)uvSrc.Item).Values;
                uvs = new Vector2[uvVal.Length / 2];

                for (int i = 0; i < uvs.Length; i++)
                {
                    uvs[i] = new Vector2((float)uvVal[i * 2 + 0], (float)uvVal[i * 2 + 1]);
                }

            }

            ModelFace face = new ModelFace();
            face.MaterialID = list.material;
            if (face.MaterialID != null)
            {
                if (MatSymTarget.ContainsKey(list.material))
                {
                    ModelMaterial mat = Materials.Find(m => m.ID == MatSymTarget[list.material]);
                    if (mat != null)
                    {
                        face.Material = mat;
                    }
                }
            }

            int curIdx = 0;

            for (int i = 0; i < vcount.Length; i++)
            {
                var nvert = vcount[i];
                if (nvert < 3 || nvert > 4)
                {
                    throw new InvalidDataException("Only triangles and quads supported");
                }

                Vertex[] verts = new Vertex[nvert];
                for (int j = 0; j < nvert; j++)
                {
                    verts[j].Position = prim.Positions[idx[curIdx + posOffset + (int)stride * j]];

                    if (normals != null)
                    {
                        verts[j].Normal = normals[idx[curIdx + norOffset + (int)stride * j]];
                    }

                    if (uvs != null)
                    {
                        verts[j].TexCoord = uvs[idx[curIdx + uvOffset + (int)stride * j]];
                    }
                }


                if (nvert == 3) // add the triangle
                {
                    face.AddVertex(verts[0]);
                    face.AddVertex(verts[1]);
                    face.AddVertex(verts[2]);
                }
                else if (nvert == 4) // quad, add two triangles
                {
                    face.AddVertex(verts[0]);
                    face.AddVertex(verts[1]);
                    face.AddVertex(verts[2]);

                    face.AddVertex(verts[0]);
                    face.AddVertex(verts[2]);
                    face.AddVertex(verts[3]);
                }

                curIdx += (int)stride * nvert;
            }

            prim.Faces.Add(face);


        }
Exemplo n.º 2
0
        void AddPositions(mesh mesh, ModelPrim prim, Matrix4 transform)
        {
            prim.Positions = new List<Vector3>();
            source posSrc = FindSource(mesh.source, mesh.vertices.input[0].source);
            double[] posVals = ((float_array)posSrc.Item).Values;

            for (int i = 0; i < posVals.Length / 3; i++)
            {
                Vector3 pos = new Vector3((float)posVals[i * 3], (float)posVals[i * 3 + 1], (float)posVals[i * 3 + 2]);
                pos = Vector3.Transform(pos, transform);
                prim.Positions.Add(pos);
            }

            prim.BoundMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            prim.BoundMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);

            foreach (var pos in prim.Positions)
            {
                if (pos.X > prim.BoundMax.X) prim.BoundMax.X = pos.X;
                if (pos.Y > prim.BoundMax.Y) prim.BoundMax.Y = pos.Y;
                if (pos.Z > prim.BoundMax.Z) prim.BoundMax.Z = pos.Z;

                if (pos.X < prim.BoundMin.X) prim.BoundMin.X = pos.X;
                if (pos.Y < prim.BoundMin.Y) prim.BoundMin.Y = pos.Y;
                if (pos.Z < prim.BoundMin.Z) prim.BoundMin.Z = pos.Z;
            }

            prim.Scale = prim.BoundMax - prim.BoundMin;
            prim.Position = prim.BoundMin + (prim.Scale / 2);

            // Fit vertex positions into identity cube -0.5 .. 0.5
            for (int i = 0; i < prim.Positions.Count; i++)
            {
                Vector3 pos = prim.Positions[i];
                pos = new Vector3(
                    prim.Scale.X == 0 ? 0 : ((pos.X - prim.BoundMin.X) / prim.Scale.X) - 0.5f,
                    prim.Scale.Y == 0 ? 0 : ((pos.Y - prim.BoundMin.Y) / prim.Scale.Y) - 0.5f,
                    prim.Scale.Z == 0 ? 0 : ((pos.Z - prim.BoundMin.Z) / prim.Scale.Z) - 0.5f
                    );
                prim.Positions[i] = pos;
            }

        }