diff --git a/CMakeLists.txt b/CMakeLists.txt index b0355e9..7343897 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,115 +1,28 @@ project(SparrowEngine) cmake_minimum_required(VERSION 2.8) -find_package(OpenGL REQUIRED) +# choose source file +file(GLOB LIB_SRC_LIST src/*.cpp src/tools/*.cpp) +file(GLOB LIB_HEAD_LIST src/*.h src/tools/*.h) +list(REMOVE_ITEM LIB_SRC_LIST src/main.cpp) +set(EXEC_SRC_LIST src/main.cpp) -if(WIN32) - set(SYSTEM_LIB_PATH "win32") - set(GLEW_LIB_NAME "glew32") -else(WIN32) - set(SYSTEM_LIB_PATH "linux") - set(GLEW_LIB_NAME "GLEW") -endif(WIN32) +#set compilation option +set(IS_LIBRARY True) +set(USE_OPENGL True) +set(USE_SFML True) +set(USE_RENDERER True) +set(USE_INPUT True) +set(USE_BULLET True) -set(LIB_SRC_LIST - engine.cpp - scene.cpp - resourcemanager.cpp - cameranode.cpp +list(APPEND INCLUDE_PATHS_EXTENSION + /bullet ) -set(LIBRARY_NAME ${PROJECT_NAME}) -set(EXECUTABLE_NAME "test${PROJECT_NAME}") - -set(DEPENDENCIES_ROOT ${PROJECT_SOURCE_DIR}/../cpp_dependencies) -set(INCLUDE_ROOT ${DEPENDENCIES_ROOT}/include) -set(LIB_ROOT ${DEPENDENCIES_ROOT}/lib/${SYSTEM_LIB_PATH}) - -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_ROOT}) #for SHARED -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_ROOT}) #for STATIC - -add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST}) -add_executable(${EXECUTABLE_NAME} main.cpp) -add_definitions(-std=c++11) - -include_directories( - ${INCLUDE_ROOT} - ${INCLUDE_ROOT}/bullet - ${PROJECT_SOURCE_DIR}/../sparrowinput - ${PROJECT_SOURCE_DIR}/../SparrowInput - ${PROJECT_SOURCE_DIR}/../sparrowrenderer +list(APPEND EXTRA_INCLUDE + ${PROJECT_SOURCE_DIR}/../sparrowinput + ${PROJECT_SOURCE_DIR}/../SparrowInput + ${PROJECT_SOURCE_DIR}/../sparrowrenderer/src ) -find_library(SFML_LIBRARY_WINDOW - NAMES - sfml-window - PATHS - ${LIB_ROOT} -) - -find_library(SFML_LIBRARY_SYSTEM - NAMES - sfml-system - PATHS - ${LIB_ROOT} -) - -find_library(SPARROW_RENDERER_LIBRARY - NAMES - SparrowRenderer - PATHS - ${LIB_ROOT} -) - -find_library(SPARROW_INPUT_LIBRARY - NAMES - SparrowInput - PATHS - ${LIB_ROOT} -) - -find_library(BULLET_COLLISION_LIBRARY - NAMES - BulletCollision - PATHS - ${LIB_ROOT} -) - -find_library(BULLET_DYNAMICS_LIBRARY - NAMES - BulletDynamics - PATHS - ${LIB_ROOT} -) - -find_library(LINEAR_MATH_LIBRARY - NAMES - LinearMath - PATHS - ${LIB_ROOT} -) - -find_library(GLEW_LIBRARY - NAMES - ${GLEW_LIB_NAME} - PATHS - ${LIB_ROOT} -) - -target_link_libraries( - ${LIBRARY_NAME} - ${SFML_LIBRARY_WINDOW} - ${SFML_LIBRARY_SYSTEM} - ${SPARROW_INPUT_LIBRARY} - ${SPARROW_RENDERER_LIBRARY} - ${BULLET_COLLISION_LIBRARY} - ${BULLET_DYNAMICS_LIBRARY} - ${LINEAR_MATH_LIBRARY} - ${GLEW_LIBRARY} - ${OPENGL_LIBRARIES} -) - -target_link_libraries( - ${EXECUTABLE_NAME} - ${LIBRARY_NAME} -) +include(template.cmake) diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 11f5ec5..0000000 --- a/main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "engine.h" -#include -#include "scene.h" -#include "cameranode.h" -#include "resourcemanager.h" -#include "sparrowrenderer.h" - -int main(){ - CameraNode camera; - RESOURCE_ADD(&camera, SceneNode, "camera"); - - Scene scene("testScene"); - scene.addChild("camera"); - - Engine engine; - engine.getRenderer()->setCamera(&camera); - engine.createWindow("test"); - engine.setScene("testScene"); - engine.start(); -} diff --git a/cameranode.cpp b/src/cameranode.cpp similarity index 100% rename from cameranode.cpp rename to src/cameranode.cpp diff --git a/cameranode.h b/src/cameranode.h similarity index 97% rename from cameranode.h rename to src/cameranode.h index 91293fd..331cb41 100644 --- a/cameranode.h +++ b/src/cameranode.h @@ -3,6 +3,7 @@ #include "scene.h" #include "camera.h" +#include "glm/vec3.hpp" class CameraNode : public SceneNode, public Camera { diff --git a/engine.cpp b/src/engine.cpp similarity index 98% rename from engine.cpp rename to src/engine.cpp index 1442110..cdcf083 100644 --- a/engine.cpp +++ b/src/engine.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "resourcemanager.h" #include "scene.h" diff --git a/engine.h b/src/engine.h similarity index 100% rename from engine.h rename to src/engine.h diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..035941c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,44 @@ +/*#include "engine.h" +#include +#include "scene.h" +#include "cameranode.h" +#include "resourcemanager.h" +#include "sparrowrenderer.h" +*/ + +#include "tools/graph.h" +#include "tools/pathfinder.h" + +int main(){ +/* CameraNode camera; + RESOURCE_ADD(&camera, SceneNode, "camera"); + + Scene scene("testScene"); + scene.addChild("camera"); + + Engine engine; + engine.getRenderer()->setCamera(&camera); + engine.createWindow("test"); + engine.setScene("testScene"); + engine.start();*/ + + GraphNode n1 = GraphNode(); + n1.setValue(1); + GraphNode n2 = GraphNode(); + n2.setValue(2); + GraphNode n3 = GraphNode(); + n3.setValue(3); + GraphNode n4 = GraphNode(); + n4.setValue(4); + + n1.addNeighbours(&n2,2); + n1.addNeighbours(&n3,3); + n2.addNeighbours(&n3,5); + n3.addNeighbours(&n4,2); + + std::vector path = PathFinder::a_star(&n1,&n4); + std::cout << "Path Size: " << path.size() << std::endl; + for(GraphNode* gn: path){ + std::cout << gn->getValue() << std::endl; + } +} diff --git a/resourcemanager.cpp b/src/resourcemanager.cpp similarity index 100% rename from resourcemanager.cpp rename to src/resourcemanager.cpp diff --git a/resourcemanager.h b/src/resourcemanager.h similarity index 100% rename from resourcemanager.h rename to src/resourcemanager.h diff --git a/scene.cpp b/src/scene.cpp similarity index 100% rename from scene.cpp rename to src/scene.cpp diff --git a/scene.h b/src/scene.h similarity index 100% rename from scene.h rename to src/scene.h diff --git a/src/tools/fiboheap.h b/src/tools/fiboheap.h new file mode 100644 index 0000000..dc9c1a2 --- /dev/null +++ b/src/tools/fiboheap.h @@ -0,0 +1,578 @@ +/** + * Fibonacci Heap + * Copyright (c) 2014, Emmanuel Benazera beniz@droidnik.fr, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ + +#ifndef FIBOHEAP_H +#define FIBOHEAP_H + +#include +#include +#include +#include + +template +class FibHeap +{ + public: + + // node + class FibNode + { + public: + FibNode(T k, void *pl) + :key(k),mark(false),p(nullptr),left(nullptr),right(nullptr),child(nullptr),degree(-1),payload(pl) + { + } + + ~FibNode() + { + } + + T key; + bool mark; + FibNode *p; + FibNode *left; + FibNode *right; + FibNode *child; + int degree; + void *payload; + }; // end FibNode + + FibHeap() + :n(0),min(nullptr) + { + } + + ~FibHeap() + { + // delete all nodes. + delete_fibnodes(min); + } + + void delete_fibnodes(FibNode *x) + { + if (!x) + return; + + FibNode *cur = x; + while(true) + { + /*std::cerr << "cur: " << cur << std::endl; + std::cerr << "x: " << x << std::endl;*/ + if (cur->left && cur->left != x) + { + //std::cerr << "cur left: " << cur->left << std::endl; + FibNode *tmp = cur; + cur = cur->left; + if (tmp->child) + delete_fibnodes(tmp->child); + delete tmp; + } + else + { + if (cur->child) + delete_fibnodes(cur->child); + delete cur; + break; + } + } + } + + /* + * insert(x) + * 1. x.degree = 0 + * 2. x.p = NIL + * 3. x.child = NIL + * 4. x.mark = FALSE + * 5. if H.min == NIL + * 6. create a root list for H containing just x + * 7. H.min = x + * 8. else insert x into H's root list + * 9. if x.key < H.min.key + *10. H.min = x + *11. H.n = H.n + 1 + */ + void insert(FibNode *x) + { + // 1 + x->degree = 0; + // 2 + x->p = nullptr; + // 3 + x->child = nullptr; + // 4 + x->mark = false; + // 5 + if ( min == nullptr) + { + // 6, 7 + min = x->left = x->right = x; + } + else + { + // 8 + min->left->right = x; + x->left = min->left; + min->left = x; + x->right = min; + // 9 + if ( x->key < min->key ) + { + // 10 + min = x; + } + } + // 11 + ++n; + } + + /* + * The minimum node of the heap. + */ + FibNode* minimum() + { + return min; + } + + /* + * union_fibheap(H1,H2) + * 1. H = MAKE-FIB-HEAP() + * 2. H.min = H1.min + * 3. concatenate the root list of H2 with the root list of H + * 4. if (H1.min == NIL) or (H2.min != NIL and H2.min.key < H1.min.key) + * 5. H.min = H2.min + * 6. H.n = H1.n + H2.n + * 7. return H + */ + static FibHeap* union_fibheap(FibHeap *H1, FibHeap *H2) + { + // 1 + FibHeap* H = new FibHeap(); + // 2 + H->min = H1->min; + // 3 + if ( H->min != nullptr && H2->min != nullptr ) + { + H->min->right->left = H2->min->left; + H2->min->left->right = H->min->right; + H->min->right = H2->min; + H2->min->left = H->min; + } + // 4 + if ( H1->min == nullptr || ( H2->min != nullptr && H2->min->key < H1->min->key ) ) + { + // 5 + H->min = H2->min; + } + // 6 + H->n = H1->n + H2->n; + // 7 + return H; + } + + /* + * extract_min + * 1. z = H.min + * 2. if z != NIL + * 3. for each child x of z + * 4. add x to the root list of H + * 5. x.p = NIL + * 6. remove z from the root list of H + * 7. if z == z.right + * 8. H.min = NIL + * 9. else H.min = z.right + *10. CONSOLIDATE(H) + *11. H.n = H.n - 1 + *12. return z + */ + FibNode* extract_min() + { + FibNode *z, *x, *next; + FibNode ** childList; + + // 1 + z = min; + // 2 + if ( z != nullptr ) + { + // 3 + x = z->child; + if ( x != nullptr ) + { + childList = new FibNode*[z->degree]; + next = x; + for ( int i = 0; i < (int)z->degree; i++ ) + { + childList[i] = next; + next = next->right; + } + for ( int i = 0; i < (int)z->degree; i++ ) + { + x = childList[i]; + // 4 + min->left->right = x; + x->left = min->left; + min->left = x; + x->right = min; + // 5 + x->p = nullptr; + } + delete [] childList; + } + // 6 + z->left->right = z->right; + z->right->left = z->left; + // 7 + if ( z == z->right ) + { + // 8 + min = nullptr; + } + else + { + // 9 + min = z->right; + // 10 + consolidate(); + } + // 11 + n--; + } + // 12 + return z; + } + + /* + * consolidate + * 1. let A[0 . . D(H.n)] be a new array + * 2. for i = 0 to D(H.n) + * 3. A[i] = NIL + * 4. for each node w in the root list of H + * 5. x = w + * 6. d = x.degree + * 7. while A[d] != NIL + * 8. y = A[d] + * 9. if x.key > y.key + *10. exchange x with y + *11. FIB-HEAP-LINK(H,y,x) + *12. A[d] = NIL + *13. d = d + 1 + *14. A[d] = x + *15. H.min = NIL + *16. for i = 0 to D(H.n) + *17. if A[i] != NIL + *18. if H.min == NIL + *19. create a root list for H containing just A[i] + *20. H.min = A[i] + *21. else insert A[i] into H's root list + *22. if A[i].key < H.min.key + *23. H.min = A[i] + */ + void consolidate() + { + FibNode* w, * next, * x, * y, * temp; + FibNode** A, ** rootList; + // Max degree <= log base golden ratio of n + int d, rootSize; + int max_degree = static_cast(floor(log(static_cast(n))/log(static_cast(1 + sqrt(static_cast(5)))/2))); + + // 1 + A = new FibNode*[max_degree+2]; // plus two both for indexing to max degree and so A[max_degree+1] == NIL + // 2, 3 + std::fill_n(A, max_degree+2, nullptr); + // 4 + w = min; + rootSize = 0; + next = w; + do + { + rootSize++; + next = next->right; + } while ( next != w ); + rootList = new FibNode*[rootSize]; + for ( int i = 0; i < rootSize; i++ ) + { + rootList[i] = next; + next = next->right; + } + for ( int i = 0; i < rootSize; i++ ) + { + w = rootList[i]; + // 5 + x = w; + // 6 + d = x->degree; + // 7 + while ( A[d] != nullptr ) + { + // 8 + y = A[d]; + // 9 + if ( x->key > y->key ) + { + // 10 + temp = x; + x = y; + y = temp; + } + // 11 + fib_heap_link(y,x); + // 12 + A[d] = nullptr; + // 13 + d++; + } + // 14 + A[d] = x; + } + delete [] rootList; + // 15 + min = nullptr; + // 16 + for ( int i = 0; i < max_degree+2; i++ ) + { + // 17 + if ( A[i] != nullptr ) + { + // 18 + if ( min == nullptr ) + { + // 19, 20 + min = A[i]->left = A[i]->right = A[i]; + } + else + { + // 21 + min->left->right = A[i]; + A[i]->left = min->left; + min->left = A[i]; + A[i]->right = min; + // 22 + if ( A[i]->key < min->key ) + { + // 23 + min = A[i]; + } + } + } + } + delete [] A; + } + +/* + * fib_heap_link(y,x) + * 1. remove y from the root list of heap + * 2. make y a child of x, incrementing x.degree + * 3. y.mark = FALSE + */ + void fib_heap_link( FibNode* y, FibNode* x ) + { + // 1 + y->left->right = y->right; + y->right->left = y->left; + // 2 + if ( x->child != nullptr ) + { + x->child->left->right = y; + y->left = x->child->left; + x->child->left = y; + y->right = x->child; + } + else + { + x->child = y; + y->right = y; + y->left = y; + } + y->p = x; + x->degree++; + // 3 + y->mark = false; + } + + + /* + * decrease_key(x,k) + * 1. if k > x.key + * 2. error "new key is greater than current key" + * 3. x.key = k + * 4. y = x.p + * 5. if y != NIL and x.key < y.key + * 6. CUT(H,x,y) + * 7. CASCADING-CUT(H,y) + * 8. if x.key < H.min.key + * 9. H.min = x + */ + void decrease_key( FibNode* x, int k ) + { + FibNode* y; + + // 1 + if ( k > x->key ) + { + // 2 + // error( "new key is greater than current key" ); + return; + } + // 3 + x->key = k; + // 4 + y = x->p; + // 5 + if ( y != nullptr && x->key < y->key ) + { + // 6 + cut(x,y); + // 7 + cascading_cut(y); + } + // 8 + if ( x->key < min->key ) + { + // 9 + min = x; + } + } + + /* + * cut(x,y) + * 1. remove x from the child list of y, decrementing y.degree + * 2. add x to the root list of H + * 3. x.p = NIL + * 4. x.mark = FALSE + */ + void cut( FibNode* x, FibNode* y ) + { + // 1 + if ( x->right == x ) + { + y->child = nullptr; + } + else + { + x->right->left = x->left; + x->left->right = x->right; + if ( y->child == x ) + { + y->child = x->right; + } + } + y->degree--; + // 2 + min->right->left = x; + x->right = min->right; + min->right = x; + x->left = min; + // 3 + x->p = nullptr; + // 4 + x->mark = false; + } + +/* + * cascading_cut(y) + * 1. z = y.p + * 2. if z != NIL + * 3. if y.mark == FALSE + * 4. y.mark = TRUE + * 5. else CUT(H,y,z) + * 6. CASCADING-CUT(H,z) + */ + void cascading_cut( FibNode* y ) + { + FibNode* z; + + // 1 + z = y->p; + // 2 + if ( z != nullptr ) + { + // 3 + if ( y->mark == false ) + { + // 4 + y->mark = true; + } + else + { + // 5 + cut(y,z); + // 6 + cascading_cut(z); + } + } + } + + /* + * set to infinity so that it hits the top of the heap, then easily remove. + */ + void remove_fibnode( FibNode* x ) + { + decrease_key(x,std::numeric_limits::min()); + FibNode *fn = extract_min(); + delete fn; + } + + /* + * mapping operations to STL-compatible signatures. + */ + bool empty() const + { + return n == 0; + } + + FibNode* topNode() + { + return minimum(); + } + + T top() + { + return minimum()->key; + } + + void pop() + { + if (empty()) + return; + FibNode *x = extract_min(); + if (x) + delete x; + } + + FibNode* push(T k, void *pl) + { + FibNode *x = new FibNode(k,pl); + insert(x); + return x; + } + + FibNode* push(T k) + { + return push(k,nullptr); + } + + unsigned int size() + { + return (unsigned int) n; + } + + int n; + FibNode *min; + +}; +#endif diff --git a/src/tools/graph.cpp b/src/tools/graph.cpp new file mode 100644 index 0000000..cc97225 --- /dev/null +++ b/src/tools/graph.cpp @@ -0,0 +1,62 @@ +#include "graph.h" + +#include +using namespace std; + +GraphNode::GraphNode() +{ + m_neighbours = vector(); +} + +GraphNode::GraphNode(vector neighbours):m_neighbours(neighbours) +{ +} + +void GraphNode::addNeighbours(GraphNode* n,float f){ + GraphEdge edge = GraphEdge(n,f); + addNeighbours(edge); +} + +void GraphNode::addNeighbours(GraphEdge edge){ + m_neighbours.push_back(edge); +} + +int GraphNode::getNbNeighbours(){ + return m_neighbours.size(); +} + +vector GraphNode::getNeighbours(){ + return m_neighbours; +} + +void GraphNode::print(std::string prefix) +{ + cout << prefix << "Node_id : "; + cout << prefix << m_testvalue << endl; +// cout << prefix << "Neighbours list :" << endl; + //prefix += "\t"; + //for_each (m_neighbours.begin(), m_neighbours.end(),[prefix](GraphEdge voisin) { + // voisin.getTarget()->print(prefix); + //}); +} + +void GraphNode::setValue(int a){ + m_testvalue = a; +} + +int GraphNode::getValue(){ + return m_testvalue; +} + + + +GraphEdge::GraphEdge(GraphNode* gn,float v):m_target(gn),m_weight(v) +{} + +GraphNode* GraphEdge::getTarget(){ + return m_target; +} + +float GraphEdge::getWeight(){ + return m_weight; +} diff --git a/src/tools/graph.h b/src/tools/graph.h new file mode 100644 index 0000000..42f670d --- /dev/null +++ b/src/tools/graph.h @@ -0,0 +1,39 @@ +#ifndef GRAPH_H +#define GRAPH_H + +#include +#include + +class GraphEdge; + +class GraphNode +{ + std::vector m_neighbours; + int m_testvalue; //temp variable +public: + GraphNode(); + GraphNode(std::vector); + + std::vector getNeighbours(); + void addNeighbours(GraphNode*,float); + void addNeighbours(GraphEdge); + int getNbNeighbours(); + virtual float heuristic(GraphNode*){return 1;}; + + void setValue(int); + int getValue(); + void print(std::string prefix); +}; + +class GraphEdge +{ + GraphNode* m_target; + float m_weight; + +public: + GraphEdge(GraphNode*,float); + GraphNode* getTarget(); + float getWeight(); +}; + +#endif // GRAPH_H diff --git a/src/tools/pathfinder.cpp b/src/tools/pathfinder.cpp new file mode 100644 index 0000000..e692459 --- /dev/null +++ b/src/tools/pathfinder.cpp @@ -0,0 +1,68 @@ +#include "pathfinder.h" + +#include +#include +#include +//#include "fiboheap.h" + +PathFinder::PathFinder(){ +} + +std::vector PathFinder::a_star(GraphNode* start,GraphNode* goal) +{ + // Check if priorityqueue sort value in right order. + std::priority_queue frontier = std::priority_queue(); + std::map cost = std::map(); //cost of visited node + std::map pred = std::map(); //pred of visited node + + // init frontier, cost, and pred with value for start + PriorityNode* pn = new PriorityNode(); + pn->node = std::pair(start,0); + frontier.push(pn); + cost.insert(std::pair(start,0)); + pred.insert(std::pair(start,NULL)); + + GraphNode* current; + while(!frontier.empty()){ + //pick best element from frontier (with priority queue the best is in front) + pn = frontier.top(); + current = pn->node.first; + frontier.pop(); + + // goal reached, end of a-star + if (current == goal){ + break; + } + + // for all neighbours of current node + for (GraphEdge next : current->getNeighbours()){ + float new_cost = cost[current] + next.getWeight(); + + if ((cost.count(next.getTarget()) == 0) || (new_cost < cost[next.getTarget()])){ + // affect processed cost to next node in cost_map + cost[next.getTarget()] = new_cost; + + // calcul priority of node with heuristic,and add it to frontier + float priority = new_cost; //+ heuristic(next.getTarget(), goal); + PriorityNode* pn = new PriorityNode(); + pn->node = std::pair(next.getTarget(),priority); + frontier.push(pn); + + // memorize predecessor for next + pred[next.getTarget()] = current; + } + } + } + + // reconstruct path by backtracking from goal to start + std::vector path = std::vector(); + while(current != start){ + path.push_back(current); + current = pred[current]; + } + path.push_back(start); + std::reverse(path.begin(),path.end()); + return path; +} + + diff --git a/src/tools/pathfinder.h b/src/tools/pathfinder.h new file mode 100644 index 0000000..d4a3d94 --- /dev/null +++ b/src/tools/pathfinder.h @@ -0,0 +1,23 @@ +#ifndef PATHFINDER_H +#define PATHFINDER_H + +#include +#include "graph.h" + +class PathFinder +{ +public: + PathFinder(); + static std::vector a_star(GraphNode* start,GraphNode* goal); +}; + +struct PriorityNode +{ + std::pair node; + bool operator<(PriorityNode other) const + { + return node.second < other.node.second; + } +}; + +#endif // PATHFINDER_H diff --git a/template.cmake b/template.cmake new file mode 100644 index 0000000..195e6b9 --- /dev/null +++ b/template.cmake @@ -0,0 +1,130 @@ +# Variable that you need to define to use this template +# IS_LIBRARY, USE_SFML, USE_RENDERER, USE_INPUT, USE_BULLET,USE_OPENGL +# +# Container for list of file to be compiled : +# LIB_SRC_LIST, LIB_HEAD_LIST, EXEC_SRC_LIST, EXEC_HEAD_LIST + +#detect system +if(WIN32) + set(SYSTEM_LIB_PATH "win32") +else(WIN32) + set(SYSTEM_LIB_PATH "linux") +endif(WIN32) + +#set dependencies paths +set(DEPENDENCIES_ROOT ${PROJECT_SOURCE_DIR}/../cpp_dependencies) +set(INCLUDE_ROOT ${DEPENDENCIES_ROOT}/include) +set(LIB_ROOT ${DEPENDENCIES_ROOT}/lib/${SYSTEM_LIB_PATH}) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_ROOT}) #for SHARED +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_ROOT}) #for STATIC + +#create library and executable +if(IS_LIBRARY) + set(LIBRARY_NAME ${PROJECT_NAME}) + set(EXECUTABLE_NAME "test${PROJECT_NAME}") + add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST} ${LIB_HEAD_LIST}) +else() + set(EXECUTABLE_NAME "${PROJECT_NAME}") +endif() + add_executable(${EXECUTABLE_NAME} ${EXEC_SRC_LIST}) + +add_definitions(-std=c++11) + +LIST(APPEND INCLUDE_PATHS ${INCLUDE_ROOT}) + +foreach(EXTENSION ${INCLUDE_PATHS_EXTENSION}) + LIST(APPEND INCLUDE_PATHS ${INCLUDE_ROOT}${EXTENSION} " ") +endforeach() + +include_directories( + ${INCLUDE_PATHS} + ${EXTRA_INCLUDE} +) + +MESSAGE(STATUS ${INCLUDE_DIRECTORIES}) + +#find libraries +set(DEP_LIST "") + +if(USE_SFML) + find_library(SFML_LIBRARY_WINDOW + NAMES + sfml-window + PATHS + ${LIB_ROOT} + ) + + find_library(SFML_LIBRARY_SYSTEM + NAMES + sfml-system + PATHS + ${LIB_ROOT} + ) + LIST(APPEND DEP_LIST ${SFML_LIBRARY_WINDOW} ${SFML_LIBRARY_SYSTEM}) +endif() + +if(USE_RENDERER) + find_library(SPARROW_RENDERER_LIBRARY + NAMES + sparrowrenderer + PATHS + ${LIB_ROOT} + ) + LIST(APPEND DEP_LIST ${SPARROW_RENDERER_LIBRARY}) +endif() + +if(USE_INPUT) + find_library(SPARROW_INPUT_LIBRARY + NAMES + SparrowInput + PATHS + ${LIB_ROOT} + ) + LIST(APPEND DEP_LIST ${SPARROW_INPUT_LIBRARY}) +endif() + +if(USE_BULLET) + find_library(BULLET_COLLISION_LIBRARY + NAMES + BulletCollision + PATHS + ${LIB_ROOT} + ) + + find_library(BULLET_DYNAMICS_LIBRARY + NAMES + BulletDynamics + PATHS + ${LIB_ROOT} + ) + + find_library(LINEAR_MATH_LIBRARY + NAMES + LinearMath + PATHS + ${LIB_ROOT} + ) + LIST(APPEND DEP_LIST ${BULLET_COLLISION_LIBRARY} ${BULLET_DYNAMICS_LIBRARY} ${LINEAR_MATH_LIBRARY}) +endif() + +if(USE_OPENGL) + find_package(OpenGL REQUIRED) + LIST(APPEND DEP_LIST ${OPENGL_LIBRARIES}) +endif() + +if(IS_LIBRARY) + target_link_libraries( + ${LIBRARY_NAME} + ${DEP_LIST} + ) + target_link_libraries( + ${EXECUTABLE_NAME} + ${LIBRARY_NAME} + ) +else() + target_link_libraries( + ${EXECUTABLE_NAME} + ${DEP_LIST} + ) +endif()