Merge branch 'pathfinding'
This commit is contained in:
commit
5c6a9f4d91
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
build*
|
build*
|
||||||
*.user
|
*.user
|
||||||
|
data/*
|
||||||
|
25
src/main.cpp
25
src/main.cpp
@ -7,16 +7,18 @@
|
|||||||
|
|
||||||
#include "tools/graph.h"
|
#include "tools/graph.h"
|
||||||
#include "tools/pathfinder.h"
|
#include "tools/pathfinder.h"
|
||||||
|
#include "tools/loader.h"
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
SceneTree scene("testScene");
|
SceneTree scene("testScene");
|
||||||
|
|
||||||
Engine engine;
|
Engine engine;
|
||||||
|
|
||||||
engine.createWindow("test");
|
engine.createWindow("test");
|
||||||
engine.setScene("testScene");
|
engine.setScene("testScene");
|
||||||
engine.start();
|
engine.start();
|
||||||
|
|
||||||
GraphNode n1 = GraphNode();
|
/* GraphNode n1 = GraphNode();
|
||||||
n1.setValue(1);
|
n1.setValue(1);
|
||||||
GraphNode n2 = GraphNode();
|
GraphNode n2 = GraphNode();
|
||||||
n2.setValue(2);
|
n2.setValue(2);
|
||||||
@ -24,15 +26,24 @@ int main(){
|
|||||||
n3.setValue(3);
|
n3.setValue(3);
|
||||||
GraphNode n4 = GraphNode();
|
GraphNode n4 = GraphNode();
|
||||||
n4.setValue(4);
|
n4.setValue(4);
|
||||||
|
GraphNode n5 = GraphNode();
|
||||||
|
n5.setValue(5);
|
||||||
|
|
||||||
n1.addNeighbours(&n2,2);
|
n1.addNeighbours(&n2);
|
||||||
n1.addNeighbours(&n3,3);
|
n1.addNeighbours(&n3);
|
||||||
n2.addNeighbours(&n3,5);
|
n2.addNeighbours(&n4);
|
||||||
n3.addNeighbours(&n4,2);
|
n3.addNeighbours(&n4);
|
||||||
|
n3.addNeighbours(&n2);
|
||||||
|
n3.addNeighbours(&n5);
|
||||||
|
|
||||||
std::vector<GraphNode*> path = PathFinder::a_star(&n1,&n4);
|
std::vector<GraphNode*> path = PathFinder::a_star(&n1,&n4,true);
|
||||||
std::cout << "Path Size: " << path.size() << std::endl;
|
std::cout << "Path Size: " << path.size() << std::endl;
|
||||||
for(GraphNode* gn: path){
|
for(GraphNode* gn: path){
|
||||||
std::cout << gn->getValue() << std::endl;
|
std::cout << gn->getValue() << std::endl;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
Loader::setObjDirectory("../data/");
|
||||||
|
Loader::setMtlDirectory("../data/");
|
||||||
|
Loader::setTexDirectory("../data/");
|
||||||
|
std::vector<Mesh*> meshes = Loader::loadMesh("sword.obj");
|
||||||
}
|
}
|
||||||
|
7
src/message.cpp
Normal file
7
src/message.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
|
||||||
|
Message::Message(std::string id, SystemType sender):m_id(id),m_sender(sender)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
18
src/message.h
Normal file
18
src/message.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef MESSAGE_H
|
||||||
|
#define MESSAGE_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
class Message
|
||||||
|
{
|
||||||
|
std::string m_id;
|
||||||
|
SystemType m_sender;
|
||||||
|
public:
|
||||||
|
Message(std::string,SystemType);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MESSAGE_H
|
29
src/messagebus.cpp
Normal file
29
src/messagebus.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "messagebus.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
MessageBus::MessageBus()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBus::registerSystem(SystemType type, System* system){
|
||||||
|
systems[type] = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBus::update()
|
||||||
|
{
|
||||||
|
while (!message_list.empty()){
|
||||||
|
Message* msg = message_list.front();
|
||||||
|
message_list.pop();
|
||||||
|
for(auto const &entity : systems){
|
||||||
|
entity.second->handleMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBus::postMessage(Message *msg)
|
||||||
|
{
|
||||||
|
message_list.push(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
26
src/messagebus.h
Normal file
26
src/messagebus.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef MESSAGEBUS_H
|
||||||
|
#define MESSAGEBUS_H
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
class Message;
|
||||||
|
class System;
|
||||||
|
|
||||||
|
class MessageBus
|
||||||
|
{
|
||||||
|
std::map<SystemType,System*> systems;
|
||||||
|
std::queue<Message*> message_list; //message file
|
||||||
|
|
||||||
|
public:
|
||||||
|
MessageBus();
|
||||||
|
void registerSystem(SystemType,System*);
|
||||||
|
void postMessage(Message* msg);
|
||||||
|
void update();
|
||||||
|
void handleMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MESSAGEBUS_H
|
51
src/sparrowshell.cpp
Normal file
51
src/sparrowshell.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "sparrowshell.h"
|
||||||
|
|
||||||
|
#include "message.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
const int SparrowShell::BUFFER_MAX_LENGTH = 50;
|
||||||
|
const int SparrowShell::BUFFER_DISPLAYED_NUMBER = 10;
|
||||||
|
const int SparrowShell::SCROLLBAR_PIXEL_WIDTH = 2;
|
||||||
|
|
||||||
|
SparrowShell::SparrowShell(sf::Window* window, Input* input): m_position(glm::ivec2(0,0)),m_window(window),m_input(input),m_scrollbar(this)
|
||||||
|
{
|
||||||
|
//m_dimension = glm::ivec2();//
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowShell::out(std::string s)
|
||||||
|
{
|
||||||
|
if (m_buffer.size() == BUFFER_MAX_LENGTH)
|
||||||
|
m_buffer.pop_back();
|
||||||
|
m_buffer.push_front(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowShell::scrollUp(){
|
||||||
|
if (m_index + BUFFER_DISPLAYED_NUMBER < m_buffer.size()) m_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowShell::scrollDown(){
|
||||||
|
if (m_index > 0) m_index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowShell::update()
|
||||||
|
{
|
||||||
|
//TODO : update TextMesh
|
||||||
|
m_scrollbar.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
SparrowShell::ScrollBar::ScrollBar(SparrowShell* shell):m_shell(shell){
|
||||||
|
m_position = glm::ivec2(m_shell->m_dimension.x - SCROLLBAR_PIXEL_WIDTH,0);
|
||||||
|
m_dimension = glm::ivec2(SCROLLBAR_PIXEL_WIDTH,m_shell->m_dimension.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowShell::ScrollBar::update(){
|
||||||
|
m_position.y = m_shell->m_position.y;
|
||||||
|
m_dimension.y = m_shell->m_dimension.y;
|
||||||
|
|
||||||
|
if (m_shell->m_buffer.size() > BUFFER_DISPLAYED_NUMBER){
|
||||||
|
float cran = ((float)m_shell->m_dimension.y/(float)m_shell->m_buffer.size());
|
||||||
|
int indexCursor = m_shell->m_buffer.size()-(m_shell->m_index+SCROLLBAR_PIXEL_WIDTH);
|
||||||
|
m_position.y += (int)(cran * indexCursor);
|
||||||
|
m_dimension.y = (int)(cran * BUFFER_DISPLAYED_NUMBER);
|
||||||
|
}
|
||||||
|
}
|
55
src/sparrowshell.h
Normal file
55
src/sparrowshell.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef SPARROWSHELL_H
|
||||||
|
#define SPARROWSHELL_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "scene.h"
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
class Input;
|
||||||
|
|
||||||
|
namespace sf {
|
||||||
|
class Window;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SparrowShell : public SceneNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class ScrollBar{
|
||||||
|
SparrowShell* m_shell;
|
||||||
|
glm::ivec2 m_position;
|
||||||
|
glm::ivec2 m_dimension;
|
||||||
|
//TODO : Add rectangle mesh
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScrollBar();
|
||||||
|
ScrollBar(SparrowShell* shell);
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int BUFFER_MAX_LENGTH;
|
||||||
|
static const int BUFFER_DISPLAYED_NUMBER;
|
||||||
|
static const int SCROLLBAR_PIXEL_WIDTH;
|
||||||
|
|
||||||
|
std::list<std::string> m_buffer;
|
||||||
|
sf::Window* m_window;
|
||||||
|
Input* m_input;
|
||||||
|
int m_index = 0;
|
||||||
|
|
||||||
|
glm::ivec2 m_position;
|
||||||
|
glm::ivec2 m_dimension;
|
||||||
|
|
||||||
|
//textMesh
|
||||||
|
ScrollBar m_scrollbar;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SparrowShell(sf::Window*, Input*);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void scrollUp();
|
||||||
|
void scrollDown();
|
||||||
|
void out(std::string);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPARROWSHELL_H
|
28
src/system.cpp
Normal file
28
src/system.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include "messagebus.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
System::System()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
InputSystem::InputSystem(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputSystem::initInput(sf::Window *window){
|
||||||
|
m_input = new Input(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputSystem::update(){
|
||||||
|
int action;
|
||||||
|
Message* message;
|
||||||
|
while (action = m_input->getAction() != NO_ACTION){
|
||||||
|
message = new Message(std::to_string(action),SystemType::INPUT_SYSTEM);
|
||||||
|
m_msgBus->postMessage(message);
|
||||||
|
}
|
||||||
|
}
|
36
src/system.h
Normal file
36
src/system.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef SYSTEM_H
|
||||||
|
#define SYSTEM_H
|
||||||
|
|
||||||
|
class MessageBus;
|
||||||
|
class Message;
|
||||||
|
class Input;
|
||||||
|
|
||||||
|
namespace sf{
|
||||||
|
class Window;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:complete this part with other existing system,
|
||||||
|
enum SystemType {INPUT_SYSTEM, RENDERER_SYSTEM, IA_SYSTEM,GAME_SYSTEM,LENGTH};
|
||||||
|
|
||||||
|
class System
|
||||||
|
{
|
||||||
|
SystemType m_type;
|
||||||
|
protected:
|
||||||
|
MessageBus* m_msgBus;
|
||||||
|
|
||||||
|
public:
|
||||||
|
System();
|
||||||
|
virtual void handleMessage(Message* message) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputSystem : public System{
|
||||||
|
private:
|
||||||
|
Input* m_input;
|
||||||
|
public:
|
||||||
|
InputSystem();
|
||||||
|
~InputSystem();
|
||||||
|
void initInput(sf::Window* window);
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SYSTEM_H
|
@ -5,27 +5,22 @@ using namespace std;
|
|||||||
|
|
||||||
GraphNode::GraphNode()
|
GraphNode::GraphNode()
|
||||||
{
|
{
|
||||||
m_neighbours = vector<GraphEdge>();
|
m_neighbours = vector<GraphNode*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphNode::GraphNode(vector<GraphEdge> neighbours):m_neighbours(neighbours)
|
GraphNode::GraphNode(vector<GraphNode*> neighbours):m_neighbours(neighbours)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphNode::addNeighbours(GraphNode* n,float f){
|
void GraphNode::addNeighbours(GraphNode* node){
|
||||||
GraphEdge edge = GraphEdge(n,f);
|
m_neighbours.push_back(node);
|
||||||
addNeighbours(edge);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GraphNode::addNeighbours(GraphEdge edge){
|
|
||||||
m_neighbours.push_back(edge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GraphNode::getNbNeighbours(){
|
int GraphNode::getNbNeighbours(){
|
||||||
return m_neighbours.size();
|
return m_neighbours.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<GraphEdge> GraphNode::getNeighbours(){
|
vector<GraphNode*> GraphNode::getNeighbours(){
|
||||||
return m_neighbours;
|
return m_neighbours;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,11 +28,6 @@ void GraphNode::print(std::string prefix)
|
|||||||
{
|
{
|
||||||
cout << prefix << "Node_id : ";
|
cout << prefix << "Node_id : ";
|
||||||
cout << prefix << m_testvalue << endl;
|
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){
|
void GraphNode::setValue(int a){
|
||||||
@ -48,15 +38,11 @@ int GraphNode::getValue(){
|
|||||||
return m_testvalue;
|
return m_testvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphNode::setPriority(float priority){
|
||||||
|
m_priority = priority;
|
||||||
GraphEdge::GraphEdge(GraphNode* gn,float v):m_target(gn),m_weight(v)
|
|
||||||
{}
|
|
||||||
|
|
||||||
GraphNode* GraphEdge::getTarget(){
|
|
||||||
return m_target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float GraphEdge::getWeight(){
|
float GraphNode::getPriority(){
|
||||||
return m_weight;
|
return m_priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,32 +8,31 @@ class GraphEdge;
|
|||||||
|
|
||||||
class GraphNode
|
class GraphNode
|
||||||
{
|
{
|
||||||
std::vector<GraphEdge> m_neighbours;
|
std::vector<GraphNode*> m_neighbours;
|
||||||
int m_testvalue; //temp variable
|
int m_testvalue; //temp variable
|
||||||
|
float m_priority;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphNode();
|
GraphNode();
|
||||||
GraphNode(std::vector<GraphEdge>);
|
GraphNode(std::vector<GraphNode*>);
|
||||||
|
|
||||||
std::vector<GraphEdge> getNeighbours();
|
std::vector<GraphNode*> getNeighbours();
|
||||||
void addNeighbours(GraphNode*,float);
|
void addNeighbours(GraphNode*);
|
||||||
void addNeighbours(GraphEdge);
|
|
||||||
int getNbNeighbours();
|
int getNbNeighbours();
|
||||||
virtual float heuristic(GraphNode*){return 1;};
|
virtual float cost(GraphNode*){
|
||||||
|
std::cout << "WARNING : You're using the default cost function. For better result, redefine the cost function in GraphNode." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual float heuristic(GraphNode*){
|
||||||
|
std::cout << "WARNING : You're using the default heuristic function. For better result, redefine the heuristic function in GraphNode." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void setValue(int);
|
void setValue(int);
|
||||||
int getValue();
|
int getValue();
|
||||||
|
void setPriority(float);
|
||||||
|
float getPriority();
|
||||||
void print(std::string prefix);
|
void print(std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GraphEdge
|
|
||||||
{
|
|
||||||
GraphNode* m_target;
|
|
||||||
float m_weight;
|
|
||||||
|
|
||||||
public:
|
|
||||||
GraphEdge(GraphNode*,float);
|
|
||||||
GraphNode* getTarget();
|
|
||||||
float getWeight();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GRAPH_H
|
#endif // GRAPH_H
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <cstring>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include "../resourcemanager.h"
|
||||||
#include <SFML/Graphics/Image.hpp>
|
#include <SFML/Graphics/Image.hpp>
|
||||||
|
#include <mesh.h>
|
||||||
|
#include <phongmaterial.h>
|
||||||
|
#include "../sparrowrenderer/src/texture.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
std::string Loader::obj_directory = "";
|
||||||
|
std::string Loader::mtl_directory = "";
|
||||||
|
std::string Loader::tex_directory = "";
|
||||||
|
|
||||||
|
|
||||||
std::string* Loader::loadTextFile(const std::string &filename)
|
std::string* Loader::loadTextFile(const std::string &filename)
|
||||||
{
|
{
|
||||||
@ -21,7 +33,7 @@ std::string* Loader::loadTextFile(const std::string &filename)
|
|||||||
Image* Loader::loadImage(const std::string &filename, bool hasAlpha)
|
Image* Loader::loadImage(const std::string &filename, bool hasAlpha)
|
||||||
{
|
{
|
||||||
sf::Image sfImg;
|
sf::Image sfImg;
|
||||||
sfImg.loadFromFile(filename);
|
sfImg.loadFromFile(tex_directory+filename);
|
||||||
Image* img = new Image();
|
Image* img = new Image();
|
||||||
img->depth = hasAlpha ? 32 : 24;
|
img->depth = hasAlpha ? 32 : 24;
|
||||||
img->width = sfImg.getSize().x;
|
img->width = sfImg.getSize().x;
|
||||||
@ -39,3 +51,285 @@ Image* Loader::loadImage(const std::string &filename, bool hasAlpha)
|
|||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Mesh*> Loader::loadMesh(const std::string &filename){
|
||||||
|
std::vector<Mesh*> meshes;
|
||||||
|
|
||||||
|
std::vector<glm::vec3> pos;
|
||||||
|
std::vector<glm::vec3> norm;
|
||||||
|
std::vector<glm::vec2> tex;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
Material* defaultMat = RESOURCE_GET(Material, "default");
|
||||||
|
|
||||||
|
if(defaultMat == NULL)
|
||||||
|
{
|
||||||
|
defaultMat = new PhongMaterial();
|
||||||
|
RESOURCE_ADD(defaultMat,Material,"default");
|
||||||
|
}
|
||||||
|
Material* currentMat = defaultMat;
|
||||||
|
std::ifstream file(obj_directory + filename);
|
||||||
|
|
||||||
|
if(!file.is_open())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "can't load %s.\n", filename.c_str());
|
||||||
|
return meshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh* currentMesh = new Mesh();
|
||||||
|
meshes.push_back(currentMesh);
|
||||||
|
currentMesh->setMaterial(currentMat);
|
||||||
|
|
||||||
|
std::getline(file, line);
|
||||||
|
while(!file.eof())
|
||||||
|
{
|
||||||
|
if(line.length() == 0) // line vide
|
||||||
|
{
|
||||||
|
std::getline(file, line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(line[0])
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
//vertex attribute
|
||||||
|
switch(line[1])
|
||||||
|
{
|
||||||
|
case ' ': // vertex position
|
||||||
|
{
|
||||||
|
glm::vec3 p;
|
||||||
|
std::sscanf(line.c_str(),"v %f %f %f",&(p.x),&(p.y),&(p.z));
|
||||||
|
pos.push_back(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 't': // texCoord
|
||||||
|
{
|
||||||
|
glm::vec2 t;
|
||||||
|
std::sscanf(line.c_str(),"vt %f %f",&(t.x),&(t.y));
|
||||||
|
tex.push_back(t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'n': // normal
|
||||||
|
{
|
||||||
|
glm::vec3 n;
|
||||||
|
std::sscanf(line.c_str(),"vn %f %f %f",&(n.x),&(n.y),&(n.z));
|
||||||
|
norm.push_back(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f': // face
|
||||||
|
{
|
||||||
|
int tab[9];
|
||||||
|
std::sscanf(line.c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d",tab,tab+1,tab+2,tab+3,tab+4,tab+5,tab+6,tab+7,tab+8);
|
||||||
|
//TODO: check sscanf success
|
||||||
|
|
||||||
|
int nb_vertices = currentMesh->positions3D.size();
|
||||||
|
|
||||||
|
currentMesh->addTriangle(nb_vertices, nb_vertices+1, nb_vertices+2);
|
||||||
|
for(int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
if(norm.size() == 0)
|
||||||
|
{
|
||||||
|
if(tex.size() == 0)
|
||||||
|
currentMesh->addVertex(pos[tab[i]-1]);
|
||||||
|
else
|
||||||
|
currentMesh->addVertex(pos[tab[i]-1], tex[tab[i+1]-1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(tex.size() == 0)
|
||||||
|
currentMesh->addVertex(pos[tab[i]-1], norm[tab[i+2]-1]);
|
||||||
|
else
|
||||||
|
currentMesh->addVertex(pos[tab[i]-1], norm[tab[i+2]-1], tex[tab[i+1]-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
currentMesh = new Mesh();
|
||||||
|
meshes.push_back(currentMesh);
|
||||||
|
currentMesh->setMaterial(currentMat);
|
||||||
|
break;
|
||||||
|
case 'm': // mtllib
|
||||||
|
{
|
||||||
|
char mat_filename[256];
|
||||||
|
std::sscanf(line.c_str(),"mtllib %s",mat_filename);
|
||||||
|
loadMTL(std::string(mat_filename));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'u':
|
||||||
|
{
|
||||||
|
// usemtl
|
||||||
|
char mat_name[256];
|
||||||
|
std::sscanf(line.c_str(),"usemtl %s",mat_name);
|
||||||
|
std::string material_name(mat_name);
|
||||||
|
currentMat = RESOURCE_GET(Material, material_name);
|
||||||
|
if(currentMat == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cannot find any material named : %s.\n", material_name.c_str());
|
||||||
|
currentMat = new PhongMaterial();
|
||||||
|
RESOURCE_ADD(currentMat,Material,material_name);
|
||||||
|
}
|
||||||
|
currentMesh->setMaterial(currentMat);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case '#':
|
||||||
|
// comment
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::getline(file,line);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(std::size_t i=0; i<meshes.size(); ++i)
|
||||||
|
{
|
||||||
|
if(meshes[i]->indices.size() == 0)
|
||||||
|
{
|
||||||
|
meshes[i] = meshes.back();
|
||||||
|
meshes.pop_back();
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return meshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//move this to an utils file ?
|
||||||
|
std::vector<std::string> split(const std::string &line, char sep){
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
std::size_t start=0, end=0;
|
||||||
|
while((end = line.find(sep,start)) != std::string::npos){
|
||||||
|
tokens.push_back(line.substr(start,end-start));
|
||||||
|
start=end+1;
|
||||||
|
}
|
||||||
|
tokens.push_back(line.substr(start));
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load MTL
|
||||||
|
bool Loader::loadMTL(const std::string &filename)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream file(mtl_directory + filename);
|
||||||
|
|
||||||
|
if(!file.is_open())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "can't load %s.\n", filename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhongMaterial* mat = NULL;
|
||||||
|
bool hasNormalMap = false;
|
||||||
|
|
||||||
|
std::getline(file,line);
|
||||||
|
|
||||||
|
while(!file.eof())
|
||||||
|
{
|
||||||
|
if(line.length() == 0)
|
||||||
|
{
|
||||||
|
std::getline(file,line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//QStringList tokens = line.split(' ');
|
||||||
|
std::vector<std::string> tokens = split(line,' ');
|
||||||
|
|
||||||
|
if(tokens[0].substr(0,1) == "#")
|
||||||
|
{
|
||||||
|
// this is a comment
|
||||||
|
}
|
||||||
|
else if((tokens[0] == "newmtl") && tokens.size() == 2)
|
||||||
|
{
|
||||||
|
mat = new PhongMaterial();
|
||||||
|
RESOURCE_ADD(mat,Material,tokens[1]);
|
||||||
|
}
|
||||||
|
else if((tokens[0].compare("Ka") == 0) && tokens.size() == 4)
|
||||||
|
{
|
||||||
|
mat->ambient.r = std::stof(tokens[1]);
|
||||||
|
mat->ambient.g = std::stof(tokens[2]);
|
||||||
|
mat->ambient.b = std::stof(tokens[3]);
|
||||||
|
}
|
||||||
|
else if(tokens[0].compare("Kd") == 0 && tokens.size() == 4)
|
||||||
|
{
|
||||||
|
mat->diffuse.r = std::stof(tokens[1]);
|
||||||
|
mat->diffuse.g = std::stof(tokens[2]);
|
||||||
|
mat->diffuse.b = std::stof(tokens[3]);
|
||||||
|
}
|
||||||
|
else if(tokens[0].compare("Ks") == 0 && tokens.size() == 4)
|
||||||
|
{
|
||||||
|
mat->specular.r = std::stof(tokens[1]);
|
||||||
|
mat->specular.g = std::stof(tokens[2]);
|
||||||
|
mat->specular.b = std::stof(tokens[3]);
|
||||||
|
}
|
||||||
|
else if(tokens[0].compare("Ns") == 0 && tokens.size() == 2)
|
||||||
|
{
|
||||||
|
mat->shininess = std::stof(tokens[1]);
|
||||||
|
}
|
||||||
|
else if((tokens[0].substr(0,4) == "map_") && tokens.size() == 2)
|
||||||
|
{
|
||||||
|
if(tokens[0].compare("map_Ka") == 0){
|
||||||
|
mat->ambient_texture = RESOURCE_GET(Texture,tokens[1]);
|
||||||
|
if (mat->ambient_texture == NULL){
|
||||||
|
mat->ambient_texture = new Texture(loadImage(tokens[1]));
|
||||||
|
RESOURCE_ADD(mat->ambient_texture,Texture,tokens[1]);
|
||||||
|
}
|
||||||
|
} else if(tokens[0].compare("map_Kd") == 0) {
|
||||||
|
mat->diffuse_texture = RESOURCE_GET(Texture,tokens[1]);
|
||||||
|
if (mat->diffuse_texture == NULL){
|
||||||
|
mat->diffuse_texture = new Texture(loadImage(tokens[1]));
|
||||||
|
RESOURCE_ADD(mat->diffuse_texture,Texture,tokens[1]);
|
||||||
|
}
|
||||||
|
} else if(tokens[0].compare("map_Ks") == 0) {
|
||||||
|
mat->specular_texture = RESOURCE_GET(Texture,tokens[1]);
|
||||||
|
if (mat->specular_texture == NULL){
|
||||||
|
mat->specular_texture = new Texture(loadImage(tokens[1]));
|
||||||
|
RESOURCE_ADD(mat->specular_texture,Texture,tokens[1]);
|
||||||
|
}
|
||||||
|
} else if(tokens[0].compare("map_Normal") == 0) {
|
||||||
|
mat->normal_map = RESOURCE_GET(Texture,tokens[1]);
|
||||||
|
if (mat->normal_map == NULL){
|
||||||
|
mat->normal_map = new Texture(loadImage(tokens[1]));
|
||||||
|
RESOURCE_ADD(mat->normal_map,Texture,tokens[1]);
|
||||||
|
}
|
||||||
|
hasNormalMap = true;
|
||||||
|
} else if(tokens[0].compare("map_d") == 0) {
|
||||||
|
mat->alpha_mask = RESOURCE_GET(Texture,tokens[1]);
|
||||||
|
if (mat->alpha_mask == NULL){
|
||||||
|
mat->alpha_mask = new Texture(loadImage(tokens[1]));
|
||||||
|
RESOURCE_ADD(mat->alpha_mask,Texture,tokens[1]);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "unsupported material property : \"%s\"\n", tokens[0].c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stderr, "unsupported material property : \"%s\"\n", tokens[0].c_str());
|
||||||
|
|
||||||
|
std::getline(file,line);
|
||||||
|
}
|
||||||
|
return hasNormalMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::setObjDirectory(std::string dir_){
|
||||||
|
obj_directory = dir_;
|
||||||
|
}
|
||||||
|
void Loader::setMtlDirectory(std::string dir_){
|
||||||
|
mtl_directory = dir_;
|
||||||
|
}
|
||||||
|
void Loader::setTexDirectory(std::string dir_){
|
||||||
|
tex_directory = dir_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//glfinish
|
||||||
|
void temp_glfinish(){
|
||||||
|
for(std::size_t i=0; i<images.size(); ++i)
|
||||||
|
{
|
||||||
|
if(images[i]){
|
||||||
|
images[i]->initGL();
|
||||||
|
todos[i].target = images[i]->texture;
|
||||||
|
delete images[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@ -2,14 +2,26 @@
|
|||||||
#define LOADER_H
|
#define LOADER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Image;
|
class Image;
|
||||||
|
class Mesh;
|
||||||
|
|
||||||
class Loader
|
class Loader
|
||||||
{
|
{
|
||||||
|
static std::string obj_directory;
|
||||||
|
static std::string mtl_directory;
|
||||||
|
static std::string tex_directory;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::string* loadTextFile(const std::string &filename);
|
static std::string* loadTextFile(const std::string &filename);
|
||||||
static Image* loadImage(const std::string &filename, bool hasAlpha = true);
|
static Image* loadImage(const std::string &filename, bool hasAlpha = true);
|
||||||
|
static std::vector<Mesh*> loadMesh(const std::string &filename);
|
||||||
|
static bool loadMTL(const std::string &filename);
|
||||||
|
|
||||||
|
static void setObjDirectory(std::string);
|
||||||
|
static void setMtlDirectory(std::string);
|
||||||
|
static void setTexDirectory(std::string);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOADER_H
|
#endif // LOADER_H
|
||||||
|
@ -3,59 +3,128 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
//#include "fiboheap.h"
|
//#include "fiboheap.h"
|
||||||
|
|
||||||
PathFinder::PathFinder(){
|
PathFinder::PathFinder(){
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal)
|
std::vector<GraphNode*> PathFinder::a_star(GraphNode* start, GraphNode* goal, bool debug)
|
||||||
{
|
{
|
||||||
// Check if priorityqueue sort value in right order.
|
// Check if priorityqueue sort value in right order.
|
||||||
std::priority_queue<PriorityNode*> frontier = std::priority_queue<PriorityNode*>();
|
std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority> frontier = std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority>();
|
||||||
std::map<GraphNode*, float> cost = std::map<GraphNode*, float>(); //cost of visited node
|
std::map<GraphNode*, float> cost = std::map<GraphNode*, float>(); //cost of visited node
|
||||||
std::map<GraphNode*, GraphNode*> pred = std::map<GraphNode*, GraphNode*>(); //pred of visited node
|
std::map<GraphNode*, GraphNode*> pred = std::map<GraphNode*, GraphNode*>(); //pred of visited node
|
||||||
|
|
||||||
|
std::set<GraphNode*> visited = std::set<GraphNode*>();
|
||||||
|
|
||||||
// init frontier, cost, and pred with value for start
|
// init frontier, cost, and pred with value for start
|
||||||
PriorityNode* pn = new PriorityNode();
|
frontier.push(start);
|
||||||
pn->node = std::pair<GraphNode*,float>(start,0);
|
|
||||||
frontier.push(pn);
|
|
||||||
cost.insert(std::pair<GraphNode*,float>(start,0));
|
cost.insert(std::pair<GraphNode*,float>(start,0));
|
||||||
pred.insert(std::pair<GraphNode*,GraphNode*>(start,NULL));
|
pred.insert(std::pair<GraphNode*,GraphNode*>(start,NULL));
|
||||||
|
|
||||||
GraphNode* current;
|
GraphNode* current;
|
||||||
while(!frontier.empty()){
|
while(!frontier.empty()){
|
||||||
//pick best element from frontier (with priority queue the best is in front)
|
//pick best element from frontier (with priority queue the best is in front)
|
||||||
pn = frontier.top();
|
current = frontier.top();
|
||||||
current = pn->node.first;
|
//current = pn->node.first;
|
||||||
frontier.pop();
|
frontier.pop();
|
||||||
|
if (visited.count(current) == 0)
|
||||||
|
visited.insert(current);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(debug) std::cout << "Exploring node " << current->getValue() << std::endl;
|
||||||
// goal reached, end of a-star
|
// goal reached, end of a-star
|
||||||
if (current == goal){
|
if (current == goal){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for all neighbours of current node
|
// for all neighbours of current node
|
||||||
for (GraphEdge next : current->getNeighbours()){
|
for (GraphNode* next : current->getNeighbours()){
|
||||||
float new_cost = cost[current] + next.getWeight();
|
float new_cost = cost[current] + current->cost(next);
|
||||||
|
if(debug) std::cout << "\tExploring neighbours node " << next->getValue() << " with cost " << new_cost << std::endl;
|
||||||
|
|
||||||
if ((cost.count(next.getTarget()) == 0) || (new_cost < cost[next.getTarget()])){
|
if ((cost.count(next) == 0) || (new_cost < cost[next])){
|
||||||
// affect processed cost to next node in cost_map
|
// affect processed cost to next node in cost_map
|
||||||
cost[next.getTarget()] = new_cost;
|
cost[next] = new_cost;
|
||||||
|
|
||||||
// calcul priority of node with heuristic,and add it to frontier
|
// calcul priority of node with heuristic,and add it to frontier
|
||||||
float priority = new_cost; //+ heuristic(next.getTarget(), goal);
|
float priority = new_cost + next->heuristic(goal);
|
||||||
PriorityNode* pn = new PriorityNode();
|
if(debug) std::cout << "\t\t Priority: " << priority << std::endl;
|
||||||
pn->node = std::pair<GraphNode*,float>(next.getTarget(),priority);
|
next->setPriority(priority);
|
||||||
frontier.push(pn);
|
visited.erase(next);
|
||||||
|
frontier.push(next);
|
||||||
// memorize predecessor for next
|
// memorize predecessor for next
|
||||||
pred[next.getTarget()] = current;
|
pred[next] = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(debug) std::cout << "path cost :" << cost[goal] << std::endl;
|
||||||
|
return backtrack_path(start,goal,pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GraphNode*> PathFinder::a_star_min_max(GraphNode* start,GraphNode* goal,bool debug)
|
||||||
|
{
|
||||||
|
std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority> frontier = std::priority_queue<GraphNode*,std::vector<GraphNode*>,ComparePriority>();
|
||||||
|
std::map<GraphNode*, float> cost = std::map<GraphNode*, float>(); //cost of visited node
|
||||||
|
std::map<GraphNode*, GraphNode*> pred = std::map<GraphNode*, GraphNode*>(); //pred of visited node
|
||||||
|
|
||||||
|
std::set<GraphNode*> visited = std::set<GraphNode*>();
|
||||||
|
|
||||||
|
// init frontier, cost, and pred with value for start
|
||||||
|
frontier.push(start);
|
||||||
|
cost.insert(std::pair<GraphNode*,float>(start,0));
|
||||||
|
pred.insert(std::pair<GraphNode*,GraphNode*>(start,NULL));
|
||||||
|
|
||||||
|
GraphNode* current;
|
||||||
|
while(!frontier.empty()){
|
||||||
|
//pick best element from frontier (with priority queue the best is in front)
|
||||||
|
current = frontier.top();
|
||||||
|
//current = pn->node.first;
|
||||||
|
frontier.pop();
|
||||||
|
if (visited.count(current) == 0)
|
||||||
|
visited.insert(current);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(debug) std::cout << "Exploring node " << current->getValue() << std::endl;
|
||||||
|
// goal reached, end of a-star
|
||||||
|
if (current == goal){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for all neighbours of current node
|
||||||
|
for (GraphNode* next : current->getNeighbours()){
|
||||||
|
float new_cost = std::max(cost[current],current->cost(next));
|
||||||
|
if(debug) std::cout << "\tExploring neighbours node " << next->getValue() << " with cost " << new_cost << std::endl;
|
||||||
|
|
||||||
|
if ((cost.count(next) == 0) || (new_cost < cost[next])){
|
||||||
|
// affect processed cost to next node in cost_map
|
||||||
|
cost[next] = new_cost;
|
||||||
|
|
||||||
|
// calcul priority of node with heuristic,and add it to frontier
|
||||||
|
float priority = new_cost + next->heuristic(goal);
|
||||||
|
if(debug) std::cout << "\t\t Priority: " << priority << std::endl;
|
||||||
|
next->setPriority(priority);
|
||||||
|
visited.erase(next);
|
||||||
|
frontier.push(next);
|
||||||
|
// memorize predecessor for next
|
||||||
|
pred[next] = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(debug) std::cout << "path cost :" << cost[goal] << std::endl;
|
||||||
|
return backtrack_path(start,goal,pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GraphNode*> PathFinder::backtrack_path(GraphNode* start,GraphNode* goal, std::map<GraphNode*, GraphNode*> pred){
|
||||||
// reconstruct path by backtracking from goal to start
|
// reconstruct path by backtracking from goal to start
|
||||||
std::vector<GraphNode*> path = std::vector<GraphNode*>();
|
std::vector<GraphNode*> path = std::vector<GraphNode*>();
|
||||||
|
GraphNode* current = goal;
|
||||||
while(current != start){
|
while(current != start){
|
||||||
path.push_back(current);
|
path.push_back(current);
|
||||||
current = pred[current];
|
current = pred[current];
|
||||||
@ -65,4 +134,7 @@ std::vector<GraphNode*> PathFinder::a_star(GraphNode* start,GraphNode* goal)
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ComparePriority::operator ()(GraphNode* a, GraphNode* b)
|
||||||
|
{
|
||||||
|
return a->getPriority() > b->getPriority();
|
||||||
|
}
|
||||||
|
@ -2,22 +2,23 @@
|
|||||||
#define PATHFINDER_H
|
#define PATHFINDER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
|
|
||||||
class PathFinder
|
class PathFinder
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
static std::vector<GraphNode*> backtrack_path(GraphNode* start,GraphNode* goal, std::map<GraphNode*, GraphNode*> pred);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PathFinder();
|
PathFinder();
|
||||||
static std::vector<GraphNode*> a_star(GraphNode* start,GraphNode* goal);
|
static std::vector<GraphNode*> a_star(GraphNode* start,GraphNode* goal,bool debug = false);
|
||||||
|
static std::vector<GraphNode*> a_star_min_max(GraphNode* start,GraphNode* goal,bool debug = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PriorityNode
|
class ComparePriority{
|
||||||
{
|
public:
|
||||||
std::pair<GraphNode*, float> node;
|
bool operator() (GraphNode*,GraphNode*s);
|
||||||
bool operator<(PriorityNode other) const
|
|
||||||
{
|
|
||||||
return node.second < other.node.second;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PATHFINDER_H
|
#endif // PATHFINDER_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user