Пример #1
0
        public bool AreTrianglesAdjacent(DTriangle t1, DTriangle t2)
        {
            int match_verts = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if ((vertex[t1.vert[i]] - vertex[t2.vert[j]]).LengthSquared <= MATCH_DIST_SQ)
                    {
                        match_verts += 1;
                    }
                }
            }

            if (match_verts >= 2)
            {
                Vector3 n1 = Utility.FindNormal(vertex[t1.vert[0]], vertex[t1.vert[1]], vertex[t1.vert[2]]);
                Vector3 n2 = Utility.FindNormal(vertex[t2.vert[0]], vertex[t2.vert[1]], vertex[t2.vert[2]]);

                if (Vector3.Dot(n1, n2) > MATCH_NORMAL)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        public List <DTriangle> DeconvertPoly()
        {
            // Triange for each vert beyond 2 (0-1-2, 0-2-3, 0-3-4, etc)
            List <DTriangle> tri_list = new List <DTriangle>();

            int[]     vrt  = new int[3];
            Vector3[] nrml = new Vector3[3];
            Vector2[] uv   = new Vector2[3];
            for (int i = 0; i < num_verts - 2; i++)
            {
                vrt[0]  = vert[0];
                vrt[1]  = vert[i + 1];
                vrt[2]  = vert[i + 2];
                nrml[0] = normal[0];
                nrml[1] = normal[i + 1];
                nrml[2] = normal[i + 2];
                uv[0]   = tex_uv[0];
                uv[1]   = tex_uv[i + 1];
                uv[2]   = tex_uv[i + 2];

                DTriangle dtri = new DTriangle(vrt, nrml, uv, tex_index);
                dtri.poly_num = num;
                dtri.flags    = flags;
                smoothing     = 0;
                tri_list.Add(dtri);
            }

            return(tri_list);
        }
Пример #3
0
		public void CreateTriangle(DTriangle tri, DMesh mesh)
		{
			for (int i = 0; i < 3; i++) {
				GL.TexCoord2(tri.tex_uv[i]);
				GL.Normal3(tri.normal[i]);
				GL.Vertex3(mesh.vertex[tri.vert[i]]);
			}
		}
 public void CreateLinesFromVertNormals(DTriangle tri, DMesh mesh)
 {
     GL.Vertex3(mesh.vertex[tri.vert[0]]);
     GL.Vertex3(mesh.vertex[tri.vert[0]] + tri.normal[0] * 0.1f);
     GL.Vertex3(mesh.vertex[tri.vert[1]]);
     GL.Vertex3(mesh.vertex[tri.vert[1]] + tri.normal[1] * 0.1f);
     GL.Vertex3(mesh.vertex[tri.vert[2]]);
     GL.Vertex3(mesh.vertex[tri.vert[2]] + tri.normal[2] * 0.1f);
 }
 public void CreateLinesFromTriangle(DTriangle tri, DMesh mesh)
 {
     GL.Vertex3(mesh.vertex[tri.vert[0]]);
     GL.Vertex3(mesh.vertex[tri.vert[1]]);
     GL.Vertex3(mesh.vertex[tri.vert[1]]);
     GL.Vertex3(mesh.vertex[tri.vert[2]]);
     GL.Vertex3(mesh.vertex[tri.vert[2]]);
     GL.Vertex3(mesh.vertex[tri.vert[0]]);
 }
Пример #6
0
        public void ReverseWindingOrder()
        {
            DTriangle flip_tri = new DTriangle(this, 0);

            for (int i = 0; i < 3; i++)
            {
                vert[i]   = flip_tri.vert[2 - i];
                normal[i] = flip_tri.normal[2 - i];
                tex_uv[i] = flip_tri.tex_uv[2 - i];
            }
        }
Пример #7
0
        public void CreateGMTriangle(DTriangle tri, GMesh mesh)
        {
            Vector3 normal = Utility.FindNormal(mesh.m_vertex[tri.vert[0]], mesh.m_vertex[tri.vert[1]], mesh.m_vertex[tri.vert[2]]);

            for (int i = 0; i < 3; i++)
            {
                GL.TexCoord2(tri.tex_uv[i]);
                //GL.Normal3(tri.normal[i]);
                GL.Normal3(normal);
                GL.Vertex3(mesh.m_vertex[tri.vert[i]]);
            }
        }
Пример #8
0
        public DTriangle(DTriangle src, int vert_idx_offset)
        {
            for (int i = 0; i < 3; i++)
            {
                vert[i]   = src.vert[i] + vert_idx_offset;
                normal[i] = src.normal[i];
                tex_uv[i] = src.tex_uv[i];
            }

            tex_index = src.tex_index;
            flags     = src.flags;
        }
Пример #9
0
 public DPoly(DTriangle dtri)
 {
     num_verts = 3;
     flags     = dtri.flags;
     smoothing = 0;
     ClearLists();
     for (int i = 0; i < num_verts; i++)
     {
         vert.Add(dtri.vert[i]);
         normal.Add(dtri.normal[i]);
         tex_uv.Add(dtri.tex_uv[i]);
         tex_index = dtri.tex_index;
     }
 }
        public void AddFaceFromCTriangle(CTriangle ct)
        {
            int start_vrt = m_vertex.Count;

            for (int i = 0; i < 3; i++)
            {
                m_vertex.Add(ct.original_verts[i].Position);
            }

            bool      use_clipped_data = false;
            DTriangle tri = new DTriangle(ct, start_vrt, 0, use_clipped_data);

            m_triangle.Add(tri);
        }
        public void AddGeometry(DMesh dm, Vector3 offset)
        {
            // Currently, this creates the geometry in World space
            Matrix4 full_rotation = Matrix4.Mult(Matrix4.CreateRotationX(-Utility.RAD_90), m_base_rot);

            // Build up the transform to use for the normals
            // Note: Invert directions because the uvec was setup for texture V coordinates
            Matrix4 normal_full_rotation = new Matrix4();

            normal_full_rotation.M11 = -m_base_rvec.X;
            normal_full_rotation.M12 = -m_base_rvec.Y;
            normal_full_rotation.M13 = -m_base_rvec.Z;
            normal_full_rotation.M14 = 0.0f;
            normal_full_rotation.M21 = m_base_uvec.X;
            normal_full_rotation.M22 = m_base_uvec.Y;
            normal_full_rotation.M23 = m_base_uvec.Z;
            normal_full_rotation.M24 = 0.0f;
            normal_full_rotation.M31 = -m_base_normal.X;
            normal_full_rotation.M32 = -m_base_normal.Y;
            normal_full_rotation.M33 = -m_base_normal.Z;
            normal_full_rotation.M34 = 0.0f;
            normal_full_rotation.M41 = 0.0f;
            normal_full_rotation.M42 = 0.0f;
            normal_full_rotation.M43 = 0.0f;
            normal_full_rotation.M44 = 1.0f;
            normal_full_rotation     = Matrix4.CreateRotationX(-Utility.RAD_90) * normal_full_rotation;

            int vert_idx_offset = m_vertex.Count;

            for (int i = 0; i < dm.vertex.Count; i++)
            {
                Vector3 rot_pos = Vector3.Transform(dm.vertex[i], full_rotation);
                m_vertex.Add(rot_pos + offset);
            }

            for (int i = 0; i < dm.triangle.Count; i++)
            {
                DTriangle d_tri = new DTriangle(dm.triangle[i], vert_idx_offset);

                for (int v = 0; v < 3; ++v)
                {
                    d_tri.normal[v] = OpenTK.Vector3.Transform(d_tri.normal[v], normal_full_rotation);
                }

                m_triangle.Add(d_tri);
            }
        }
Пример #12
0
        public void Copy(DMesh src, bool ignore_light = false)
        {
            name  = src.name;
            flags = src.flags;
            for (int i = 0; i < src.vertex.Count; i++)
            {
                vertex.Add(src.vertex[i]);
            }
            for (int i = 0; i < src.triangle.Count; i++)
            {
                DTriangle dtri = new DTriangle(src.triangle[i], 0);
                triangle.Add(dtri);
            }
            CopyExtraProperties(src);

            for (int i = 0; i < src.tex_name.Count; i++)
            {
                tex_name.Add(src.tex_name[i]);
#if OVERLOAD_LEVEL_EDITOR
                m_tex_gl_id.Add(src.m_tex_gl_id[i]);
#endif
            }
            if (!ignore_light)
            {
                light.Clear();
                for (int i = 0; i < src.light.Count; i++)
                {
                    DLight dl = new DLight(src.light[i]);
                    light.Add(dl);
                }
                color.Clear();
                for (int i = 0; i < src.color.Count; i++)
                {
                    color.Add(src.color[i]);
                }
            }
        }
        // Assumes the face has 3 verts
        public void AddFace(int[] vrt_idx, Vector3[] nrml, Vector2[] uv, int tex_idx)
        {
            DTriangle tri = new DTriangle(vrt_idx, nrml, uv, tex_idx);

            m_triangle.Add(tri);
        }
Пример #14
0
        public static bool CheckAndCleanMeshIssues(ref List <DTriangle> triangle, List <Vector3> vertex, bool removeSmallInvalidTriangles, out string issues)
        {
            const float  kLengthEpsilon         = 0.0001f;
            const float  kDotEpsilon            = 0.99999f;
            const double kUVEpsilon             = 0.000001;
            const double kMaxAreaForAutoRemoval = 0.0003;

            Vector3[] verts = new Vector3[3];

            bool result = false;

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            List <BadTriangle> badTriangleIndices = new List <BadTriangle>();

            foreach (int triIdx in Enumerable.Range(0, triangle.Count))
            {
                var tri = triangle[triIdx];
                if (tri.vert.Length != 3)
                {
                    builder.AppendFormat("-- Polygon is not 3 verts\n");
                    result = true;
                    badTriangleIndices.Add(new BadTriangle()
                    {
                        index = triIdx, reason = BadTriangleReason.ZeroArea
                    });
                    continue;
                }

                for (int i = 0; i < 3; ++i)
                {
                    verts[i] = vertex[tri.vert[i]];
                }

                Vector3 edge0 = verts[0] - verts[1];
                Vector3 edge1 = verts[2] - verts[1];
                Vector3 edge2 = verts[0] - verts[2];

                bool isZeroAreaTriangle = false;
                bool isBadUVTriangle    = false;

                if (edge0.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge0 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }
                if (edge1.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge1 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }
                if (edge2.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge2 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }

                if (!isZeroAreaTriangle)
                {
                    float edge_dot = Math.Abs(Vector3.Dot(edge0.Normalized(), edge1.Normalized()));
                    if (edge_dot >= kDotEpsilon)
                    {
                        builder.AppendFormat("-- triangle has no area {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString());
                        isZeroAreaTriangle = true;
                    }
                }

                // Check UVs to make sure there is a gradient
                Vector2 w1 = tri.tex_uv[0];
                Vector2 w2 = tri.tex_uv[1];
                Vector2 w3 = tri.tex_uv[2];
                double  s1 = w2.X - w1.X;
                double  s2 = w3.X - w1.X;
                double  t1 = w2.Y - w1.Y;
                double  t2 = w3.Y - w1.Y;

                double den = (s1 * t2 - s2 * t1);
                if (Math.Abs(den) <= kUVEpsilon)
                {
                    double area = CalculateTriangleArea(edge0, edge1, edge2);
                    if (area <= kMaxAreaForAutoRemoval)
                    {
                        builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (REMOVING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area);
                        isZeroAreaTriangle = true;
                    }
                    else
                    {
                        builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (FIXING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area);
                        isBadUVTriangle = true;
                    }
                }

                if (isZeroAreaTriangle)
                {
                    result = true;

                    // Calculate the area of the triangle
                    double triangleArea = CalculateTriangleArea(edge0, edge1, edge2);
                    if (triangleArea < kMaxAreaForAutoRemoval)
                    {
                        badTriangleIndices.Add(new BadTriangle()
                        {
                            index = triIdx, reason = BadTriangleReason.ZeroArea
                        });
                    }
                }
                else if (isBadUVTriangle)
                {
                    result = true;
                    badTriangleIndices.Add(new BadTriangle()
                    {
                        index = triIdx, reason = BadTriangleReason.BadUV
                    });
                }
            }

            if (removeSmallInvalidTriangles && badTriangleIndices.Count > 0)
            {
                List <DTriangle> newTriangles = new List <DTriangle>();
                int numRemoved = 0;

                int numBadTriangles = badTriangleIndices.Count;
                int badIndex        = 0;
                foreach (int srcTriIndex in Enumerable.Range(0, triangle.Count))
                {
                    if (badIndex < numBadTriangles && badTriangleIndices[badIndex].index == srcTriIndex)
                    {
                        bool skipThis = false;
                        switch (badTriangleIndices[badIndex++].reason)
                        {
                        case BadTriangleReason.ZeroArea: {
                            skipThis = true;
                        }
                        break;

                        case BadTriangleReason.BadUV: {
                            DTriangle tri = triangle[srcTriIndex];
                            tri.tex_uv[1] = tri.tex_uv[1] + new Vector2(0.1f, 0.1f);
                            tri.tex_uv[2] = tri.tex_uv[2] - new Vector2(0.1f, 0.1f);
                        }
                        break;
                        }
                        if (skipThis)
                        {
                            ++numRemoved;
                            continue;
                        }
                    }

                    newTriangles.Add(triangle[srcTriIndex]);
                }

                triangle = newTriangles;
                builder.AppendFormat("Removed {0} triangles\n", numRemoved);
            }

            issues = builder.ToString();

            return(result);
        }
Пример #15
0
        public void Deserialize(JObject root)
        {
            vertex.Clear();
            triangle.Clear();
#if OVERLOAD_LEVEL_EDITOR
            m_tex_gl_id.Clear();
#endif
            tex_name.Clear();

            Vector3 vec     = Vector3.Zero;
            JArray  j_verts = root["verts"].GetArray();
            foreach (JObject j_vert in j_verts)
            {
                vec.X = j_vert["x"].GetFloat(0.0f);
                vec.Y = j_vert["y"].GetFloat(0.0f);
                vec.Z = j_vert["z"].GetFloat(0.0f);
                vertex.Add(vec);
            }

#if OVERLOAD_LEVEL_EDITOR
            DeserializePolys(root);
#endif

            JObject j_tris = root["triangles"].GetObject();
            foreach (var kvp in j_tris)
            {
                JObject   j_tri = kvp.Value.GetObject();
                DTriangle d_tri = new DTriangle(j_tri);
                triangle.Add(d_tri);
            }

            JArray j_tex_names = root["tex_names"].GetArray();
            for (int i = 0; i < j_tex_names.Count; i++)
            {
#if OVERLOAD_LEVEL_EDITOR
                m_tex_gl_id.Add(-1);
#endif
                tex_name.Add(j_tex_names[i].GetString(""));
            }

            JObject j_lights = root["lights"].GetObject();
            if (j_lights.Count > 0)
            {
                light.Clear();
            }
            int count = 0;
            foreach (var kvp in j_lights)
            {
                JObject j_light = kvp.Value.GetObject();
                DLight  d_light = new DLight(j_light);
                if (count < 4)
                {
                    light.Add(d_light);
                    count += 1;
                }
            }

            int cr, cg, cb;
            count = 0;
            JArray j_colors = root["colors"].GetArray();
            if (j_colors.Count > 0)
            {
                color.Clear();
            }
            foreach (JObject j_color in j_colors)
            {
#if OVERLOAD_LEVEL_EDITOR
                cr = j_color["r"].GetInt(255);
                cg = j_color["g"].GetInt(255);
                cb = j_color["b"].GetInt(255);
                if (count < 4)
                {
                    color.Add(Color.FromArgb(cr, cg, cb));
                }
                count += 1;
#else
                cr = j_color["r"].GetInt(255);
                cg = j_color["g"].GetInt(255);
                cb = j_color["b"].GetInt(255);
                color.Add(new Vector3((float)cr / 255.0f, (float)cg / 255.0f, (float)cb / 255.0f));
#endif
            }

#if OVERLOAD_LEVEL_EDITOR
            for (int i = color.Count; i < NUM_COLORS; i++)
            {
                color.Add(Color.White);
            }
#endif

            smooth_angle_same = root["smooth_same"].GetInt(smooth_angle_same);
            smooth_angle_diff = root["smooth_diff"].GetInt(smooth_angle_diff);
        }