Added some basic geometry functionality (only tangent generation for now).
This commit is contained in:
102
source/mijin/geo/tangent_generation.hpp
Normal file
102
source/mijin/geo/tangent_generation.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(MIJIN_GEO_TANGENT_GENERATION_HPP_INCLUDED)
|
||||
#define MIJIN_GEO_TANGENT_GENERATION_HPP_INCLUDED 1
|
||||
|
||||
#include <mikktspace.h>
|
||||
#include "./geometry_traits.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
template<FullMesh3D TMesh>
|
||||
struct MikktData
|
||||
{
|
||||
Mesh3DTraits<TMesh> traits;
|
||||
Vector2Traits<typename TMesh::vector2_t> vec2Traits;
|
||||
Vector3Traits<typename TMesh::vector3_t> vec3Traits;
|
||||
TMesh* mesh;
|
||||
};
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
int mikktGetNumFaces(const SMikkTSpaceContext* context)
|
||||
{
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
return static_cast<int>(data.traits.getNumFaces(*data.mesh));
|
||||
}
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
int mikktGetNumVerticesOfFace(const SMikkTSpaceContext* context, const int face)
|
||||
{
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
return static_cast<int>(data.traits.getFaceNumVertices(*data.mesh, face));
|
||||
}
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
void mikktGetPosition(const SMikkTSpaceContext* context, float posOut[], const int face, const int vert) // NOLINT
|
||||
{
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
const auto position = data.traits.getPosition(*data.mesh, face, vert);
|
||||
posOut[0] = data.vec3Traits.getX(position);
|
||||
posOut[1] = data.vec3Traits.getY(position);
|
||||
posOut[2] = data.vec3Traits.getZ(position);
|
||||
}
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
void mikktGetNormal(const SMikkTSpaceContext* context, float normOut[], const int face, const int vert) // NOLINT
|
||||
{
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
const auto normal = data.traits.getNormal(*data.mesh, face, vert);
|
||||
normOut[0] = data.vec3Traits.getX(normal);
|
||||
normOut[1] = data.vec3Traits.getY(normal);
|
||||
normOut[2] = data.vec3Traits.getZ(normal);
|
||||
}
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
void mikktGetTexCoord(const SMikkTSpaceContext* context, float texcOut[], const int face, const int vert) // NOLINT
|
||||
{
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
const auto texCoord = data.traits.getTexCoord(*data.mesh, face, vert);
|
||||
texcOut[0] = data.vec2Traits.getX(texCoord);
|
||||
texcOut[1] = data.vec2Traits.getY(texCoord);
|
||||
}
|
||||
|
||||
template<FullMesh3D TMesh>
|
||||
void mikktSetTSpaceBasic(const SMikkTSpaceContext* context, const float resultTangent[], const float sign, const int face, const int vert) // NOLINT
|
||||
{
|
||||
// TODO: what do we do with sign? (it should be used for the direction of the bitangent)
|
||||
(void) sign;
|
||||
const MikktData<TMesh>& data = *static_cast<MikktData<TMesh>*>(context->m_pUserData);
|
||||
typename Mesh3DTraits<TMesh>::vector3_t tangent;
|
||||
data.vec3Traits.setX(tangent, resultTangent[0]);
|
||||
data.vec3Traits.setY(tangent, resultTangent[1]);
|
||||
data.vec3Traits.setZ(tangent, resultTangent[2]);
|
||||
data.traits.setTangent(*data.mesh, face, vert, tangent);
|
||||
}
|
||||
}
|
||||
template<FullMesh3D TMesh>
|
||||
bool generateTangentsMikkt(TMesh& mesh)
|
||||
{
|
||||
SMikkTSpaceInterface mikktInterface = {
|
||||
.m_getNumFaces = &impl::mikktGetNumFaces<TMesh>,
|
||||
.m_getNumVerticesOfFace = &impl::mikktGetNumVerticesOfFace<TMesh>,
|
||||
.m_getPosition = &impl::mikktGetPosition<TMesh>,
|
||||
.m_getNormal = &impl::mikktGetNormal<TMesh>,
|
||||
.m_getTexCoord = &impl::mikktGetTexCoord<TMesh>,
|
||||
.m_setTSpaceBasic = &impl::mikktSetTSpaceBasic<TMesh>
|
||||
};
|
||||
impl::MikktData<TMesh> data = {
|
||||
.mesh = &mesh
|
||||
};
|
||||
const SMikkTSpaceContext context = {
|
||||
.m_pInterface = &mikktInterface,
|
||||
.m_pUserData = &data
|
||||
};
|
||||
return genTangSpaceDefault(&context);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MIJIN_GEO_TANGENT_GENERATION_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user