paella/include/Animation/AnimatedMesh.hpp

176 lines
7.3 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.
////////////////////////////////////////////////////////////////////////////////
#ifndef ANIMATEDMESH_HPP
#define ANIMATEDMESH_HPP
#include <vector>
#include <unordered_map>
#include <memory>
#include <Geometry/Tree.hpp>
#include <Geometry/Mesh.hpp>
#include <Geometry/Point.hpp>
#include <Geometry/MathFunctions.hpp>
#include <Geometry/Rotation.hpp>
#include <Meshing/Skeleton3D.hpp>
#include <GL/gl.h>
namespace pae
{
///////////////////////////////////////////////////////////
/// \ingroup animation
/// \brief Class representing an animated mesh
///////////////////////////////////////////////////////////
class AnimatedMesh
{
public:
///////////////////////////////////////////////////////////
/// \brief Usual constructor
/// \param skeleton Skeleton to animate
///
/// Create an animated mesh from the skeletton. It opens
/// a GUI to create patellas with the left clic, and choose a root for
/// the trees. The right click must be on an extremity of the mesh.
///////////////////////////////////////////////////////////
AnimatedMesh(Skeleton3D const& skeleton);
///////////////////////////////////////////////////////////
/// \brief OpenGL render function
///
/// Draw the animated mesh with OpenGL
///////////////////////////////////////////////////////////
void draw() const;
geo::Tree<geo::Rotation> rotations; ///< Tree of rotations
std::vector<geo::Path> paths; ///< Vector of paths to access elements in the order
private:
/////////////////////////////////////////////////////////////////////
///
/// \brief find the nearest segment of each point
///
/// \param segments takes a vector for the different splines, containing vectors corresponding to the different segments
/// \param mesh the mesh
///
/// \return the associated segment for each point
///
/////////////////////////////////////////////////////////////////////
void associateBranches(std::vector<geo::Segment<float,3>> const& segments, geo::Mesh& mesh);
//////////////////////////////////////////////////////////////////////
///
/// \brief find a point nearest segment
///
/// \param segments list of skeleton's segments
/// \param p point to project
///
/// \return nearest segment index
///
//////////////////////////////////////////////////////////////////////
unsigned int findNearestSegment(std::vector<geo::Segment<float,3>> const& segments, geo::Point<float> const& p);
//////////////////////////////////////////////////////////////////////
///
/// \brief find the faces associated to each segment
///
/// \param associatedSegments the associated segment for each point
/// \param mesh the mesh
/// \param nbSegments number of segments
///
/// \return faces associated to each segment
///
//////////////////////////////////////////////////////////////////////
void findFaces(std::vector<unsigned int> const& associatedSegments, geo::Mesh& mesh, unsigned int nbSegments);
std::vector<geo::Segment<float,3>> segments; ///< segments of the skeleton
std::vector<geo::Vector3<float>> vertices; ///< Vertices of the mesh
std::vector<unsigned int> associatedSegment; ///< Each element of this vector is the indexes of the associated segment
std::vector<std::vector<geo::Vector3<unsigned int>>> facesPerSegment; ///< Each vector contains the faces of one segment
geo::Tree<int> structure; ///< Tree containing the indices of the vertices. The root is -1
geo::Tree<geo::Vector3<float>> roots; ///< Tree containing the vertices corresponding to the centers of the rotations
geo::Tree<std::vector<geo::Vector3<unsigned int>>> structuredFaces; ///< Faces structured as a tree
std::unordered_map<unsigned int, geo::Path> otherVertices; ///< map providing path to access to vertices in the trees (usefull to find the rotations)
geo::Tree<std::array<float,3>> colors; ///< Tree containg the colors of vertices
};
geo::Tree<int>& genStructure(std::vector<geo::Segment<float,3>> const& segments, geo::Tree<geo::Vector3<float>> const& tree, geo::Tree<int>& ret);
geo::Tree<geo::Vector3<float>>& genStructure(std::vector<geo::Segment<float,3>> const& segments, geo::Tree<geo::Vector3<float>> const& tree, geo::Tree<geo::Vector3<float>>& ret);
geo::Tree<std::vector<geo::Vector3<unsigned int>>>&
genStructuredFaces(
std::vector<std::vector<geo::Vector3<unsigned int>>> const& facesPerSegment,
geo::Tree<int> const& structure,
geo::Tree<std::vector<geo::Vector3<unsigned int>>>& faces
);
std::unordered_map<unsigned int, geo::Path>&
genOtherVertices(
std::vector<geo::Vector3<float>> const& vertices,
std::vector<geo::Vector3<unsigned int>> const& otherFaces,
std::vector<unsigned int> associatedSegment,
geo::Tree<int> const& structure,
std::unordered_map<unsigned int, geo::Path>& ret,
geo::Path path = {}
);
geo::Tree<std::array<float,3>>&
genColors(
geo::Tree<int> const& structure,
geo::Tree<std::array<float,3>>& colors);
geo::Tree<geo::Rotation>&
genRotations(
geo::Tree<geo::Vector3<float>> const& extremities,
geo::Tree<geo::Rotation>& ret
);
std::vector<geo::Path>&
genPaths(
geo::Tree<int> const& structure,
std::vector<geo::Path>& paths,
geo::Path currentPath = {});
void drawTree(std::vector<geo::Vector3<float>> const& vertices, geo::Tree<std::vector<geo::Vector3<unsigned int>>> const& faces, geo::Tree<std::array<float,3>> const& colors, geo::Tree<geo::Vector3<float>> const& extremities, geo::Tree<geo::Rotation> const& rotations);
void drawOthers(std::vector<geo::Vector3<float>> const& vertices, std::unordered_map<unsigned int, geo::Path> const& other_vertices, std::vector<geo::Vector3<unsigned int>> const& faces, geo::Tree<std::array<float,3>> const& colors, geo::Tree<geo::Rotation> const& rotations);
} // namespace pae
#endif // ANIMATEDMESH_HPP