| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 | //-----------------------------------------------------------------------------// Copyright (c) 2012 GarageGames, LLC//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS// IN THE SOFTWARE.//-----------------------------------------------------------------------------#include "math/util/sphereMesh.h"SphereMesh::SphereMesh(U32 baseType){   VECTOR_SET_ASSOCIATION(mDetails);   switch(baseType)   {      case Tetrahedron:         mDetails.push_back(createTetrahedron());         break;      case Octahedron:         mDetails.push_back(createOctahedron());         break;      case Icosahedron:         mDetails.push_back(createIcosahedron());         break;   }   calcNormals(mDetails[0]);}//------------------------------------------------------------------------------SphereMesh::TriangleMesh * SphereMesh::createTetrahedron(){   const F32 sqrt3 = 0.5773502692f;   static Point3F spherePnts[] = {      Point3F( sqrt3, sqrt3, sqrt3 ),      Point3F(-sqrt3,-sqrt3, sqrt3 ),      Point3F(-sqrt3, sqrt3,-sqrt3 ),      Point3F( sqrt3,-sqrt3,-sqrt3 )   };   static Triangle tetrahedron[] = {      Triangle(spherePnts[0], spherePnts[1], spherePnts[2]),      Triangle(spherePnts[0], spherePnts[3], spherePnts[1]),      Triangle(spherePnts[2], spherePnts[1], spherePnts[3]),      Triangle(spherePnts[3], spherePnts[0], spherePnts[2]),   };   static TriangleMesh tetrahedronMesh = {      Tetrahedron,      &tetrahedron[0]   };   return(&tetrahedronMesh);}//------------------------------------------------------------------------------SphereMesh::TriangleMesh * SphereMesh::createOctahedron(){   //   static Point3F spherePnts[] = {      Point3F( 1, 0, 0),      Point3F(-1, 0, 0),      Point3F( 0, 1, 0),      Point3F( 0,-1, 0),      Point3F( 0, 0, 1),      Point3F( 0, 0,-1)   };   //   static Triangle octahedron[] = {      Triangle(spherePnts[0], spherePnts[4], spherePnts[2]),      Triangle(spherePnts[2], spherePnts[4], spherePnts[1]),      Triangle(spherePnts[1], spherePnts[4], spherePnts[3]),      Triangle(spherePnts[3], spherePnts[4], spherePnts[0]),      Triangle(spherePnts[0], spherePnts[2], spherePnts[5]),      Triangle(spherePnts[2], spherePnts[1], spherePnts[5]),      Triangle(spherePnts[1], spherePnts[3], spherePnts[5]),      Triangle(spherePnts[3], spherePnts[0], spherePnts[5])   };   //   static TriangleMesh octahedronMesh = {      Octahedron,      &octahedron[0]   };   return(&octahedronMesh);}SphereMesh::TriangleMesh * SphereMesh::createIcosahedron(){   const F32 tau = 0.8506508084f;   const F32 one = 0.5257311121f;   static Point3F spherePnts[] = {      Point3F( tau, one,   0),      Point3F(-tau, one,   0),      Point3F(-tau,-one,   0),      Point3F( tau,-one,   0),      Point3F( one,   0, tau),      Point3F( one,   0,-tau),      Point3F(-one,   0,-tau),      Point3F(-one,   0, tau),      Point3F(   0, tau, one),      Point3F(   0,-tau, one),      Point3F(   0,-tau,-one),      Point3F(   0, tau,-one),   };   static Triangle icosahedron[] = {      Triangle(spherePnts[4],  spherePnts[8],  spherePnts[7]),      Triangle(spherePnts[4],  spherePnts[7],  spherePnts[9]),      Triangle(spherePnts[5],  spherePnts[6],  spherePnts[11]),      Triangle(spherePnts[5],  spherePnts[10], spherePnts[6]),      Triangle(spherePnts[0],  spherePnts[4],  spherePnts[3]),      Triangle(spherePnts[0],  spherePnts[3],  spherePnts[5]),      Triangle(spherePnts[2],  spherePnts[7],  spherePnts[1]),      Triangle(spherePnts[2],  spherePnts[1],  spherePnts[6]),      Triangle(spherePnts[8],  spherePnts[0],  spherePnts[11]),      Triangle(spherePnts[8],  spherePnts[11], spherePnts[1]),      Triangle(spherePnts[9],  spherePnts[10], spherePnts[3]),      Triangle(spherePnts[9],  spherePnts[2],  spherePnts[10]),      Triangle(spherePnts[8],  spherePnts[4],  spherePnts[0]),      Triangle(spherePnts[11], spherePnts[0],  spherePnts[5]),      Triangle(spherePnts[4],  spherePnts[9],  spherePnts[3]),      Triangle(spherePnts[5],  spherePnts[3],  spherePnts[10]),      Triangle(spherePnts[7],  spherePnts[8],  spherePnts[1]),      Triangle(spherePnts[6],  spherePnts[1],  spherePnts[11]),      Triangle(spherePnts[7],  spherePnts[2],  spherePnts[9]),      Triangle(spherePnts[6],  spherePnts[10], spherePnts[2]),   };   static TriangleMesh icosahedronMesh = {      Icosahedron,      &icosahedron[0]   };   return(&icosahedronMesh);}//------------------------------------------------------------------------------void SphereMesh::calcNormals(TriangleMesh * mesh){   for(U32 i = 0; i < mesh->numPoly; i++)   {      Triangle & tri = mesh->poly[i];      mCross(tri.pnt[1] - tri.pnt[0], tri.pnt[2] - tri.pnt[0], &tri.normal);   }}//------------------------------------------------------------------------------SphereMesh::~SphereMesh(){   // level 0 is static data   for(U32 i = 1; i < mDetails.size(); i++)   {      delete [] mDetails[i]->poly;      delete mDetails[i];   }}//------------------------------------------------------------------------------const SphereMesh::TriangleMesh * SphereMesh::getMesh(U32 level){   AssertFatal(mDetails.size(), "SphereMesh::getMesh: no details!");   if(level > MaxLevel)      level = MaxLevel;   //   while(mDetails.size() <= level)      mDetails.push_back(subdivideMesh(mDetails.last()));   return(mDetails[level]);}SphereMesh::TriangleMesh * SphereMesh::subdivideMesh(TriangleMesh * prevMesh){   AssertFatal(prevMesh, "SphereMesh::subdivideMesh: invalid previous mesh level!");   //   TriangleMesh * mesh = new TriangleMesh;   mesh->numPoly = prevMesh->numPoly * 4;   mesh->poly = new Triangle [mesh->numPoly];   //   for(U32 i = 0; i < prevMesh->numPoly; i++)   {      Triangle * pt = &prevMesh->poly[i];      Triangle * nt = &mesh->poly[i*4];      Point3F a = (pt->pnt[0] + pt->pnt[2]) / 2;      Point3F b = (pt->pnt[0] + pt->pnt[1]) / 2;      Point3F c = (pt->pnt[1] + pt->pnt[2]) / 2;      // force the point onto the unit sphere surface      a.normalize();      b.normalize();      c.normalize();      //      nt->pnt[0] = pt->pnt[0];      nt->pnt[1] = b;      nt->pnt[2] = a;      nt++;      //      nt->pnt[0] = b;      nt->pnt[1] = pt->pnt[1];      nt->pnt[2] = c;      nt++;      //      nt->pnt[0] = a;      nt->pnt[1] = b;      nt->pnt[2] = c;      nt++;      //      nt->pnt[0] = a;      nt->pnt[1] = c;      nt->pnt[2] = pt->pnt[2];   }   calcNormals(mesh);   return(mesh);}
 |