diff --git a/src/planet.cpp b/src/planet.cpp index 2059e9a..de6254f 100644 --- a/src/planet.cpp +++ b/src/planet.cpp @@ -433,6 +433,42 @@ static void SubdivideVeryLongTri(vector3d& tip, vector3d& v1, vector3d& v2, int glEnd(); } +static void SphereBlobTess(vector3d& center, std::vector& edgeVerts) { + const int s = edgeVerts.size(); + std::vector vDead(s); + for(unsigned int i = 0; i < vDead.size(); i++) vDead[i] = 0; + //vDead.reserve(s); + int iters = 0; + int v1 = 0; + int v2 = 0; + int v3 = 0; + do { + vector3d v2dir = edgeVerts[v3] - edgeVerts[v2]; + vector3d v1norm = vector3d::Cross(edgeVerts[v1], edgeVerts[v2] - edgeVerts[v1]); + + const float dot = vector3d::Dot(v1norm, v2dir); + + if(dot >= 0.0) { + glBegin(GL_TRIANGLES); + /* Make like a billion tris... */ + SphereTriSubdivide(edgeVerts[v1], edgeVerts[v2], edgeVerts[v3], 3); + glEnd(); + vDead[v2] = 1; + + v2 = v3; + do { v3 = (v3+1)%s; } while(vDead[v3]); + } else { + v1 = v2; + v2 = v3; + do { v3 = (v3 + 1)%s; } while(vDead[v3]); + } + if(++iters > 1000) { printf("Brokend %d(%d),%d(%d),%d(%d)!\n",v1,vDead[v1],v2,vDead[v2],v3,vDead[v3]); break; } + } while((v1 != v2) && (v2 != v3) && (v3 != v1)); + int notDead = 0; + for(unsigned int i = 0; i < vDead.size(); i++) if(!vDead[i]) notDead++; + printf("%d not dead (%d iters)\n", notDead, iters); +} + static int exp2i(int foo) { int n = 2; while(--foo) n*=2; return n; } static void MakeContinent(matrix4x4d& rot, float scale, MTRand& rng) { glDisable(GL_DEPTH_TEST); @@ -464,9 +500,8 @@ static void MakeContinent(matrix4x4d& rot, float scale, MTRand& rng) { SubdivideTriangularContinent2(edgeVerts, 2*nvps, 3*nvps, GEOSPLIT, rng); vector3d center = vector3d::Normalize(v1+v2+v3); - for(unsigned int i = 0; i < edgeVerts.size()-1; i++) { - SubdivideVeryLongTri(center, edgeVerts[i], edgeVerts[i+1], 16); - } + SphereBlobTess(center, edgeVerts); + glEnable(GL_DEPTH_TEST); glDisable(GL_NORMALIZE); }