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);
- }
|