| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- #include <limits>
- #include "map.h"
- #include "Mesh.h"
- #include "Scanner.h"
- #include "Parser.h"
- #include "Resource.h"
- #include "Camera.h"
- /*
- =======================================================================================================================================
- CreateRoot =
- =======================================================================================================================================
- */
- void octree_t::CreateRoot( const Vec<Mesh*>& meshes )
- {
- DEBUG_ERR( root ); // root should be NULL
- /// get the root's aabb size
- Vec3 min( numeric_limits<float>::max() ), max( numeric_limits<float>::min() );
- for( uint m=0; m<meshes.size(); m++ )
- {
- Mesh* cmesh = meshes[m];
- for( uint v=0; v<cmesh->vertCoords.size(); v++ )
- {
- const Vec3& vertCoords = cmesh->vertCoords[v];
- for( int i=0; i<3; i++ )
- {
- if( vertCoords[i] > max[i] )
- max[i] = vertCoords[i];
- else if( vertCoords[i] < min[i] )
- min[i] = vertCoords[i];
- } // end for 3 times
- } // end for all mesh verts
- } // end for all meshes
- /// create a new node
- node_t* node = new node_t;
- node->bounding_box.min = min;
- node->bounding_box.max = max;
- /// create the face and vert ids
- DEBUG_ERR( node->face_ids.size() != 0 || node->vertIds.size() != 0 || node->meshes.size() != 0 ); // vectors not empty. wrong node init
- node->face_ids.resize( meshes.size() );
- node->vertIds.resize( meshes.size() );
- node->meshes.resize( meshes.size() );
- for( uint m=0; m<meshes.size(); m++ )
- {
- Mesh* cmesh = meshes[m];
- // first set the mesh
- node->meshes[m] = cmesh;
- // then set the face_ids
- node->face_ids[m].resize( cmesh->tris.size() );
- for( uint f=0; f<cmesh->tris.size(); f++ )
- node->face_ids[m][f] = f; // simple as taking a shit
- // and last the verts
- }
- /// set root
- root = node;
- }
- /*
- =======================================================================================================================================
- GetFacesNum =
- =======================================================================================================================================
- */
- uint octree_t::node_t::GetFacesNum() const
- {
- int count = 0;
- for( uint i=0; i<meshes.size(); i++ )
- {
- count += meshes[i]->tris.size();
- }
- return count;
- }
- /*
- =======================================================================================================================================
- IsSubdivHeuristicMet =
- returns true when the used difined heuristic is met that sais that we can subdivide the node. Long story short it returns true when =
- we can subdivide the node further =
- =======================================================================================================================================
- */
- bool octree_t::IsSubdivHeuristicMet( node_t* node ) const
- {
- if( node->GetFacesNum() < 100 ) return false;
- return true;
- }
- /*
- =======================================================================================================================================
- SubdivideNode =
- subdivides the node and creates max 8 children and then subdivides the children =
- =======================================================================================================================================
- */
- void octree_t::SubdivideNode( node_t* node )
- {
- if( !IsSubdivHeuristicMet(node) ) return;
- // subdivide the children
- for( int i=0; i<8; i++ )
- {
- if( node->childs[i] == NULL ) continue;
- SubdivideNode( node->childs[i] );
- }
- }
- /*
- =======================================================================================================================================
- CreateTree =
- =======================================================================================================================================
- */
- void octree_t::CreateTree( const Vec<Mesh*>& meshes )
- {
- CreateRoot( meshes );
- SubdivideNode( root );
- }
- /*
- =======================================================================================================================================
- CheckNodeAgainstFrustum =
- the func checks the node and returns if its inside the cameras fruntum. It returns 0 if the cube is not inside, 1 if partialy =
- inside and 2 if totaly inside =
- =======================================================================================================================================
- */
- uint octree_t::CheckNodeAgainstFrustum( node_t* node, const Camera& cam ) const
- {
- int points_outside_frustum_num = 0;
- const aabb_t& box = node->bounding_box;
- Vec3 box_points[] = { box.max, Vec3(box.min.x, box.max.y, box.max.z), Vec3(box.min.x, box.min.y, box.max.z), Vec3(box.max.x, box.min.y, box.max.z),
- box.min, Vec3(box.min.x, box.max.y, box.min.z), Vec3(box.min.x, box.min.y, box.min.z), Vec3(box.max.x, box.min.y, box.min.z), };
- for( int i=0; i<8; i++ )
- {
- for( int j=0; j<6; j++ )
- {
- const plane_t& plane = cam.wspaceFrustumPlanes[j];
- if( plane.Test( box_points[i] ) < 0.0 )
- {
- ++points_outside_frustum_num;
- continue;
- }
- }
- }
- if( points_outside_frustum_num == 8 ) return 0;
- if( points_outside_frustum_num < 8 ) return 1;
- return 2;
- }
- /*
- =======================================================================================================================================
- map =
- =======================================================================================================================================
- */
- /*
- =======================================================================================================================================
- load =
- =======================================================================================================================================
- */
- bool map_t::load( const char* filename )
- {
- DEBUG_ERR( meshes.size() != 0 ); // meshes vector should be empty
- Scanner scanner;
- const Scanner::Token* token;
- if( !scanner.loadFile( filename ) ) return false;
- do
- {
- token = &scanner.getNextToken();
- // strings is what we want in this case... please let it be G-Strings
- if( token->getCode() == Scanner::TC_STRING )
- {
- Mesh* mesh = Rsrc::meshes.load( token->getValue().getString() );
- if( !mesh ) return false;
- meshes.push_back( mesh );
- }
- // end of file
- else if( token->getCode() == Scanner::TC_EOF )
- {
- break;
- }
- // other crap
- else
- {
- PARSE_ERR_UNEXPECTED();
- return false;
- }
- }while( true );
- return true;
- }
|