mesh.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  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. /*
  20. ===============================================================
  21. MESH SUBDIVISION
  22. ===============================================================
  23. */
  24. int originalWidths[MAX_EXPANDED_AXIS];
  25. int originalHeights[MAX_EXPANDED_AXIS];
  26. int neighbors[8][2] = {
  27. {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
  28. };
  29. /*
  30. ============
  31. LerpDrawVert
  32. ============
  33. */
  34. void LerpDrawVert( drawVert_t *a, drawVert_t *b, drawVert_t *out ) {
  35. out->xyz[0] = 0.5 * (a->xyz[0] + b->xyz[0]);
  36. out->xyz[1] = 0.5 * (a->xyz[1] + b->xyz[1]);
  37. out->xyz[2] = 0.5 * (a->xyz[2] + b->xyz[2]);
  38. out->st[0] = 0.5 * (a->st[0] + b->st[0]);
  39. out->st[1] = 0.5 * (a->st[1] + b->st[1]);
  40. out->lightmap[0] = 0.5 * (a->lightmap[0] + b->lightmap[0]);
  41. out->lightmap[1] = 0.5 * (a->lightmap[1] + b->lightmap[1]);
  42. out->color[0] = (a->color[0] + b->color[0]) >> 1;
  43. out->color[1] = (a->color[1] + b->color[1]) >> 1;
  44. out->color[2] = (a->color[2] + b->color[2]) >> 1;
  45. out->color[3] = (a->color[3] + b->color[3]) >> 1;
  46. }
  47. void FreeMesh( mesh_t *m ) {
  48. free( m->verts );
  49. free( m );
  50. }
  51. void PrintMesh( mesh_t *m ) {
  52. int i, j;
  53. for ( i = 0 ; i < m->height ; i++ ) {
  54. for ( j = 0 ; j < m->width ; j++ ) {
  55. _printf("(%5.2f %5.2f %5.2f) "
  56. , m->verts[i*m->width+j].xyz[0]
  57. , m->verts[i*m->width+j].xyz[1]
  58. , m->verts[i*m->width+j].xyz[2] );
  59. }
  60. _printf("\n");
  61. }
  62. }
  63. mesh_t *CopyMesh( mesh_t *mesh ) {
  64. mesh_t *out;
  65. int size;
  66. out = malloc( sizeof( *out ) );
  67. out->width = mesh->width;
  68. out->height = mesh->height;
  69. size = out->width * out->height * sizeof( *out->verts );
  70. out->verts = malloc( size );
  71. memcpy( out->verts, mesh->verts, size );
  72. return out;
  73. }
  74. /*
  75. =================
  76. TransposeMesh
  77. Returns a transposed copy of the mesh, freeing the original
  78. =================
  79. */
  80. mesh_t *TransposeMesh( mesh_t *in ) {
  81. int w, h;
  82. mesh_t *out;
  83. out = malloc( sizeof( *out ) );
  84. out->width = in->height;
  85. out->height = in->width;
  86. out->verts = malloc( out->width * out->height * sizeof( drawVert_t ) );
  87. for ( h = 0 ; h < in->height ; h++ ) {
  88. for ( w = 0 ; w < in->width ; w++ ) {
  89. out->verts[ w * in->height + h ] = in->verts[ h * in->width + w ];
  90. }
  91. }
  92. FreeMesh( in );
  93. return out;
  94. }
  95. void InvertMesh( mesh_t *in ) {
  96. int w, h;
  97. drawVert_t temp;
  98. for ( h = 0 ; h < in->height ; h++ ) {
  99. for ( w = 0 ; w < in->width / 2 ; w++ ) {
  100. temp = in->verts[ h * in->width + w ];
  101. in->verts[ h * in->width + w ] = in->verts[ h * in->width + in->width - 1 - w ];
  102. in->verts[ h * in->width + in->width - 1 - w ] = temp;
  103. }
  104. }
  105. }
  106. /*
  107. =================
  108. MakeMeshNormals
  109. =================
  110. */
  111. void MakeMeshNormals( mesh_t in ) {
  112. int i, j, k, dist;
  113. vec3_t normal;
  114. vec3_t sum;
  115. int count;
  116. vec3_t base;
  117. vec3_t delta;
  118. int x, y;
  119. drawVert_t *dv;
  120. vec3_t around[8], temp;
  121. qboolean good[8];
  122. qboolean wrapWidth, wrapHeight;
  123. float len;
  124. wrapWidth = qfalse;
  125. for ( i = 0 ; i < in.height ; i++ ) {
  126. VectorSubtract( in.verts[i*in.width].xyz,
  127. in.verts[i*in.width+in.width-1].xyz, delta );
  128. len = VectorLength( delta );
  129. if ( len > 1.0 ) {
  130. break;
  131. }
  132. }
  133. if ( i == in.height ) {
  134. wrapWidth = qtrue;
  135. }
  136. wrapHeight = qfalse;
  137. for ( i = 0 ; i < in.width ; i++ ) {
  138. VectorSubtract( in.verts[i].xyz,
  139. in.verts[i + (in.height-1)*in.width].xyz, delta );
  140. len = VectorLength( delta );
  141. if ( len > 1.0 ) {
  142. break;
  143. }
  144. }
  145. if ( i == in.width) {
  146. wrapHeight = qtrue;
  147. }
  148. for ( i = 0 ; i < in.width ; i++ ) {
  149. for ( j = 0 ; j < in.height ; j++ ) {
  150. count = 0;
  151. dv = &in.verts[j*in.width+i];
  152. VectorCopy( dv->xyz, base );
  153. for ( k = 0 ; k < 8 ; k++ ) {
  154. VectorClear( around[k] );
  155. good[k] = qfalse;
  156. for ( dist = 1 ; dist <= 3 ; dist++ ) {
  157. x = i + neighbors[k][0] * dist;
  158. y = j + neighbors[k][1] * dist;
  159. if ( wrapWidth ) {
  160. if ( x < 0 ) {
  161. x = in.width - 1 + x;
  162. } else if ( x >= in.width ) {
  163. x = 1 + x - in.width;
  164. }
  165. }
  166. if ( wrapHeight ) {
  167. if ( y < 0 ) {
  168. y = in.height - 1 + y;
  169. } else if ( y >= in.height ) {
  170. y = 1 + y - in.height;
  171. }
  172. }
  173. if ( x < 0 || x >= in.width || y < 0 || y >= in.height ) {
  174. break; // edge of patch
  175. }
  176. VectorSubtract( in.verts[y*in.width+x].xyz, base, temp );
  177. if ( VectorNormalize( temp, temp ) == 0 ) {
  178. continue; // degenerate edge, get more dist
  179. } else {
  180. good[k] = qtrue;
  181. VectorCopy( temp, around[k] );
  182. break; // good edge
  183. }
  184. }
  185. }
  186. VectorClear( sum );
  187. for ( k = 0 ; k < 8 ; k++ ) {
  188. if ( !good[k] || !good[(k+1)&7] ) {
  189. continue; // didn't get two points
  190. }
  191. CrossProduct( around[(k+1)&7], around[k], normal );
  192. if ( VectorNormalize( normal, normal ) == 0 ) {
  193. continue;
  194. }
  195. VectorAdd( normal, sum, sum );
  196. count++;
  197. }
  198. if ( count == 0 ) {
  199. //_printf("bad normal\n");
  200. count = 1;
  201. }
  202. VectorNormalize( sum, dv->normal );
  203. }
  204. }
  205. }
  206. /*
  207. =================
  208. PutMeshOnCurve
  209. Drops the aproximating points onto the curve
  210. =================
  211. */
  212. void PutMeshOnCurve( mesh_t in ) {
  213. int i, j, l;
  214. float prev, next;
  215. // put all the aproximating points on the curve
  216. for ( i = 0 ; i < in.width ; i++ ) {
  217. for ( j = 1 ; j < in.height ; j += 2 ) {
  218. for ( l = 0 ; l < 3 ; l++ ) {
  219. prev = ( in.verts[j*in.width+i].xyz[l] + in.verts[(j+1)*in.width+i].xyz[l] ) * 0.5;
  220. next = ( in.verts[j*in.width+i].xyz[l] + in.verts[(j-1)*in.width+i].xyz[l] ) * 0.5;
  221. in.verts[j*in.width+i].xyz[l] = ( prev + next ) * 0.5;
  222. }
  223. }
  224. }
  225. for ( j = 0 ; j < in.height ; j++ ) {
  226. for ( i = 1 ; i < in.width ; i += 2 ) {
  227. for ( l = 0 ; l < 3 ; l++ ) {
  228. prev = ( in.verts[j*in.width+i].xyz[l] + in.verts[j*in.width+i+1].xyz[l] ) * 0.5;
  229. next = ( in.verts[j*in.width+i].xyz[l] + in.verts[j*in.width+i-1].xyz[l] ) * 0.5;
  230. in.verts[j*in.width+i].xyz[l] = ( prev + next ) * 0.5;
  231. }
  232. }
  233. }
  234. }
  235. /*
  236. =================
  237. SubdivideMesh
  238. =================
  239. */
  240. mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ) {
  241. int i, j, k, l;
  242. drawVert_t prev, next, mid;
  243. vec3_t prevxyz, nextxyz, midxyz;
  244. vec3_t delta;
  245. float len;
  246. mesh_t out;
  247. drawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
  248. out.width = in.width;
  249. out.height = in.height;
  250. for ( i = 0 ; i < in.width ; i++ ) {
  251. for ( j = 0 ; j < in.height ; j++ ) {
  252. expand[j][i] = in.verts[j*in.width+i];
  253. }
  254. }
  255. for ( i = 0 ; i < in.height ; i++ ) {
  256. originalHeights[i] = i;
  257. }
  258. for ( i = 0 ; i < in.width ; i++ ) {
  259. originalWidths[i] = i;
  260. }
  261. // horizontal subdivisions
  262. for ( j = 0 ; j + 2 < out.width ; j += 2 ) {
  263. // check subdivided midpoints against control points
  264. for ( i = 0 ; i < out.height ; i++ ) {
  265. for ( l = 0 ; l < 3 ; l++ ) {
  266. prevxyz[l] = expand[i][j+1].xyz[l] - expand[i][j].xyz[l];
  267. nextxyz[l] = expand[i][j+2].xyz[l] - expand[i][j+1].xyz[l];
  268. midxyz[l] = (expand[i][j].xyz[l] + expand[i][j+1].xyz[l] * 2
  269. + expand[i][j+2].xyz[l] ) * 0.25;
  270. }
  271. // if the span length is too long, force a subdivision
  272. if ( VectorLength( prevxyz ) > minLength
  273. || VectorLength( nextxyz ) > minLength ) {
  274. break;
  275. }
  276. // see if this midpoint is off far enough to subdivide
  277. VectorSubtract( expand[i][j+1].xyz, midxyz, delta );
  278. len = VectorLength( delta );
  279. if ( len > maxError ) {
  280. break;
  281. }
  282. }
  283. if ( out.width + 2 >= MAX_EXPANDED_AXIS ) {
  284. break; // can't subdivide any more
  285. }
  286. if ( i == out.height ) {
  287. continue; // didn't need subdivision
  288. }
  289. // insert two columns and replace the peak
  290. out.width += 2;
  291. for ( k = out.width - 1 ; k > j + 3 ; k-- ) {
  292. originalWidths[k] = originalWidths[k-2];
  293. }
  294. originalWidths[j+3] = originalWidths[j+1];
  295. originalWidths[j+2] = originalWidths[j+1];
  296. originalWidths[j+1] = originalWidths[j];
  297. for ( i = 0 ; i < out.height ; i++ ) {
  298. LerpDrawVert( &expand[i][j], &expand[i][j+1], &prev );
  299. LerpDrawVert( &expand[i][j+1], &expand[i][j+2], &next );
  300. LerpDrawVert( &prev, &next, &mid );
  301. for ( k = out.width - 1 ; k > j + 3 ; k-- ) {
  302. expand[i][k] = expand[i][k-2];
  303. }
  304. expand[i][j + 1] = prev;
  305. expand[i][j + 2] = mid;
  306. expand[i][j + 3] = next;
  307. }
  308. // back up and recheck this set again, it may need more subdivision
  309. j -= 2;
  310. }
  311. // vertical subdivisions
  312. for ( j = 0 ; j + 2 < out.height ; j += 2 ) {
  313. // check subdivided midpoints against control points
  314. for ( i = 0 ; i < out.width ; i++ ) {
  315. for ( l = 0 ; l < 3 ; l++ ) {
  316. prevxyz[l] = expand[j+1][i].xyz[l] - expand[j][i].xyz[l];
  317. nextxyz[l] = expand[j+2][i].xyz[l] - expand[j+1][i].xyz[l];
  318. midxyz[l] = (expand[j][i].xyz[l] + expand[j+1][i].xyz[l] * 2
  319. + expand[j+2][i].xyz[l] ) * 0.25;
  320. }
  321. // if the span length is too long, force a subdivision
  322. if ( VectorLength( prevxyz ) > minLength
  323. || VectorLength( nextxyz ) > minLength ) {
  324. break;
  325. }
  326. // see if this midpoint is off far enough to subdivide
  327. VectorSubtract( expand[j+1][i].xyz, midxyz, delta );
  328. len = VectorLength( delta );
  329. if ( len > maxError ) {
  330. break;
  331. }
  332. }
  333. if ( out.height + 2 >= MAX_EXPANDED_AXIS ) {
  334. break; // can't subdivide any more
  335. }
  336. if ( i == out.width ) {
  337. continue; // didn't need subdivision
  338. }
  339. // insert two columns and replace the peak
  340. out.height += 2;
  341. for ( k = out.height - 1 ; k > j + 3 ; k-- ) {
  342. originalHeights[k] = originalHeights[k-2];
  343. }
  344. originalHeights[j+3] = originalHeights[j+1];
  345. originalHeights[j+2] = originalHeights[j+1];
  346. originalHeights[j+1] = originalHeights[j];
  347. for ( i = 0 ; i < out.width ; i++ ) {
  348. LerpDrawVert( &expand[j][i], &expand[j+1][i], &prev );
  349. LerpDrawVert( &expand[j+1][i], &expand[j+2][i], &next );
  350. LerpDrawVert( &prev, &next, &mid );
  351. for ( k = out.height - 1 ; k > j + 3 ; k-- ) {
  352. expand[k][i] = expand[k-2][i];
  353. }
  354. expand[j+1][i] = prev;
  355. expand[j+2][i] = mid;
  356. expand[j+3][i] = next;
  357. }
  358. // back up and recheck this set again, it may need more subdivision
  359. j -= 2;
  360. }
  361. // collapse the verts
  362. out.verts = &expand[0][0];
  363. for ( i = 1 ; i < out.height ; i++ ) {
  364. memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(drawVert_t) );
  365. }
  366. return CopyMesh(&out);
  367. }
  368. /*
  369. ================
  370. ProjectPointOntoVector
  371. ================
  372. */
  373. void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj )
  374. {
  375. vec3_t pVec, vec;
  376. VectorSubtract( point, vStart, pVec );
  377. VectorSubtract( vEnd, vStart, vec );
  378. VectorNormalize( vec, vec );
  379. // project onto the directional vector for this segment
  380. VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj );
  381. }
  382. /*
  383. ================
  384. RemoveLinearMeshColumsRows
  385. ================
  386. */
  387. mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
  388. int i, j, k;
  389. float len, maxLength;
  390. vec3_t proj, dir;
  391. mesh_t out;
  392. drawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
  393. out.width = in->width;
  394. out.height = in->height;
  395. for ( i = 0 ; i < in->width ; i++ ) {
  396. for ( j = 0 ; j < in->height ; j++ ) {
  397. expand[j][i] = in->verts[j*in->width+i];
  398. }
  399. }
  400. for ( j = 1 ; j < out.width - 1; j++ ) {
  401. maxLength = 0;
  402. for ( i = 0 ; i < out.height ; i++ ) {
  403. ProjectPointOntoVector(expand[i][j].xyz, expand[i][j-1].xyz, expand[i][j+1].xyz, proj);
  404. VectorSubtract(expand[i][j].xyz, proj, dir);
  405. len = VectorLength(dir);
  406. if (len > maxLength) {
  407. maxLength = len;
  408. }
  409. }
  410. if (maxLength < 0.1)
  411. {
  412. out.width--;
  413. for ( i = 0 ; i < out.height ; i++ ) {
  414. for (k = j; k < out.width; k++) {
  415. expand[i][k] = expand[i][k+1];
  416. }
  417. }
  418. for (k = j; k < out.width; k++) {
  419. originalWidths[k] = originalWidths[k+1];
  420. }
  421. j--;
  422. }
  423. }
  424. for ( j = 1 ; j < out.height - 1; j++ ) {
  425. maxLength = 0;
  426. for ( i = 0 ; i < out.width ; i++ ) {
  427. ProjectPointOntoVector(expand[j][i].xyz, expand[j-1][i].xyz, expand[j+1][i].xyz, proj);
  428. VectorSubtract(expand[j][i].xyz, proj, dir);
  429. len = VectorLength(dir);
  430. if (len > maxLength) {
  431. maxLength = len;
  432. }
  433. }
  434. if (maxLength < 0.1)
  435. {
  436. out.height--;
  437. for ( i = 0 ; i < out.width ; i++ ) {
  438. for (k = j; k < out.height; k++) {
  439. expand[k][i] = expand[k+1][i];
  440. }
  441. }
  442. for (k = j; k < out.height; k++) {
  443. originalHeights[k] = originalHeights[k+1];
  444. }
  445. j--;
  446. }
  447. }
  448. // collapse the verts
  449. out.verts = &expand[0][0];
  450. for ( i = 1 ; i < out.height ; i++ ) {
  451. memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(drawVert_t) );
  452. }
  453. return CopyMesh(&out);
  454. }
  455. /*
  456. ============
  457. LerpDrawVertAmount
  458. ============
  459. */
  460. void LerpDrawVertAmount( drawVert_t *a, drawVert_t *b, float amount, drawVert_t *out ) {
  461. out->xyz[0] = a->xyz[0] + amount * (b->xyz[0] - a->xyz[0]);
  462. out->xyz[1] = a->xyz[1] + amount * (b->xyz[1] - a->xyz[1]);
  463. out->xyz[2] = a->xyz[2] + amount * (b->xyz[2] - a->xyz[2]);
  464. out->st[0] = a->st[0] + amount * (b->st[0] - a->st[0]);
  465. out->st[1] = a->st[1] + amount * (b->st[1] - a->st[1]);
  466. out->lightmap[0] = a->lightmap[0] + amount * (b->lightmap[0] - a->lightmap[0]);
  467. out->lightmap[1] = a->lightmap[1] + amount * (b->lightmap[1] - a->lightmap[1]);
  468. out->color[0] = a->color[0] + amount * (b->color[0] - a->color[0]);
  469. out->color[1] = a->color[1] + amount * (b->color[1] - a->color[1]);
  470. out->color[2] = a->color[2] + amount * (b->color[2] - a->color[2]);
  471. out->color[3] = a->color[3] + amount * (b->color[3] - a->color[3]);
  472. out->normal[0] = a->normal[0] + amount * (b->normal[0] - a->normal[0]);
  473. out->normal[1] = a->normal[1] + amount * (b->normal[1] - a->normal[1]);
  474. out->normal[2] = a->normal[2] + amount * (b->normal[2] - a->normal[2]);
  475. VectorNormalize(out->normal, out->normal);
  476. }
  477. /*
  478. =================
  479. SubdivideMeshQuads
  480. =================
  481. */
  482. mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int widthtable[], int heighttable[]) {
  483. int i, j, k, w, h, maxsubdivisions, subdivisions;
  484. vec3_t dir;
  485. float length, maxLength, amount;
  486. mesh_t out;
  487. drawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
  488. out.width = in->width;
  489. out.height = in->height;
  490. for ( i = 0 ; i < in->width ; i++ ) {
  491. for ( j = 0 ; j < in->height ; j++ ) {
  492. expand[j][i] = in->verts[j*in->width+i];
  493. }
  494. }
  495. if (maxsize > MAX_EXPANDED_AXIS)
  496. Error("SubdivideMeshQuads: maxsize > MAX_EXPANDED_AXIS");
  497. // horizontal subdivisions
  498. maxsubdivisions = (maxsize - in->width) / (in->width - 1);
  499. for ( w = 0, j = 0 ; w < in->width - 1; w++, j += subdivisions + 1) {
  500. maxLength = 0;
  501. for ( i = 0 ; i < out.height ; i++ ) {
  502. VectorSubtract(expand[i][j+1].xyz, expand[i][j].xyz, dir);
  503. length = VectorLength( dir );
  504. if (length > maxLength) {
  505. maxLength = length;
  506. }
  507. }
  508. subdivisions = (int) (maxLength / minLength);
  509. if (subdivisions > maxsubdivisions)
  510. subdivisions = maxsubdivisions;
  511. widthtable[w] = subdivisions + 1;
  512. if (subdivisions <= 0)
  513. continue;
  514. out.width += subdivisions;
  515. for ( k = out.width - 1; k >= j + subdivisions; k-- ) {
  516. originalWidths[k] = originalWidths[k-subdivisions];
  517. }
  518. for (k = 1; k <= subdivisions; k++) {
  519. originalWidths[j+k] = originalWidths[j];
  520. }
  521. for ( i = 0 ; i < out.height ; i++ ) {
  522. for ( k = out.width - 1 ; k > j + subdivisions; k-- ) {
  523. expand[i][k] = expand[i][k-subdivisions];
  524. }
  525. for (k = 1; k <= subdivisions; k++)
  526. {
  527. amount = (float) k / (subdivisions + 1);
  528. LerpDrawVertAmount(&expand[i][j], &expand[i][j+subdivisions+1], amount, &expand[i][j+k]);
  529. }
  530. }
  531. }
  532. maxsubdivisions = (maxsize - in->height) / (in->height - 1);
  533. for ( h = 0, j = 0 ; h < in->height - 1; h++, j += subdivisions + 1) {
  534. maxLength = 0;
  535. for ( i = 0 ; i < out.width ; i++ ) {
  536. VectorSubtract(expand[j+1][i].xyz, expand[j][i].xyz, dir);
  537. length = VectorLength( dir );
  538. if (length > maxLength) {
  539. maxLength = length;
  540. }
  541. }
  542. subdivisions = (int) (maxLength / minLength);
  543. if (subdivisions > maxsubdivisions)
  544. subdivisions = maxsubdivisions;
  545. heighttable[h] = subdivisions + 1;
  546. if (subdivisions <= 0)
  547. continue;
  548. out.height += subdivisions;
  549. for ( k = out.height - 1; k >= j + subdivisions; k-- ) {
  550. originalHeights[k] = originalHeights[k-subdivisions];
  551. }
  552. for (k = 1; k <= subdivisions; k++) {
  553. originalHeights[j+k] = originalHeights[j];
  554. }
  555. for ( i = 0 ; i < out.width ; i++ ) {
  556. for ( k = out.height - 1 ; k > j + subdivisions; k-- ) {
  557. expand[k][i] = expand[k-subdivisions][i];
  558. }
  559. for (k = 1; k <= subdivisions; k++)
  560. {
  561. amount = (float) k / (subdivisions + 1);
  562. LerpDrawVertAmount(&expand[j][i], &expand[j+subdivisions+1][i], amount, &expand[j+k][i]);
  563. }
  564. }
  565. }
  566. // collapse the verts
  567. out.verts = &expand[0][0];
  568. for ( i = 1 ; i < out.height ; i++ ) {
  569. memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(drawVert_t) );
  570. }
  571. return CopyMesh(&out);
  572. }