patch.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qbsp.h"
  19. void PrintCtrl( vec3_t ctrl[9] ) {
  20. int i, j;
  21. for ( i = 0 ; i < 3 ; i++ ) {
  22. for ( j = 0 ; j < 3 ; j++ ) {
  23. _printf("(%5.2f %5.2f %5.2f) ", ctrl[i*3+j][0], ctrl[i*3+j][1], ctrl[i*3+j][2] );
  24. }
  25. _printf("\n");
  26. }
  27. }
  28. /*
  29. ================
  30. DrawSurfaceForMesh
  31. ================
  32. */
  33. mapDrawSurface_t *DrawSurfaceForMesh( mesh_t *m ) {
  34. mapDrawSurface_t *ds;
  35. int i, j;
  36. mesh_t *copy;
  37. // to make valid normals for patches with degenerate edges,
  38. // we need to make a copy of the mesh and put the aproximating
  39. // points onto the curve
  40. copy = CopyMesh( m );
  41. PutMeshOnCurve( *copy );
  42. MakeMeshNormals( *copy );
  43. for ( j = 0 ; j < m->width ; j++ ) {
  44. for ( i = 0 ; i < m->height ; i++ ) {
  45. VectorCopy( copy->verts[i*m->width+j].normal, m->verts[i*m->width+j].normal );
  46. }
  47. }
  48. FreeMesh( copy );
  49. ds = AllocDrawSurf();
  50. ds->mapBrush = NULL;
  51. ds->side = NULL;
  52. ds->patch = qtrue;
  53. ds->patchWidth = m->width;
  54. ds->patchHeight = m->height;
  55. ds->numVerts = ds->patchWidth * ds->patchHeight;
  56. ds->verts = malloc( ds->numVerts * sizeof( *ds->verts ) );
  57. memcpy( ds->verts, m->verts, ds->numVerts * sizeof( *ds->verts ) );
  58. ds->lightmapNum = -1;
  59. ds->fogNum = -1;
  60. return ds;
  61. }
  62. /*
  63. =================
  64. ParsePatch
  65. Creates a mapDrawSurface_t from the patch text
  66. =================
  67. */
  68. void ParsePatch( void ) {
  69. vec_t info[5];
  70. int i, j;
  71. parseMesh_t *pm;
  72. char texture[MAX_QPATH];
  73. char shader[MAX_QPATH];
  74. mesh_t m;
  75. drawVert_t *verts;
  76. epair_t *ep;
  77. MatchToken( "{" );
  78. // get texture
  79. GetToken (qtrue);
  80. strcpy( texture, token );
  81. // save the shader name for retexturing
  82. if ( numMapIndexedShaders == MAX_MAP_BRUSHSIDES ) {
  83. Error( "MAX_MAP_BRUSHSIDES" );
  84. }
  85. strcpy( mapIndexedShaders[numMapIndexedShaders], texture );
  86. numMapIndexedShaders++;
  87. Parse1DMatrix( 5, info );
  88. m.width = info[0];
  89. m.height = info[1];
  90. m.verts = verts = malloc( m.width * m.height * sizeof( m.verts[0] ) );
  91. if ( m.width < 0 || m.width > MAX_PATCH_SIZE
  92. || m.height < 0 || m.height > MAX_PATCH_SIZE ) {
  93. Error("ParsePatch: bad size");
  94. }
  95. MatchToken( "(" );
  96. for ( j = 0 ; j < m.width ; j++ ) {
  97. MatchToken( "(" );
  98. for ( i = 0 ; i < m.height ; i++ ) {
  99. Parse1DMatrix( 5, verts[i*m.width+j].xyz );
  100. }
  101. MatchToken( ")" );
  102. }
  103. MatchToken( ")" );
  104. // if brush primitives format, we may have some epairs to ignore here
  105. GetToken(qtrue);
  106. if (g_bBrushPrimit!=BPRIMIT_OLDBRUSHES && strcmp(token,"}"))
  107. {
  108. // NOTE: we leak that!
  109. ep = ParseEpair();
  110. }
  111. else
  112. UnGetToken();
  113. MatchToken( "}" );
  114. MatchToken( "}" );
  115. if ( noCurveBrushes ) {
  116. return;
  117. }
  118. // find default flags and values
  119. pm = malloc( sizeof( *pm ) );
  120. memset( pm, 0, sizeof( *pm ) );
  121. sprintf( shader, "textures/%s", texture );
  122. pm->shaderInfo = ShaderInfoForShader( shader );
  123. pm->mesh = m;
  124. // link to the entity
  125. pm->next = mapent->patches;
  126. mapent->patches = pm;
  127. }
  128. void GrowGroup_r( int patchNum, int patchCount, const byte *bordering, byte *group ) {
  129. int i;
  130. const byte *row;
  131. if ( group[patchNum] ) {
  132. return;
  133. }
  134. group[patchNum] = 1;
  135. row = bordering + patchNum * patchCount;
  136. for ( i = 0 ; i < patchCount ; i++ ) {
  137. if ( row[i] ) {
  138. GrowGroup_r( i, patchCount, bordering, group );
  139. }
  140. }
  141. }
  142. /*
  143. =====================
  144. PatchMapDrawSurfs
  145. Any patches that share an edge need to choose their
  146. level of detail as a unit, otherwise the edges would
  147. pull apart.
  148. =====================
  149. */
  150. void PatchMapDrawSurfs( entity_t *e ) {
  151. parseMesh_t *pm;
  152. parseMesh_t *check, *scan;
  153. mapDrawSurface_t *ds;
  154. int patchCount, groupCount;
  155. int i, j, k, l, c1, c2;
  156. drawVert_t *v1, *v2;
  157. vec3_t bounds[2];
  158. byte *bordering;
  159. parseMesh_t *meshes[MAX_MAP_DRAW_SURFS];
  160. qboolean grouped[MAX_MAP_DRAW_SURFS];
  161. byte group[MAX_MAP_DRAW_SURFS];
  162. qprintf( "----- PatchMapDrawSurfs -----\n" );
  163. patchCount = 0;
  164. for ( pm = e->patches ; pm ; pm = pm->next ) {
  165. meshes[patchCount] = pm;
  166. patchCount++;
  167. }
  168. if ( !patchCount ) {
  169. return;
  170. }
  171. bordering = malloc( patchCount * patchCount );
  172. memset( bordering, 0, patchCount * patchCount );
  173. // build the bordering matrix
  174. for ( k = 0 ; k < patchCount ; k++ ) {
  175. bordering[k*patchCount+k] = 1;
  176. for ( l = k+1 ; l < patchCount ; l++ ) {
  177. check = meshes[k];
  178. scan = meshes[l];
  179. c1 = scan->mesh.width * scan->mesh.height;
  180. v1 = scan->mesh.verts;
  181. for ( i = 0 ; i < c1 ; i++, v1++ ) {
  182. c2 = check->mesh.width * check->mesh.height;
  183. v2 = check->mesh.verts;
  184. for ( j = 0 ; j < c2 ; j++, v2++ ) {
  185. if ( fabs( v1->xyz[0] - v2->xyz[0] ) < 1.0
  186. && fabs( v1->xyz[1] - v2->xyz[1] ) < 1.0
  187. && fabs( v1->xyz[2] - v2->xyz[2] ) < 1.0 ) {
  188. break;
  189. }
  190. }
  191. if ( j != c2 ) {
  192. break;
  193. }
  194. }
  195. if ( i != c1 ) {
  196. // we have a connection
  197. bordering[k*patchCount+l] =
  198. bordering[l*patchCount+k] = 1;
  199. } else {
  200. // no connection
  201. bordering[k*patchCount+l] =
  202. bordering[l*patchCount+k] = 0;
  203. }
  204. }
  205. }
  206. // build groups
  207. memset( grouped, 0, sizeof(grouped) );
  208. groupCount = 0;
  209. for ( i = 0 ; i < patchCount ; i++ ) {
  210. if ( !grouped[i] ) {
  211. groupCount++;
  212. }
  213. // recursively find all patches that belong in the same group
  214. memset( group, 0, patchCount );
  215. GrowGroup_r( i, patchCount, bordering, group );
  216. // bound them
  217. ClearBounds( bounds[0], bounds[1] );
  218. for ( j = 0 ; j < patchCount ; j++ ) {
  219. if ( group[j] ) {
  220. grouped[j] = qtrue;
  221. scan = meshes[j];
  222. c1 = scan->mesh.width * scan->mesh.height;
  223. v1 = scan->mesh.verts;
  224. for ( k = 0 ; k < c1 ; k++, v1++ ) {
  225. AddPointToBounds( v1->xyz, bounds[0], bounds[1] );
  226. }
  227. }
  228. }
  229. // create drawsurf
  230. scan = meshes[i];
  231. scan->grouped = qtrue;
  232. ds = DrawSurfaceForMesh( &scan->mesh );
  233. ds->shaderInfo = scan->shaderInfo;
  234. VectorCopy( bounds[0], ds->lightmapVecs[0] );
  235. VectorCopy( bounds[1], ds->lightmapVecs[1] );
  236. }
  237. qprintf( "%5i patches\n", patchCount );
  238. qprintf( "%5i patch LOD groups\n", groupCount );
  239. }