85 lines
2.4 KiB
C
85 lines
2.4 KiB
C
|
#define HL_NAME(n) fmt_##n
|
||
|
#include <mikktspace.h>
|
||
|
#include <hl.h>
|
||
|
|
||
|
typedef struct {
|
||
|
hl_type *t;
|
||
|
float *buffer;
|
||
|
int stride;
|
||
|
int xpos;
|
||
|
int normalPos;
|
||
|
int uvPos;
|
||
|
float *tangents;
|
||
|
int tangentsStride;
|
||
|
int tangentPos;
|
||
|
int *indexes;
|
||
|
int indices;
|
||
|
} user_info;
|
||
|
|
||
|
typedef const SMikkTSpaceContext Mikkt;
|
||
|
|
||
|
static int get_num_faces( Mikkt *ctx ) {
|
||
|
user_info *i = (user_info*)ctx->m_pUserData;
|
||
|
return i->indices / 3;
|
||
|
}
|
||
|
|
||
|
static int get_num_vertices( Mikkt *ctx, int face ) {
|
||
|
return 3;
|
||
|
}
|
||
|
|
||
|
static void get_position( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
|
||
|
user_info *i = (user_info*)ctx->m_pUserData;
|
||
|
int idx = iFace * 3 + iVert;
|
||
|
int v = i->indexes[idx];
|
||
|
int p = v * i->stride + i->xpos;
|
||
|
fvPosOut[0] = i->buffer[p++];
|
||
|
fvPosOut[1] = i->buffer[p++];
|
||
|
fvPosOut[2] = i->buffer[p++];
|
||
|
}
|
||
|
|
||
|
static void get_normal( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
|
||
|
user_info *i = (user_info*)ctx->m_pUserData;
|
||
|
int idx = iFace * 3 + iVert;
|
||
|
int v = i->indexes[idx];
|
||
|
int p = v * i->stride + i->normalPos;
|
||
|
fvPosOut[0] = i->buffer[p++];
|
||
|
fvPosOut[1] = i->buffer[p++];
|
||
|
fvPosOut[2] = i->buffer[p++];
|
||
|
}
|
||
|
|
||
|
static void get_tcoord( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
|
||
|
user_info *i = (user_info*)ctx->m_pUserData;
|
||
|
int idx = iFace * 3 + iVert;
|
||
|
int v = i->indexes[idx];
|
||
|
int p = v * i->stride + i->uvPos;
|
||
|
fvPosOut[0] = i->buffer[p++];
|
||
|
fvPosOut[1] = i->buffer[p++];
|
||
|
}
|
||
|
|
||
|
static void set_tangent( Mikkt *ctx, const float fvTangent[], const float fSign, const int iFace, const int iVert ) {
|
||
|
user_info *i = (user_info*)ctx->m_pUserData;
|
||
|
int idx = iFace * 3 + iVert;
|
||
|
int p = idx * i->tangentsStride + i->tangentPos;
|
||
|
i->tangents[p++] = fvTangent[0];
|
||
|
i->tangents[p++] = fvTangent[1];
|
||
|
i->tangents[p++] = fvTangent[2];
|
||
|
i->tangents[p++] = fSign;
|
||
|
}
|
||
|
|
||
|
HL_PRIM bool HL_NAME(compute_mikkt_tangents)( user_info *inf, double threshold ) {
|
||
|
SMikkTSpaceContext ctx;
|
||
|
SMikkTSpaceInterface intf;
|
||
|
intf.m_getNumFaces = get_num_faces;
|
||
|
intf.m_getNumVerticesOfFace = get_num_vertices;
|
||
|
intf.m_getPosition = get_position;
|
||
|
intf.m_getNormal = get_normal;
|
||
|
intf.m_getTexCoord = get_tcoord;
|
||
|
intf.m_setTSpaceBasic = set_tangent;
|
||
|
intf.m_setTSpace = NULL;
|
||
|
ctx.m_pInterface = &intf;
|
||
|
ctx.m_pUserData = inf;
|
||
|
return genTangSpace(&ctx, (float)threshold);
|
||
|
}
|
||
|
|
||
|
DEFINE_PRIM(_BOOL, compute_mikkt_tangents, _DYN _F64);
|