mikkt.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #define HL_NAME(n) heaps_##n
  2. #include <mikktspace.h>
  3. #include <hl.h>
  4. typedef struct {
  5. hl_type *t;
  6. float *buffer;
  7. int stride;
  8. int xpos;
  9. int normalPos;
  10. int uvPos;
  11. float *tangents;
  12. int tangentsStride;
  13. int tangentPos;
  14. int *indexes;
  15. int indices;
  16. } user_info;
  17. typedef const SMikkTSpaceContext Mikkt;
  18. static int get_num_faces( Mikkt *ctx ) {
  19. user_info *i = (user_info*)ctx->m_pUserData;
  20. return i->indices / 3;
  21. }
  22. static int get_num_vertices( Mikkt *ctx, int face ) {
  23. return 3;
  24. }
  25. static void get_position( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
  26. user_info *i = (user_info*)ctx->m_pUserData;
  27. int idx = iFace * 3 + iVert;
  28. int v = i->indexes[idx];
  29. int p = v * i->stride + i->xpos;
  30. fvPosOut[0] = i->buffer[p++];
  31. fvPosOut[1] = i->buffer[p++];
  32. fvPosOut[2] = i->buffer[p++];
  33. }
  34. static void get_normal( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
  35. user_info *i = (user_info*)ctx->m_pUserData;
  36. int idx = iFace * 3 + iVert;
  37. int v = i->indexes[idx];
  38. int p = v * i->stride + i->normalPos;
  39. fvPosOut[0] = i->buffer[p++];
  40. fvPosOut[1] = i->buffer[p++];
  41. fvPosOut[2] = i->buffer[p++];
  42. }
  43. static void get_tcoord( Mikkt *ctx, float fvPosOut[], const int iFace, const int iVert ) {
  44. user_info *i = (user_info*)ctx->m_pUserData;
  45. int idx = iFace * 3 + iVert;
  46. int v = i->indexes[idx];
  47. int p = v * i->stride + i->uvPos;
  48. fvPosOut[0] = i->buffer[p++];
  49. fvPosOut[1] = i->buffer[p++];
  50. }
  51. static void set_tangent( Mikkt *ctx, const float fvTangent[], const float fSign, const int iFace, const int iVert ) {
  52. user_info *i = (user_info*)ctx->m_pUserData;
  53. int idx = iFace * 3 + iVert;
  54. int p = idx * i->tangentsStride + i->tangentPos;
  55. i->tangents[p++] = fvTangent[0];
  56. i->tangents[p++] = fvTangent[1];
  57. i->tangents[p++] = fvTangent[2];
  58. i->tangents[p++] = fSign;
  59. }
  60. HL_PRIM bool HL_NAME(compute_mikkt_tangents)( user_info *inf, double threshold ) {
  61. SMikkTSpaceContext ctx;
  62. SMikkTSpaceInterface intf;
  63. intf.m_getNumFaces = get_num_faces;
  64. intf.m_getNumVerticesOfFace = get_num_vertices;
  65. intf.m_getPosition = get_position;
  66. intf.m_getNormal = get_normal;
  67. intf.m_getTexCoord = get_tcoord;
  68. intf.m_setTSpaceBasic = set_tangent;
  69. intf.m_setTSpace = NULL;
  70. ctx.m_pInterface = &intf;
  71. ctx.m_pUserData = inf;
  72. return genTangSpace(&ctx, (float)threshold);
  73. }
  74. DEFINE_PRIM(_BOOL, compute_mikkt_tangents, _DYN _F64);