285 lines
8.0 KiB
C++
285 lines
8.0 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Paella
|
|
// Copyright (C) 2015 - Thomas FORGIONE, Emilie JALRAS, Marion LENFANT, Thierry MALON, Amandine PAILLOUX
|
|
// Authors :
|
|
// Thomas FORGIONE
|
|
// Emilie JALRAS
|
|
// Marion LENFANT
|
|
// Thierry MALON
|
|
// Amandine PAILLOUX
|
|
//
|
|
// This file is part of the project Paella
|
|
// This software is provided 'as-is', without any express or implied warranty.
|
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it freely,
|
|
// subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented;
|
|
// you must not claim that you wrote the original software.
|
|
// If you use this software in a product, an acknowledgment
|
|
// in the product documentation would be appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such,
|
|
// and must not be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <cmath>
|
|
#include <SFML/Window.hpp>
|
|
#include <SFML/Graphics.hpp>
|
|
#include <SFML/OpenGL.hpp>
|
|
#include <GL/gl.h>
|
|
#include <GL/glu.h>
|
|
|
|
#include "SFMLTools/FreeFlyCamera.hpp"
|
|
#include "Geometry/Mesh.hpp"
|
|
#include "Geometry/Vector.hpp"
|
|
#include "Geometry/Point.hpp"
|
|
#include "Meshing/Skeleton3D.hpp"
|
|
|
|
// Full hd : 1920x1080
|
|
constexpr auto WIDTH = 1920;
|
|
constexpr auto HEIGHT = 1080;
|
|
|
|
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh);
|
|
|
|
void drawCircle(geo::Circle<float> const& circle);
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
// Init mesh
|
|
pae::Skeleton3D<geo::Vector3<float>, float> skeleton;
|
|
|
|
if (argc <= 1)
|
|
{
|
|
if (!skeleton.loadFromFile("data/skl/skel.skl"))
|
|
{
|
|
std::cerr << "Default file not found ! Try with a file..." << std::endl;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
auto path = std::string{argv[1]};
|
|
if (!skeleton.loadFromFile(path))
|
|
{
|
|
std::cerr << "File " << path << " not found ! Try with another file..." << std::endl;
|
|
}
|
|
}
|
|
|
|
geo::Mesh mesh;
|
|
std::vector<std::vector<geo::Circle<float>>> splines_circles;
|
|
|
|
unsigned int globalOffset = 0;
|
|
float pointsProportion = 4;
|
|
unsigned int nbPointsPerCircle = 36u;
|
|
unsigned int profondeur = 10;
|
|
|
|
for (auto const& spline : skeleton.splines)
|
|
{
|
|
float l = geo::splineLenght(spline);
|
|
unsigned int nbCirclesOnTheSpline = std::max(static_cast<unsigned int>(std::round(pointsProportion*l)),2u);
|
|
auto spl = spline.computeCircles(nbCirclesOnTheSpline,nbPointsPerCircle,globalOffset);
|
|
splines_circles.push_back(spl);
|
|
mesh += geo::splineMeshing(spl);
|
|
globalOffset+=nbPointsPerCircle*nbCirclesOnTheSpline;
|
|
}
|
|
|
|
// skeleton.meshExtremities(mesh, splines_circles, profondeur);
|
|
|
|
auto circles = skeleton.meshJunctions(mesh,splines_circles);
|
|
|
|
std::vector<geo::Vector3<float>> centers;
|
|
for (auto & c : circles)
|
|
{
|
|
// for (auto& p : c.points)
|
|
// {
|
|
// p.second /= 1000;
|
|
// }
|
|
|
|
// c.center /= 1000;
|
|
|
|
centers.push_back(c.center);
|
|
std::cout << c.center << std::endl;
|
|
for (auto const& pt : c.points)
|
|
{
|
|
std::cout << "\t" << pt.second << std::endl;
|
|
}
|
|
}
|
|
|
|
auto plane = pae::detail::closestPlane<float>(centers);
|
|
|
|
std::cout << plane << std::endl;
|
|
|
|
// Dessin du plan
|
|
auto p1 = geo::Vector3f{-plane.y(), plane.x(), -plane.t() / plane.z()};
|
|
auto v1 = geo::Vector3f{-plane.z(), 0.0f, plane.x()};
|
|
auto v2 = geo::crossProduct(geo::Vector3<float>{plane.x(), plane.y(), plane.z()}, v1);
|
|
|
|
|
|
std::cout << "p1 " << p1 << std::endl;
|
|
v1 /= v1.norm();
|
|
v2 /= v2.norm();
|
|
|
|
auto pt1 = p1 - 5000*v1;
|
|
auto pt2 = p1 + 5000*v2;
|
|
auto pt3 = p1 + 5000*v1;
|
|
auto pt4 = p1 - 5000*v2;
|
|
|
|
std::cout << pt1 << std::endl << pt2 << std::endl;
|
|
|
|
// mesh.prepare();
|
|
|
|
// Création de la fenêtre
|
|
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT),
|
|
"pae",
|
|
sf::Style::Fullscreen,
|
|
sf::ContextSettings(32));
|
|
|
|
window.setVerticalSyncEnabled(true);
|
|
window.setMouseCursorVisible(false);
|
|
|
|
//Initialisation du mode 3D
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,100000);
|
|
|
|
// Initialisation de Z-Buffer
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
// Activer les textures
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
// Autoriser la transparence
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
// Ces 2 lignes améliorent le rendu
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
|
|
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
|
|
|
|
// On efface le tampon d'affichage
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glFlush();
|
|
|
|
// Camera
|
|
auto camera = sft::FreeFlyCamera{};
|
|
|
|
// la boucle principale
|
|
auto running = true;
|
|
auto captureRequired = false;
|
|
while (running)
|
|
{
|
|
// gestion des évènements
|
|
sf::Event event;
|
|
while (window.pollEvent(event))
|
|
{
|
|
if (event.type == sf::Event::Closed)
|
|
{
|
|
// on stoppe le programme
|
|
running = false;
|
|
}
|
|
else if (event.type == sf::Event::KeyPressed)
|
|
{
|
|
if (event.key.code == sf::Keyboard::Escape)
|
|
{
|
|
running = false;
|
|
}
|
|
else if (event.key.code == sf::Keyboard::P)
|
|
{
|
|
captureRequired = true;
|
|
}
|
|
}
|
|
else if (event.type == sf::Event::MouseMoved)
|
|
{
|
|
// Hum...
|
|
}
|
|
else if (event.type == sf::Event::Resized)
|
|
{
|
|
// on ajuste le viewport lorsque la fenêtre est redimensionnée
|
|
glViewport(0, 0, event.size.width, event.size.height);
|
|
}
|
|
|
|
}
|
|
|
|
// Les trucs qui sont pas des évènements
|
|
camera.nextStep(WIDTH, HEIGHT);
|
|
sf::Mouse::setPosition(sf::Vector2i{WIDTH/2, HEIGHT/2});
|
|
|
|
// Dessin de la scene
|
|
drawScene(camera, mesh);
|
|
|
|
for (auto const& c : circles)
|
|
{
|
|
drawCircle(c);
|
|
}
|
|
|
|
glColor4f(1.0,1.0,1.0,0.5);
|
|
glBegin(GL_QUADS);
|
|
glVertex3fv(&pt1.data[0]);
|
|
glVertex3fv(&pt2.data[0]);
|
|
glVertex3fv(&pt3.data[0]);
|
|
glVertex3fv(&pt4.data[0]);
|
|
glEnd();
|
|
glFlush();
|
|
|
|
|
|
if (captureRequired)
|
|
{
|
|
window.capture().saveToFile("capture.jpg");
|
|
captureRequired = false;
|
|
}
|
|
|
|
// termine la trame courante (en interne, échange les deux tampons de rendu)
|
|
window.display();
|
|
}
|
|
|
|
// libération des ressources...
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drawScene(sft::FreeFlyCamera const& camera, geo::Mesh const& mesh)
|
|
{
|
|
// Initialisation
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical)
|
|
camera.look();
|
|
|
|
glBegin(GL_LINES);
|
|
glColor3f(1,0,0);
|
|
glVertex3f(0,0,0);
|
|
glVertex3f(1,0,0);
|
|
glColor3f(0,1,0);
|
|
glVertex3f(0,0,0);
|
|
glVertex3f(0,1,0);
|
|
glColor3f(0,0,1);
|
|
glVertex3f(0,0,0);
|
|
glVertex3f(0,0,1);
|
|
glEnd();
|
|
|
|
// Dessin de carrés
|
|
// mesh.draw();
|
|
|
|
// MAJ de l'écran
|
|
// glFlush();
|
|
}
|
|
|
|
void drawCircle(geo::Circle<float> const& circle)
|
|
{
|
|
glBegin(GL_LINES);
|
|
for (auto const& pt : circle.points)
|
|
glVertex3fv(&pt.second.data[0]);
|
|
glVertex3fv(&circle.points[0].second.data[0]);
|
|
glEnd();
|
|
}
|
|
|