#include #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& meshes) { DEBUG_ERR(root); // root should be NULL /// get the root's aabb size Vec3 min(numeric_limits::max()), max(numeric_limits::min()); for(uint m=0; mvertCoords.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; mmeshes[m] = cmesh; // then set the face_ids node->face_ids[m].resize(cmesh->tris.size()); for(uint f=0; ftris.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; itris.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& 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; }