Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Quadtree.hpp"
- #include "Object.hpp"
- #include <thread>
- #include <stdio.h>
- #include <string>
- #include <future>
- #include <SFML\System.hpp>
- sf::Mutex mutex;
- Quadtree::Quadtree() :
- left( 0 ),
- right( 0 ),
- top( 0 ),
- down( 0 ),
- numObjectsToGrow( 1 ),
- nodes( 0 ),
- isLeaf( true ),
- isReady(false)
- {
- }
- Quadtree::Quadtree( double _left, double _right, double _top, double _down, unsigned int _numObjectsToGrow ) :
- left( _left ),
- right( _right ),
- top( _top ),
- down( _down ),
- numObjectsToGrow( _numObjectsToGrow ),
- nodes( 0 ),
- isLeaf( true ),
- isReady(false)
- {
- }
- Quadtree::~Quadtree()
- {
- if ( !isLeaf )
- delete [] nodes;
- }
- void Quadtree::Setup()
- {
- center = glm::vec3((left+right)/2, 1, (top+down)/2);
- float iValue;
- float jValue;
- // ID = engine->getGraphicsManager()->getId();
- std::cout << "Setup: " << ID << std::endl;
- size = 400;
- w = 1 ;
- h = 1 ;
- float ID2 = ID *0.1;
- ID2 = 0;
- for(int i = 0; i < w; i++)
- {
- for(int j = 0; j < h; j++)
- {
- iValue = i;
- jValue = j;
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID2, 0.0+jValue));
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID2, 1.0+jValue));
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID2, 0.0+jValue));
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID2, 1.0+jValue));
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID2, 0.0+jValue));
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID2, 1.0+jValue));
- }
- }
- for(int i = 0; i < vertices.size(); i++)
- {
- uvs.push_back(glm::vec2(vertices[i].x, vertices[i].z));
- normals.push_back(vertices[i]);
- glm::vec3 oldVec = vertices[i];
- // glm::vec3 newVec = glm::normalize(oldVec);
- glm::vec3 newVec = oldVec;
- // vertices[i] = newVec * glm::vec3(size, size, size);
- //vertices[i] = newVec + (glm::vec3(center.x - (100 * (1/(pow(level-1,2)))), 1, center.z - (100 * (1/(pow(level-1,2)))) ));
- //glm::vec3 newVec = oldVec * glm::vec3(size*(pow(0.5, level)), size, size*(pow(0.5, level)));
- vertices[i] = newVec + (glm::vec3(center.x - (100 * (1/(pow(level-1,2)))), 1, center.z - (100 * (1/(pow(level-1,2)))) ));
- }
- for(int i = 0; i < vertices.size(); i+=3)
- {
- // get the three vertices that make the faces
- glm::vec3 p1 = vertices[i+0];
- glm::vec3 p2 = vertices[i+1];
- glm::vec3 p3 = vertices[i+2];
- glm::vec3 v1 = p2 - p1;
- glm::vec3 v2 = p3 - p1;
- glm::vec3 normal = glm::cross( v1,v2 );
- normal = glm::normalize(normal);
- normals[i+0] = normal;
- normals[i+1] = normal;
- normals[i+2] = normal;
- }
- std::cout << "Terrain has: " << vertices.size() * 3 << " vertices!" << std::endl;
- glGenBuffers(1, &vertexbuffer);
- glGenBuffers(1, &uvbuffer);
- glGenBuffers(1, &normalbuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
- glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
- glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
- level = 0;
- }
- void Quadtree::Setup( int width, int height)
- {
- center = glm::vec3((left+right)/2, 1, (top+down)/2);
- float prevIValue;
- float prevJValue;
- float iValue;
- float jValue;
- // size = 25;
- // w = 160 ;
- // h = 160 ;
- size = 100;
- w = 41 ;
- h = 41 ;
- // ID = engine->getGraphicsManager()->getId();
- ID = 0;
- vertices.empty();
- //std::cout << "Setup: " << ID << std::endl;
- for(int i = 0; i < w; i++)
- {
- for(int j = 0; j < h; j++)
- {
- iValue = i;
- jValue = j;
- //iValue = i * (pow(0.5, 2));
- // jValue = j * (pow(0.5, 2));
- // std::cout << "Level: " << level << std::endl;
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID, 0.0+jValue)); //top left
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID, 1.0+jValue)); // bottom left
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID, 0.0+jValue)); // top right
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID, 1.0+jValue));
- vertices.push_back(glm::vec3(1.0+iValue, 1.0+ID, 0.0+jValue));
- vertices.push_back(glm::vec3(0.0+iValue, 1.0+ID, 1.0+jValue));
- }
- }
- for(int i = 0; i < vertices.size(); i++)
- {
- uvs.push_back(glm::vec2(vertices[i].x, vertices[i].z));
- normals.push_back(vertices[i]);
- glm::vec3 oldVec = vertices[i];
- //glm::vec3 newVec = glm::normalize(oldVec);
- //glm::vec3 newVec = oldVec * glm::vec3(size*(pow(0.5, level)), size, size*(pow(0.5, level)));
- //newVec = newVec - glm::vec3(size*(pow(0.5, level)), size, size*(pow(0.5, level)));
- /*
- if(level != 1)
- {
- glm::vec3 translate = glm::vec3(50/(level-1), 0, 50/(level-1));
- newVec = newVec - translate;
- }else{
- glm::vec3 translate = glm::vec3(50, 0, 50);
- newVec = newVec - translate;
- }
- */
- //glm::vec3 newVec = oldVec / glm::vec3(2 ^ level, 1, 2 ^ level);
- glm::vec3 newVec = oldVec * glm::vec3(size*(pow(0.5001, level)), size, size*(pow(0.5001, level)));
- vertices[i] = newVec + glm::vec3(left, 0, top); //+ (glm::vec3(center.x - (100 * (1/(pow(abs(level-1),2)))), 1, center.z - (100 * (1/(pow(abs(level-1),2)))) ));
- //std::cout << " X = " << (glm::vec3(center.x - (100 * (1/(pow(abs(level-1),2)))), 1, center.z - (100 * (1/(pow(abs(level-1),2)))) )).x << " Z = " << (glm::vec3(center.x - (100 * (1/(pow(abs(level-1),2)))), 1, center.z - (100 * (1/(pow(abs(level-1),2)))) )).z << std::endl;
- }
- std::cout << normals.size() << std::endl;
- for(int i = 0; i < vertices.size(); i+=3)
- {
- // get the three vertices that make the faces
- glm::vec3 p1 = vertices[i+0];
- glm::vec3 p2 = vertices[i+1];
- glm::vec3 p3 = vertices[i+2];
- glm::vec3 v1 = p2 - p1;
- glm::vec3 v2 = p3 - p1;
- glm::vec3 normal = glm::cross( v1,v2 );
- normal = glm::normalize(normal);
- normals[i+0] = normal;
- normals[i+1] = normal;
- normals[i+2] = normal;
- }
- // std::cout << "Terrain has: " << vertices.size() * 3 << " vertices!" << std::endl;
- glGenBuffers(1, &vertexbuffer);
- glGenBuffers(1, &uvbuffer);
- glGenBuffers(1, &normalbuffer);
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
- glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
- glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
- mutex.lock();
- isReady = true;
- mutex.unlock();
- //isReady = true;
- }
- int ia = 0;
- void Quadtree::Render()
- {
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
- glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
- glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
- if(isLeaf)
- {
- // std::cout << "Rendering: " << ID << std::endl;
- //vertices
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
- glVertexAttribPointer(
- 0,
- 3,
- GL_FLOAT,
- GL_FALSE,
- 0,
- (char*)0
- );
- //UVs
- glEnableVertexAttribArray(1);
- glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
- glVertexAttribPointer(
- 1, // attribute
- 2, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized?
- 0, // stride
- (char*)0 // array buffer offset
- );
- //Normal
- glEnableVertexAttribArray(2);
- glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
- glVertexAttribPointer(
- 2, // attribute
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized?
- 0, // stride
- (void*)0 // array buffer offset
- );
- glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glDisableVertexAttribArray(2);
- }else{
- for ( int n = 0; n < NodeCount; ++n ) {
- nodes[n].Render();
- }
- }
- }
- void Quadtree::AddObject( Object *object )
- {
- if ( isLeaf ) {
- objects.push_back( object );
- bool reachedMaxObjects = ( objects.size() == numObjectsToGrow );
- if ( reachedMaxObjects ) {
- if(level < 5)
- {
- createLeaves();
- moveObjectsToLeaves();
- isLeaf = false;
- }
- }
- return;
- }
- for ( int n = 0; n < NodeCount; ++n ) {
- if ( nodes[n].contains( object ) ) {
- nodes[n].AddObject( object );
- return;
- }
- }
- objects.push_back( object );
- }
- void Quadtree::Clear()
- {
- objects.clear();
- if ( !isLeaf ) {
- for ( int n = 0; n < NodeCount; ++n ) {
- nodes[n].Clear();
- }
- }
- }
- vector<Object*> Quadtree::GetObjectsAt( double x, double y )
- {
- if ( isLeaf ) {
- return objects;
- }
- vector<Object*> returnedObjects;
- vector<Object*> childObjects;
- if ( !objects.empty() )
- returnedObjects.insert( returnedObjects.end(), objects.begin(), objects.end() );
- for ( int n = 0; n < NodeCount; ++n ) {
- if ( nodes[n].contains( x, y ) ) {
- childObjects = nodes[n].GetObjectsAt( x, y );
- returnedObjects.insert( returnedObjects.end(), childObjects.begin(), childObjects.end() );
- break;
- }
- }
- return returnedObjects;
- }
- bool Quadtree::contains( Object *object )
- {
- return object->left > left &&
- object->right < right &&
- object->top > top &&
- object->down < down;
- }
- bool Quadtree::contains( double x, double y )
- {
- return ( x >= left && x <= right ) &&
- ( y >= top && y <= down );
- }
- void Quadtree::CheckDistance(glm::vec3 camera)
- {
- if(!camera.null){
- float xd = camera.x - center.x;
- float yd = camera.y - center.y;
- float zd = camera.z - center.z;
- float distance = sqrt(xd*xd + yd*yd + zd*zd);
- //std::cout << distance << std::endl;
- if(distance > 200)
- {
- if(!isLeaf)
- {
- if(nodes != NULL)
- {
- if(level > 0)
- {
- deleteLeaves();
- }
- }
- }
- }
- if(distance < 100){
- if(level < 5)
- {
- if(nodes == NULL){
- if(isLeaf)
- {
- //std::cout << "hello" << std::endl;
- createLeaves();
- moveObjectsToLeaves();
- isLeaf = false;
- }
- }
- }
- }
- /*
- if(distance > 100){
- if(!isLeaf)
- {
- if(nodes != NULL)
- {
- if(level > 0)
- {
- deleteLeaves();
- }
- }
- }
- }
- */
- if(nodes != NULL)
- {
- nodes[NW].CheckDistance(camera);
- nodes[NE].CheckDistance(camera);
- nodes[SW].CheckDistance(camera);
- nodes[SE].CheckDistance(camera);
- }
- }
- }
- void Quadtree::createLeaves()
- {
- nodes = new Quadtree[4];
- //std::cout << "left = " << left << " right = " << right << " top = " << top << "down = " << down << std::endl;
- nodes[NW] = Quadtree( left, (left+right)/2, top, (top+down)/2, numObjectsToGrow );
- nodes[NE] = Quadtree( (left+right)/2, right, top, (top+down)/2, numObjectsToGrow );
- nodes[SW] = Quadtree( left, (left+right)/2, (top+down)/2, down, numObjectsToGrow );
- nodes[SE] = Quadtree( (left+right)/2, right, (top+down)/2, down, numObjectsToGrow );
- /* nodes[NW].center.z = center.z ;
- nodes[NW].center.x = center.x ;
- nodes[NE].level = (level+1);
- nodes[NE].center.z = center.z ;
- nodes[NE].center.x = center.x + 34;
- nodes[SW].level = (level+1);
- nodes[SW].center.z = center.z + 34 ;
- nodes[SW].center.x = center.x + 34;
- nodes[SE].level = (level+1);
- nodes[SE].center.z = center.z + 34 ;
- nodes[SE].center.x = center.x ;*/
- /*
- nodes[NW].level = (level+1);
- nodes[NW].center.z = center.z / 2;
- nodes[NW].center.x = center.x / 2;
- nodes[NW].center.y = center.y;
- nodes[NE].level = (level+1);
- nodes[NE].center.z = center.z / 2;
- nodes[NE].center.x = center.x + (center.x / 2);
- nodes[NE].center.y = center.y;
- nodes[SW].level = (level+1);
- nodes[SW].center.z = center.z + (center.z / 2);
- nodes[SW].center.x = center.x / 2;
- nodes[SW].center.y = center.y;
- nodes[SE].level = (level+1);
- nodes[SE].center.z = center.z + (center.z / 2);
- nodes[SE].center.x = center.x + (center.x / 2);
- nodes[SE].center.y = center.y;
- */
- float value = 0;
- nodes[NW].level = (level+1);
- //nodes[NW].center.z = center.z;
- //nodes[NW].center.x = center.x;
- //nodes[NW].center.y = center.y;
- // std::cout << "NW: " << nodes[NW].center.x << " " << nodes[NW].center.y << " " << nodes[NW].center.z << " " << std::endl;
- nodes[NE].level = (level+1);
- //nodes[NE].center.z = center.z ;
- //nodes[NE].center.x = center.x + (left+right)/2;
- //nodes[NE].center.y = center.y;
- // std::cout << "LEFT: " << left << std::endl;
- //std::cout << "NE: " << nodes[NE].center.x << " " << nodes[NE].center.y << " " << nodes[NE].center.z << " " << std::endl;
- nodes[SW].level = (level+1);
- //nodes[SW].center.z = center.z + (top+down)/2;
- //nodes[SW].center.x = center.x;
- //nodes[SW].center.y = center.y;
- nodes[SE].level = (level+1);
- /*nodes[SE].center.z = center.z + (top+down)/2;
- nodes[SE].center.x = center.x + (left+right)/2;
- nodes[SE].center.y = center.y;
- */
- nodes[NW].Setup( w, h);
- nodes[NE].Setup( w, h);
- nodes[SW].Setup( w, h);
- nodes[SE].Setup( w, h);
- }
- void Quadtree::deleteLeaves()
- {
- nodes = NULL;
- isLeaf = true;
- }
- void Quadtree::deleteSelf()
- {
- //nodes = NULL;
- isLeaf = true;
- }
- void Quadtree::moveObjectsToLeaves()
- {
- for ( int n = 0; n < NodeCount; ++n ) {
- for ( unsigned int m = 0; m < objects.size(); ++m ) {
- if ( nodes[n].contains( objects[m] ) ) {
- nodes[n].AddObject( objects[m] );
- objects.erase( objects.begin() + m );
- --m;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment