Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.8 KiB

  1. #ifndef OPTIMIZE_SUBD_H
  2. #define OPTIMIZE_SUBD_H
  3. #pragma once
  4. #include "optimize.h"
  5. #include "studio.h"
  6. // Maximum number of points that can be part of a subd quad.
  7. // This includes the 4 interior points of the quad, plus the 1-ring neighborhood
  8. #define MAX_SUBD_POINTS 32
  9. #define MAX_SUBD_ONERING_POINTS (MAX_SUBD_POINTS + 4*5)
  10. #define CORNER_WITH_SMOOTHBNDTANGENTS 2
  11. namespace OptimizedModel
  12. {
  13. struct SubD_Face_t;
  14. // minimal HalfEdge structure, embedded in a face (#halfedges = #vertexperface)
  15. struct HalfEdge
  16. {
  17. HalfEdge *twin;
  18. HalfEdge *sectorStart;
  19. unsigned char localID; // local halfedge/vertex ID
  20. SubD_Face_t *patch;
  21. inline HalfEdge *NextInFace();
  22. inline HalfEdge *PrevInFace();
  23. inline HalfEdge *NextByHead();
  24. inline HalfEdge *PrevByHead();
  25. inline HalfEdge *NextByTail();
  26. inline HalfEdge *PrevByTail();
  27. inline unsigned short &BndEdge();
  28. };
  29. struct Orientation
  30. {
  31. uint8 u : 1;
  32. uint8 v : 1;
  33. uint8 uSet : 1;
  34. uint8 vSet : 1;
  35. void SetU( bool b )
  36. {
  37. Assert( !uSet );
  38. u = b;
  39. uSet = true;
  40. }
  41. void SetV( bool b )
  42. {
  43. Assert( !vSet );
  44. v = b;
  45. vSet = true;
  46. }
  47. Orientation() { uSet = vSet = false; }
  48. };
  49. struct SubD_Face_t
  50. {
  51. unsigned short patchID; // for building our 4 sets of watertight UVs
  52. unsigned short vtxIDs[4];
  53. unsigned short oneRing[MAX_SUBD_ONERING_POINTS];
  54. unsigned short vtx1RingSize[4]; // Pre-calculated prefixes for the first 4 points
  55. unsigned short vtx1RingCenterQuadOffset[4]; // start of inner quad vertices in vertex 1-ring
  56. unsigned short valences[4]; // Valences for the first 4 points in current sector
  57. unsigned short minOneRingIndex[4]; // Location in oneRing array to start applying stencil (determined by lowest position index)
  58. unsigned short bndVtx[4]; // is vertex on the boundary?
  59. unsigned short bndEdge[4]; // is associated edge on the boundary?
  60. unsigned short cornerVtx[4]; // should a boundary-vertex be treated as a corner?
  61. unsigned short nbCornerVtx[4]; // bitfield, for all on-edge neighbors record if corner vertices
  62. unsigned short loopGapAngle[4];
  63. unsigned short edgeBias[8];
  64. unsigned short vUV0[4]; // Vert index for Interior TexCoord (for vtxIDs[0-3])
  65. unsigned short vUV1[4]; // Vert index for Parametric V TexCoord (for vtxIDs[0-3])
  66. unsigned short vUV2[4]; // Vert index for Parametric U TexCoord (for vtxIDs[0-3])
  67. unsigned short vUV3[4]; // Vert index for Corner TexCoord (for vtxIDs[0-3])
  68. HalfEdge halfEdges[4];
  69. void SetEdgeBias(int localID, float f0, float f1)
  70. {
  71. if (halfEdges[localID].twin==NULL) return;
  72. edgeBias[2*localID] = f0 * 32768.0f;
  73. edgeBias[2*localID+1] = f1 * 32768.0f;
  74. halfEdges[localID].twin->patch->edgeBias[ 2*halfEdges[localID].twin->localID+1 ] = (1.0f - f0) * 32768.0f;
  75. halfEdges[localID].twin->patch->edgeBias[ 2*halfEdges[localID].twin->localID ] = (1.0f - f1) * 32768.0f;
  76. }
  77. };
  78. inline HalfEdge *HalfEdge::NextInFace()
  79. {
  80. static int MOD4[8] = {0,1,2,3,0,1,2,3};
  81. return &patch->halfEdges[MOD4[localID+1]];
  82. }
  83. inline HalfEdge *HalfEdge::PrevInFace()
  84. {
  85. static int MOD4[8] = {0,1,2,3,0,1,2,3};
  86. return &patch->halfEdges[MOD4[localID+3]];
  87. }
  88. inline HalfEdge *HalfEdge::NextByHead() { return (twin==NULL)? NULL : twin->PrevInFace(); }
  89. inline HalfEdge *HalfEdge::PrevByHead() { return NextInFace()->twin; }
  90. inline HalfEdge *HalfEdge::NextByTail() { return PrevInFace()->twin; }
  91. inline HalfEdge *HalfEdge::PrevByTail() { return (twin==NULL)? NULL : twin->NextInFace(); }
  92. inline bool FaceIsRegular( SubD_Face_t *patch )
  93. {
  94. return ( patch->valences[0] == 4 && patch->valences[1] == 4 && patch->valences[2] == 4 && patch->valences[3] == 4 ) &&
  95. ( patch->bndVtx[0] == false && patch->bndVtx[1] == false && patch->bndVtx[2] == false && patch->bndVtx[3] == false ) &&
  96. ( patch->bndEdge[0] == false && patch->bndEdge[1] == false && patch->bndEdge[2] == false && patch->bndEdge[3] == false );
  97. }
  98. inline unsigned short &HalfEdge::BndEdge() { return patch->bndEdge[localID]; }
  99. typedef CUtlVector<SubD_Face_t> SubD_FaceList_t;
  100. typedef CUtlVector<Vertex_t> SubD_VertexList_t;
  101. typedef const mstudio_meshvertexdata_t *SubD_VertexData_t;
  102. class COptimizeSubDBuilder
  103. {
  104. public:
  105. COptimizeSubDBuilder(SubD_FaceList_t& subDFaceList, const SubD_VertexList_t& vertexList, const SubD_VertexData_t &vertexData, bool bIsTagged, bool bMendVertices=true );
  106. void ProcessPatches( bool bIsTagged, bool bMendVertices );
  107. HalfEdge *FindTwin(HalfEdge &he);
  108. void CheckForManifoldMesh( );
  109. void BuildNeighborhoodInfo( );
  110. void ComputeSectorStart( SubD_Face_t *quad, unsigned short k );
  111. void ComputePerVertexInfo( SubD_Face_t *baseQuad, unsigned short baseLocalID );
  112. void ComputeSectorAngle( SubD_Face_t *baseQuad, unsigned short baseLocalID );
  113. void ComputeNbCorners( SubD_Face_t *baseQuad, unsigned short baseLocalID );
  114. void ComputeSectorOneRing( SubD_Face_t *baseQuad, unsigned short baseLocalID );
  115. unsigned short FindNeighborVertex( HalfEdge** ppOutMirrorEdge, const HalfEdge *pHalfEdge, int indexAlongEdge );
  116. void ComputeNeighborTexcoords( SubD_Face_t *baseQuad );
  117. void MendVertices( SubD_Face_t *quad, unsigned short baseLocalID );
  118. void TagCreases();
  119. private:
  120. // Routines used for orienting faces for edge consistency
  121. void RotateOnce( SubD_Face_t *pFace );
  122. void RotateFace( SubD_Face_t *pFace, int nTimesToRotate );
  123. int FaceEdgeIndex( SubD_Face_t *pFace, HalfEdge *pEdge );
  124. void Propagate( CUtlVector<Orientation> & orientationArray, HalfEdge *pEdge, bool dir );
  125. void ConsistentPatchOrientation();
  126. void RemapIndices();
  127. void SetMinOneRingIndices();
  128. SubD_FaceList_t &m_faceList;
  129. const SubD_VertexList_t &m_vtxList;
  130. const SubD_VertexData_t &m_vtxData;
  131. int m_numPatches;
  132. CUtlVector<int> m_IndexRemapTable;
  133. };
  134. }; // namespace OptimizedModel
  135. #endif // OPTIMIZE_SUBD_H