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