/// <summary> /// Agrega un nuevo vertice a la lista si es que ya no hay otro igual. /// Devuelve el indice del nuevo vertice o del que ya estaba. /// </summary> public static int addVertexToListIfUnique(List<EditPolyVertex> vertices, EditPolyVertex v) { for (int i = 0; i < vertices.Count; i++) { if (EditablePolyUtils.sameVextex(vertices[i], v)) { return i; } } v.vbIndex = vertices.Count; v.edges = new List<EditPolyEdge>(); vertices.Add(v); return v.vbIndex; }
/// <summary> /// Obtener la lista de vertices originales del mesh /// </summary> private List<EditPolyVertex> getMeshOriginalVertexData(TgcMesh origMesh) { List<EditPolyVertex> origVertices = new List<EditPolyVertex>(); switch (origMesh.RenderType) { case TgcMesh.MeshRenderType.VERTEX_COLOR: TgcSceneLoader.VertexColorVertex[] verts1 = (TgcSceneLoader.VertexColorVertex[])origMesh.D3dMesh.LockVertexBuffer( typeof(TgcSceneLoader.VertexColorVertex), LockFlags.ReadOnly, origMesh.D3dMesh.NumberVertices); for (int i = 0; i < verts1.Length; i++) { EditPolyVertex v = new EditPolyVertex(); v.position = verts1[i].Position; /*v.normal = verts1[i].Normal; v.color = verts1[i].Color;*/ origVertices.Add(v); } origMesh.D3dMesh.UnlockVertexBuffer(); break; case TgcMesh.MeshRenderType.DIFFUSE_MAP: TgcSceneLoader.DiffuseMapVertex[] verts2 = (TgcSceneLoader.DiffuseMapVertex[])origMesh.D3dMesh.LockVertexBuffer( typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, origMesh.D3dMesh.NumberVertices); for (int i = 0; i < verts2.Length; i++) { EditPolyVertex v = new EditPolyVertex(); v.position = verts2[i].Position; /*v.normal = verts2[i].Normal; v.texCoords = new Vector2(verts2[i].Tu, verts2[i].Tv); v.color = verts2[i].Color;*/ origVertices.Add(v); } origMesh.D3dMesh.UnlockVertexBuffer(); break; case TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP: TgcSceneLoader.DiffuseMapAndLightmapVertex[] verts3 = (TgcSceneLoader.DiffuseMapAndLightmapVertex[])origMesh.D3dMesh.LockVertexBuffer( typeof(TgcSceneLoader.DiffuseMapAndLightmapVertex), LockFlags.ReadOnly, origMesh.D3dMesh.NumberVertices); for (int i = 0; i < verts3.Length; i++) { EditPolyVertex v = new EditPolyVertex(); v.position = verts3[i].Position; /*v.normal = verts3[i].Normal; v.texCoords = new Vector2(verts3[i].Tu0, verts3[i].Tv0); v.color = verts3[i].Color; v.texCoords2 = new Vector2(verts3[i].Tu1, verts3[i].Tv1);*/ origVertices.Add(v); } origMesh.D3dMesh.UnlockVertexBuffer(); break; } return origVertices; }
/// <summary> /// Eliminar un vertice /// </summary> private void deleteVertex(EditPolyVertex v) { //Quitar referencia de todas las aristas que lo usan foreach (EditPolyEdge edge in v.edges) { edge.a = null; edge.b = null; } //Eliminar aristas foreach (EditPolyEdge edge in v.edges) { deleteEdge(edge); } //Quitar vertice de lista de vertices vertices.RemoveAt(v.vbIndex); //Shift de vertex buffer for (int i = 0; i < vertices.Count; i++) { vertices[i].vbIndex = i; } //Ajustar indices en index buffer for (int i = 0; i < indexBuffer.Length; i++) { if (indexBuffer[i] >= v.vbIndex) { indexBuffer[i]--; } } }
/// <summary> /// Indica si dos vertices son iguales /// </summary> /// <returns></returns> public static bool sameVextex(EditPolyVertex a, EditPolyVertex b) { return equalsVector3(a.position, b.position); }
/* /// <summary> /// Filtrar todas las aristas que tiene un poligono y dejarle solo las que son parte del borde del poligono /// (Se quitan todas las aristas interiores) /// </summary> public static void computePolygonExternalEdges(Polygon p) { if (p.vertices.Count == 3) return; Vector3 planeNorm = p.getNormal(); List<Edge> externalEdges = new List<Edge>(); foreach (Edge e in p.edges) { //Half-plane entre la arista y la normal del poligono Vector3 vec = e.b.position - e.a.position; Vector3 n = Vector3.Cross(planeNorm, vec); Plane halfPlane = Plane.FromPointNormal(e.a.position, n); //Checkear el signo de todos los demas vertices del poligono bool first = true; TgcCollisionUtils.PointPlaneResult lastR = TgcCollisionUtils.PointPlaneResult.COINCIDENT; bool inside = false; foreach (Vertex v in p.vertices) { if(v.vbIndex != e.a.vbIndex && v.vbIndex != e.b.vbIndex ) { TgcCollisionUtils.PointPlaneResult r = TgcCollisionUtils.classifyPointPlane(v.position, halfPlane); if(first) { first = false; lastR = r; } else if(r != lastR) { inside = true; break; } } } if(!inside) { externalEdges.Add(e); } } p.edges = externalEdges; } /// <summary> /// Ordenar los vertices del poligono en base al recorrido de sus aristas externas /// </summary> public static void sortPolygonVertices(Polygon p) { if (p.vertices.Count == 3) return; List<Vertex> sortedVertices = new List<Vertex>(); Edge lastEdge = p.edges[0]; for (int i = 1; i < p.edges.Count; i++) { sortedVertices.Add(lastEdge.a); bool found = false; foreach (Edge e in p.edges) { if(lastEdge.b.vbIndex == e.a.vbIndex) { lastEdge = e; found = true; break; } } if(!found) throw new Exception("No se pudo recorrer aristas de poligono en loop. Poligono: " + p); } sortedVertices.Add(lastEdge.a); p.vertices = sortedVertices; } */ /// <summary> /// Agregar un vertice a un poligono existente, ubicandolo en el medio de los dos vertices de la arista que compartian entre si /// </summary> public static void addVertexToPolygon(EditPolyPolygon p, EditPolyEdge sharedEdge, EditPolyVertex newV) { for (int i = 0; i < p.vertices.Count; i++) { if (p.vertices[i].vbIndex == sharedEdge.a.vbIndex) { p.vertices.Add(null); for (int j = p.vertices.Count - 2; j >= i + 1 ; j--) { p.vertices[j + 1] = p.vertices[j]; } p.vertices[i + 1] = newV; break; } } }