123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- /****************************************************************************
- Copyright (c) 2013, Jonathan Cecil and UCLA Game Lab
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
- using UnityEngine;
- using System.Collections;
- /***
- * MC_SimpleSurfaceEdge
- * class to read pixel data and create outline edges around opaque pixel areas.
- *
- ***/
- class MC_SimpleSurfaceEdge {
- private const float versionNumber = 0.7f;
-
- Color[] pixels; // the original pixel data from the image
- int imageHeight;
- int imageWidth;
-
- ArrayList edges;
- ArrayList vertices;
- ArrayList edgeLoops;
-
- public MC_SimpleSurfaceEdge(Color[] _pixels, int _imageWidth, int _imageHeight, float threshold) {
- pixels = _pixels;
- imageWidth = _imageWidth;
- imageHeight = _imageHeight;
- edges = new ArrayList();
- vertices = new ArrayList();
- edgeLoops = new ArrayList();
-
- float uvWidth = (float)imageWidth;
- float uvHeight = (float)imageHeight;
-
- for (int x = 0; x < imageWidth; x++) {
- float uvX = x + 0.5f;
- for (int y = 0; y < imageHeight; y++) {
- float uvY = y+0.5f;
- // get the first pixel
- Color pixel = pixels[x + (imageWidth * y)];
- float pixelAlpha = pixel.a;
-
- // only continue if the current pixel is opaque
- if (pixelAlpha < threshold) continue;
-
- // set up values for other possible pixel values
- float pixelAboveAlpha = 0.0f;
- float pixelBelowAlpha = 0.0f;
- float pixelRightAlpha = 0.0f;
- float pixelLeftAlpha = 0.0f;
- float pixelAboveRightAlpha = 0.0f;
- float pixelAboveLeftAlpha = 0.0f;
- float pixelBelowRightAlpha = 0.0f;
-
- // check x area, then the y.
- if ( x > 0 && x < imageWidth-1) {
- if ( y > 0 && y < imageHeight -1 ) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- Color pixelAboveRight = pixels[x + 1 + (imageWidth * (y + 1))];
- pixelAboveRightAlpha = pixelAboveRight.a;
- Color pixelAboveLeft = pixels[x - 1 + (imageWidth * (y + 1))];
- pixelAboveLeftAlpha = pixelAboveLeft.a;
- Color pixelBelowRight = pixels[x + 1 + (imageWidth * (y - 1))];
- pixelBelowRightAlpha = pixelBelowRight.a;
- }
- else if ( y == 0) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- Color pixelAboveRight = pixels[x + 1 + (imageWidth * (y + 1))];
- pixelAboveRightAlpha = pixelAboveRight.a;
- Color pixelAboveLeft = pixels[x - 1 + (imageWidth * (y + 1))];
- pixelAboveLeftAlpha = pixelAboveLeft.a;
- }
- else if ( y == imageHeight -1 ) {
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- Color pixelBelowRight = pixels[x + 1 + (imageWidth * (y - 1))];
- pixelBelowRightAlpha = pixelBelowRight.a;
- }
- else {
- Debug.Log("SimpleSurfaceEdge:: error constructing pixel values, misinterpreted y values. Please create a new issue at https://github.com/uclagamelab/MeshCreator/issues.");
- }
- }
- else if ( x == 0 ) {
- if ( y > 0 && y < imageHeight - 1) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
-
- Color pixelAboveRight = pixels[x + 1 + (imageWidth * (y + 1))];
- pixelAboveRightAlpha = pixelAboveRight.a;
- Color pixelBelowRight = pixels[x + 1 + (imageWidth * (y - 1))];
- pixelBelowRightAlpha = pixelBelowRight.a;
- }
- else if ( y == 0) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
-
- Color pixelAboveRight = pixels[x + 1 + (imageWidth * (y + 1))];
- pixelAboveRightAlpha = pixelAboveRight.a;
- }
- else if ( y == imageHeight -1 ) {
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelRight = pixels[x + 1 + (imageWidth * y)];
- pixelRightAlpha = pixelRight.a;
-
- Color pixelBelowRight = pixels[x + 1 + (imageWidth * (y - 1))];
- pixelBelowRightAlpha = pixelBelowRight.a;
- }
- else {
- Debug.Log("SimpleSurfaceEdge:: error constructing pixel values, misinterpreted y values. Please create a new issue at https://github.com/uclagamelab/MeshCreator/issues.");
- }
-
- }
- else if ( x == imageWidth -1 ) {
- if ( y > 0 && y < imageHeight -1 ) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- Color pixelAboveLeft = pixels[x - 1 + (imageWidth * (y + 1))];
- pixelAboveLeftAlpha = pixelAboveLeft.a;
- }
- else if ( y == 0) {
- Color pixelAbove = pixels[x + (imageWidth * (y+1))];
- pixelAboveAlpha = pixelAbove.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- Color pixelAboveLeft = pixels[x - 1 + (imageWidth * (y + 1))];
- pixelAboveLeftAlpha = pixelAboveLeft.a;
- }
- else if ( y == imageHeight -1 ) {
- Color pixelBelow = pixels[x + (imageWidth * (y-1))];
- pixelBelowAlpha = pixelBelow.a;
- Color pixelLeft = pixels[x - 1 + (imageWidth * y)];
- pixelLeftAlpha = pixelLeft.a;
-
- }
- else {
- Debug.Log("SimpleSurfaceEdge:: error constructing pixel values, misinterpreted y values. Please create a new issue at https://github.com/uclagamelab/MeshCreator/issues.");
- }
- }
-
- // try the up facing case
- if (pixelAlpha >= threshold && pixelAboveAlpha >= threshold) {
- if (pixelAboveRightAlpha < threshold && pixelRightAlpha < threshold) {
- if (pixelAboveLeftAlpha >= threshold || pixelLeftAlpha >= threshold) {
- // add the vertical edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x,y+1,uvX/uvWidth,(uvY+1)/uvHeight));
- edges.Add(e);
- }
- }
- else if ( pixelAboveLeftAlpha < threshold && pixelLeftAlpha < threshold) {
- if (pixelAboveRightAlpha >= threshold || pixelRightAlpha >= threshold) {
- // add the vertical edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x,y+1,uvX/uvWidth,(uvY+1)/uvHeight));
- edges.Add(e);
- }
- }
- }
-
- // try the up diagonal case
- if (pixelAlpha >= threshold && pixelAboveRightAlpha >= threshold) {
- if (pixelAboveAlpha < threshold && pixelRightAlpha >= threshold) {
- // add the up diagonal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y+1,(uvX+1)/uvWidth,(uvY+1)/uvHeight));
- edges.Add(e);
- }
- else if (pixelAboveAlpha >= threshold && pixelRightAlpha < threshold) {
- // add the up diagonal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y+1,(uvX+1)/uvWidth,(uvY+1)/uvHeight));
- edges.Add(e);
- }
- }
-
- // try the right facing case
- if (pixelAlpha >= threshold && pixelRightAlpha >= threshold) {
- if (pixelAboveAlpha < threshold && pixelAboveRightAlpha < threshold) {
- if (pixelBelowAlpha >= threshold || pixelBelowRightAlpha >= threshold) {
- // add the horizontal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y,(uvX+1)/uvWidth,uvY/uvHeight));
- edges.Add(e);
- }
- }
- else if ( pixelBelowAlpha < threshold && pixelBelowRightAlpha < threshold) {
- if (pixelAboveAlpha >= threshold || pixelAboveRightAlpha >= threshold) {
- // add the horizontal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y,(uvX+1)/uvWidth,uvY/uvHeight));
- edges.Add(e);
- }
- }
- }
-
- // try the down diagonal case
- if (pixelAlpha >= threshold && pixelBelowRightAlpha >= threshold) {
- if ( pixelRightAlpha < threshold && pixelBelowAlpha >= threshold) {
- // add the down diagonal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y-1,(uvX+1)/uvWidth,(uvY-1)/uvHeight));
- edges.Add(e);
- }
- else if (pixelRightAlpha >= threshold && pixelBelowAlpha < threshold) {
- // ad the down diagonal edge
- MC_Edge e = new MC_Edge(GetVertex(x,y,uvX/uvWidth,uvY/uvHeight), GetVertex(x+1,y-1,(uvX+1)/uvWidth,(uvY-1)/uvHeight));
- edges.Add(e);
- }
- }
-
- }
- }
- MakeOutsideEdge();
- SimplifyEdge();
- }
-
- MC_Vertex GetVertex(float x, float y, float u, float v) {
- for (int i = 0; i < vertices.Count; i++) {
- MC_Vertex ver = (MC_Vertex) vertices[i];
- if (ver.x == x && ver.y == y) {
- return ver;
- }
- }
- MC_Vertex newver = new MC_Vertex(x,y,u,v);
- vertices.Add(newver);
- return newver;
- }
-
- public void MergeClosePoints(float mergeDistance)
- {
- foreach (MC_EdgeLoop edgeLoop in edgeLoops)
- {
- edgeLoop.MergeClosePoints(mergeDistance);
- }
- }
-
- void SimplifyEdge() {
- foreach (MC_EdgeLoop edgeLoop in edgeLoops) {
- edgeLoop.SimplifyEdge();
- }
- }
-
- void MakeOutsideEdge() {
-
- // order the edges
- // start first edge loop with the first outside edge
- MC_EdgeLoop currentEdgeLoop = new MC_EdgeLoop((MC_Edge)edges[0]);
- edges.RemoveAt(0);
- edgeLoops.Add(currentEdgeLoop);
-
- while (edges.Count > 0) {
- // if the currentEdgeLoop is fully closed make a new edge loop
- if (currentEdgeLoop.IsClosed()) {
- MC_EdgeLoop nextEdgeLoop = new MC_EdgeLoop((MC_Edge)edges[0]);
- //Debug.LogWarning("SimpleSurfaceEdge::MakeOutsideEdge: adding another edge loop, last one was " + currentEdgeLoop.orderedEdges.Count + " edges long");
- //Debug.LogWarning(" this means your image has islands, I hope that's what you want.");
- edges.RemoveAt(0);
- edgeLoops.Add(nextEdgeLoop);
- currentEdgeLoop = nextEdgeLoop;
- }
- // test each edge to see if it fits into the edgeloop
- ArrayList deleteEdges = new ArrayList();
- for (int i = 0; i < edges.Count; i++) {
- MC_Edge e = (MC_Edge) edges[i];
- if (currentEdgeLoop.AddEdge(e)) { // try to add the edge
- deleteEdges.Add(e);
- }
- }
- // delete the added edges
- for (int i = 0; i < deleteEdges.Count; i++) {
- edges.Remove( (MC_Edge)deleteEdges[i] );
- }
- }
-
- }
-
- public Vector2[] GetOutsideEdgeVertices() {
- MC_EdgeLoop eL = (MC_EdgeLoop) edgeLoops[0];
- return eL.GetVertexList();
- }
-
- public ArrayList GetAllEdgeVertices() {
- ArrayList edgeLoopVertices = new ArrayList();
- foreach (MC_EdgeLoop el in edgeLoops) {
- edgeLoopVertices.Add(el.GetVertexList());
- }
- return edgeLoopVertices;
- }
-
- public bool ContainsIslands() {
- if (edgeLoops.Count > 1) return true;
- return false;
- }
-
- public Vector2 GetUVForIndex(int loopIndex, int i) {
- MC_EdgeLoop eL = (MC_EdgeLoop) edgeLoops[loopIndex];
- return eL.GetUVForIndex(i);
- //return new Vector2(raw.x/((float)imageWidth), raw.y/((float)imageHeight));
- }
-
- public Vector2 GetUVForIndex(int i) {
- MC_EdgeLoop eL = (MC_EdgeLoop) edgeLoops[0];
- return eL.GetUVForIndex(i);
- //return new Vector2(raw.x/((float)imageWidth), raw.y/((float)imageHeight));
- }
- }
- class MC_Vertex {
- public float x,y;
- public float u,v;
- public MC_Vertex(float _x, float _y, float _u, float _v) {
- x = _x;
- y = _y;
- u = _u;
- v = _v;
- }
-
- /*
- * GetString() returns a descriptive string about info in this object
- * Useful for debugging.
- */
- public string GetString() {
- return "Vertex(x,y:" + x + "," + y + ", uv:" + u + "," + v + ")";
- }
-
- }
- class MC_Edge {
- public MC_Vertex v1;
- public MC_Vertex v2;
- public bool isShared; // indicate if there are two of these?
- ArrayList attachedFaces;
- public MC_Edge(MC_Vertex _v1, MC_Vertex _v2) {
- v1 = _v1;
- v2 = _v2;
- isShared = false;
- attachedFaces = new ArrayList();
- }
-
- public void AttachFace(MC_Face f) {
- attachedFaces.Add(f);
- }
-
- public bool OtherFaceCentered(MC_Face f) {
- if (attachedFaces.Count > 1) {
- MC_Face face1 = (MC_Face) attachedFaces[0];
- MC_Face face2 = (MC_Face) attachedFaces[1];
- if ( face1 == null && face2 == f) return true; // faces already deleted????
- else if ( face2 == null && face1 == f) return true;
- else if ( face1 != null && face1 != f && face1.IsCentered()) return true;
- else if ( face2 != null && face2 != f && face2.IsCentered()) return true;
- }
- return false;
- }
-
- public void SwitchVertices() {
- MC_Vertex hold = v1;
- v1 = v2;
- v2 = hold;
- }
-
- /*
- * GetString() returns a descriptive string about info in this object
- * Useful for debugging.
- */
- public string GetString() {
- return "Edge (" + v1.GetString() + ", " + v2.GetString() + ", shared:" + isShared + ")";
- }
- }
- class MC_Face {
- public MC_Vertex v1, v2, v3;
- public MC_Edge e1, e2, e3;
-
- public MC_Face(MC_Edge _e1, MC_Edge _e2, MC_Edge _e3) {
- e1 = _e1;
- e2 = _e2;
- e3 = _e3;
- e1.AttachFace(this);
- e2.AttachFace(this);
- e3.AttachFace(this);
- v1 = e1.v1;
- v2 = e1.v2;
- if (e2.v1 != v1 && e2.v1 != v2) v3 = e2.v1;
- else v3 = e2.v2;
- }
-
- public bool ContainsEdge(MC_Edge e) {
- if (e1 == e || e2 == e || e3 == e) {
- return true;
- }
- return false;
- }
-
- public bool IsCentered() {
- if (e1.isShared && e2.isShared && e3.isShared) {
- return true;
- }
- return false;
- }
-
- public bool IsCenteredCentered() {
- if (IsCentered()) {
- if (e1.OtherFaceCentered(this) && e2.OtherFaceCentered(this) && e3.OtherFaceCentered(this) ) {
- return true;
- }
- }
- return false;
- }
-
- public MC_Vertex[] GetVertices() {
- return new MC_Vertex[] { v1, v2, v3};
- }
- }
- // ordered list of edges
- class MC_EdgeLoop {
- public ArrayList orderedEdges;
-
- public MC_EdgeLoop(MC_Edge e) {
- orderedEdges = new ArrayList();
- orderedEdges.Add(e);
- }
-
- public bool AddEdge(MC_Edge e) {
- // see if it shares with the last edge
- MC_Vertex lastVertex = ((MC_Edge) orderedEdges[orderedEdges.Count-1]).v2;
- if (e.v1 == lastVertex) { // this is the correct vertex order
- orderedEdges.Add(e);
- return true;
- }
- else if (e.v2 == lastVertex) { // incorrect order, switch before adding
- e.SwitchVertices();
- orderedEdges.Add(e);
- return true;
- }
-
- // see if it shares with the first edge
- MC_Vertex firstVertex = ((MC_Edge) orderedEdges[0]).v1;
- if (e.v2 == firstVertex) { // this is the correct vertex order
- orderedEdges.Insert(0,e);
- return true;
- }
- else if (e.v1 == firstVertex) { // incorrect order, switch before adding
- e.SwitchVertices();
- orderedEdges.Insert(0, e);
- return true;
- }
- return false;
- }
-
- public bool IsClosed() {
- if (orderedEdges.Count < 2) return false;
- MC_Vertex lastVertex = ((MC_Edge) orderedEdges[orderedEdges.Count-1]).v2;
- MC_Vertex firstVertex = ((MC_Edge) orderedEdges[0]).v1;
- if (firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y) return true;
- return false;
- }
-
- public Vector2[] GetVertexList() {
- Vector2[] verts = new Vector2[orderedEdges.Count];
- for (int i = 0; i < orderedEdges.Count; i++) {
- MC_Vertex v = ((MC_Edge) orderedEdges[i]).v1;
- verts[i]= new Vector2(v.x, v.y);
- }
- return verts;
- }
-
- public Vector2 GetUVForIndex(int i) {
- if (i >= orderedEdges.Count) {
- //Debug.Log("got " + i + " index for ordered edge with " + orderedEdges.Count + " elements");
- return new Vector2();
- }
- MC_Vertex v = ((MC_Edge)orderedEdges[i]).v1;
- return new Vector2(v.u, v.v);
- }
-
- /*
- * GetString() returns a descriptive string about info in this object
- * Useful for debugging.
- */
- public string GetString() {
- string s = "EdgeLoop with " + orderedEdges.Count + " edges: ";
- for (int i = 0; i < orderedEdges.Count; i++) {
- MC_Edge e = (MC_Edge) orderedEdges[i];
- s += e.GetString() + ", " ;
- }
- return s;
- }
-
- /*
- * SimplifyEdge() searchs for edges in which the shared vertex is a point
- * on a line between the two outer points.
- */
- public void SimplifyEdge() {
- ArrayList newOrderedEdges = new ArrayList(); // list to stick the joined edges
- MC_Edge currentEdge = (MC_Edge)orderedEdges[0];
- for (int i = 1; i < orderedEdges.Count; i++) { // start with the second edge for comparison
- MC_Edge testEdge = (MC_Edge) orderedEdges[i];
- MC_Vertex v1 = currentEdge.v1;
- MC_Vertex v2 = testEdge.v2;
- MC_Vertex sharedPoint = currentEdge.v2;
- if (sharedPoint != testEdge.v1) { // oops, bad list, it should be closed by now
- Debug.LogError("Mesh Creator EdgeLoop Error: list is not ordered when simplifying edge. Please create a new issue at https://github.com/uclagamelab/MeshCreator/issues.");
- return;
- }
- if (v1 == v2) {
- Debug.LogError("Mesh Creator EdgeLoop Error: found matching endpoints for a line when simplifying. Please create a new issue at https://github.com/uclagamelab/MeshCreator/issues.");
- return;
- }
- // determine if sharedPoint is on a line between the two endpoints
- //The point (x3, y3) is on the line determined by (x1, y1) and (x2, y2) if and only if (x3-x1)*(y2-y1)==(x2-x1)*(y3-y1).
- float slope1 = (sharedPoint.x - v1.x) * (v2.y-v1.y);
- float slope2 = (v2.x - v1.x) * (sharedPoint.y- v1.y);
- if (slope1 == slope2) { // combine the two lines into current
- currentEdge.v2 = v2;
- }
- else { // there isn't a continuation of line, so add current to new ordered and set current to testEdge
- newOrderedEdges.Add(currentEdge);
- currentEdge = testEdge;
- }
- }
- newOrderedEdges.Add(currentEdge);
- orderedEdges = newOrderedEdges;
- }
-
- // very simple edge smoothing by comparing distance between adjacent
- // points on edge and merging if close enough
- public void MergeClosePoints(float mergeDistance)
- {
- if (mergeDistance < 0.0f) return;
-
- ArrayList newOrderedEdges = new ArrayList(); // list to stick the joined edges
- //int originalCount = orderedEdges.Count;
- MC_Edge currentEdge = (MC_Edge)orderedEdges[0];
- for (int i = 1; i < orderedEdges.Count; i++) { // start with the second edge for comparison
- MC_Edge testEdge = (MC_Edge) orderedEdges[i];
- float dist = Vector2.Distance( new Vector2(currentEdge.v1.x, currentEdge.v1.y), new Vector2(testEdge.v2.x, testEdge.v2.y) );
- MC_Vertex v2 = testEdge.v2;
-
- if ( dist < mergeDistance ) { // combine the two lines into current
- currentEdge.v2 = v2;
- }
- else { // there isn't a continuation of line, so add current to new ordered and set current to testEdge
- newOrderedEdges.Add(currentEdge);
- currentEdge = testEdge;
- }
- }
- newOrderedEdges.Add(currentEdge);
- orderedEdges = newOrderedEdges;
- /*if (originalCount != orderedEdges.Count)
- {
- Debug.Log("SimpleSurfaceEdge::MergeClosePoints(): trimmed from " + originalCount + " to " + orderedEdges.Count + " edges.");
- }*/
- }
- }
|