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);
 |