BUILDBSP.C
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:20k
源码类别:

游戏

开发平台:

Visual C++

  1. #include "idbsp.h"
  2. #include "ray.h"
  3. #include "globals.h"
  4. #include <mem.h>
  5. #define _STEVE_FIX_
  6. #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
  7. #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
  8. void * MyRealloc(void * ptr, long old_size, long new_size);
  9. /*
  10.  I assume that a grid 8 is used for the maps, so a point will be considered
  11.  on a line if it is within 8 pixels of it.  The accounts for floating error.
  12. */
  13. int             cuts;                   /* number of new lines generated by BSP process */
  14. /*
  15. ==================
  16. =
  17. = DivlineFromWorldline
  18. =
  19. ==================
  20. */
  21. void    DivlineFromWorldline (divline_t *d, line_t *w)
  22. {
  23. d->pt = w->p1;
  24. d->dx = w->p2.x - w->p1.x;
  25. d->dy = w->p2.y - w->p1.y;
  26. }
  27. /*
  28. ==================
  29. =
  30. = LineFromPoints
  31. =
  32. ==================
  33. */
  34. void    LineFromPoints(line_t * line, pvector2 source, pvector2 dest)
  35. {
  36. memset(line, 0, sizeof(line_t));
  37. line->p1.x=source->x;          
  38. line->p1.y=source->y;
  39. line->p2.x=dest->x;
  40. line->p2.y=dest->y;
  41. }
  42. #define FLOAT_ERROR 4.4722
  43. /*
  44. ==================
  45. =
  46. = PointOnSide
  47. =
  48. = Returns side 0 (front), 1 (back), or -1 (colinear)
  49. ==================
  50. */
  51. #ifdef _STEVE_FIX_
  52. int     PointOnSide (NXPoint *p, divline_t *l)
  53. {
  54.   float dist;
  55.   if (!l->dx)
  56.   {
  57.  if (p->x > l->pt.x-2 && p->x < l->pt.x+2)
  58. return -1;
  59.  if (p->x < l->pt.x)
  60. return l->dy > 0;
  61.  return l->dy < 0;
  62.   }
  63.   if (!l->dy)
  64.   {
  65.  if (p->y > l->pt.y-2 && p->y < l->pt.y+2)
  66. return -1;
  67.  if (p->y < l->pt.y)
  68. return l->dx < 0;
  69.  return l->dx > 0;
  70.   }
  71.   dist = l->dx * (p->y - l->pt.y) - l->dy * (p->x - l->pt.x);
  72. if (dist < FLOAT_ERROR && dist > -FLOAT_ERROR)
  73.  return(-1);
  74.  else if (dist < -FLOAT_ERROR)
  75.  return(0);
  76. else
  77.  return(1);
  78. }
  79. #else
  80. int     PointOnSide (NXPoint *p, divline_t *l)
  81. {
  82. float   dx,dy;
  83. float   left, right;
  84. float   a,b,c,d;
  85. if (!l->dx)
  86. {
  87. if (p->x > l->pt.x-2 && p->x < l->pt.x+2)
  88. return -1;
  89. if (p->x < l->pt.x)
  90. return l->dy > 0;
  91. return l->dy < 0;
  92. }
  93. if (!l->dy)
  94. {
  95. if (p->y > l->pt.y-2 && p->y < l->pt.y+2)
  96. return -1;
  97. if (p->y < l->pt.y)
  98. return l->dx < 0;
  99. return l->dx > 0;
  100. }
  101. dx = l->pt.x - p->x;
  102. dy = l->pt.y - p->y;
  103. a = l->dx*l->dx + l->dy*l->dy;
  104. b = 2*(l->dx*dx + l->dy*dy);
  105. c = dx*dx+dy*dy - 2*2;          /* 2 unit radius */
  106. d = b*b - 4*a*c;
  107. if (d>0)
  108. return -1;               /* within four pixels of line */
  109. dx = p->x - l->pt.x;
  110. dy = p->y - l->pt.y;
  111. left = l->dy * dx;
  112. right = dy * l->dx;
  113. if ( fabs (left-right) < 0.5 )  /* allow slop */
  114. return -1;              /* on line */
  115. if (right < left)
  116. return 0;               /* front side */
  117. return 1;                       /* back side */
  118. }
  119. #endif
  120. /*
  121. =============
  122. =
  123. = sign
  124. =
  125. = Returns -1, 0, or 1, based on the input sign
  126. =
  127. ==============
  128. */
  129. int sign (float i)
  130. {
  131. if (i<0)
  132. return -1;
  133. else if (i>0)
  134. return 1;
  135. return 0;
  136. }
  137. /*
  138. ==================
  139. =
  140. = LineOnSide
  141. =
  142. = Returns side 0 / 1, or -2 if line must be split
  143. = If the line is colinear, it will be placed on the front side if
  144. = it is going the same direction as the dividing line
  145. ==================
  146. */
  147. #ifdef _STEVE_FIX_
  148. int LineOnSide (line_t *wl, divline_t *bl)
  149. #else
  150. boolean LineOnSide (line_t *wl, divline_t *bl)
  151. #endif
  152. {
  153. int             s1,s2;
  154. float   dx, dy;
  155. s1 = PointOnSide (&wl->p1, bl);
  156. s2 = PointOnSide (&wl->p2, bl);
  157. if (s1 == s2)
  158. {
  159. if (s1 == -1)
  160. {       /* colinear, so see if the directions are the same */
  161. dx = wl->p2.x - wl->p1.x;
  162. dy = wl->p2.y - wl->p1.y;
  163. if (sign(dx) == sign (bl->dx) && sign(dy) == sign(bl->dy) )
  164. return 0;
  165. return 1;
  166. }
  167. return s1;
  168. }
  169. if (s1 == -1)
  170. return s2;
  171. if (s2 == -1)
  172. return s1;
  173. return -2;
  174. }
  175. /*
  176. ===============
  177. =
  178. = InterceptVector
  179. =
  180. = Returns the fractional intercept point along first vector
  181. ===============
  182. */
  183. float InterceptVector (divline_t *v2, divline_t *v1)
  184. {
  185. #if 0
  186. v1.x + f1*v1.xs = v2.x + f2*v2.xs       (parametric x coordinates)
  187. f1*v1.xs = v2.x - v1.x + f2*v2.xs
  188. f1 = (v2.x - v1.x +f2*v2.xs) / v1.xs
  189. v1.y + f1*v1.ys = v2.y + f2*v2.ys       (parametric y coordinates)
  190. f1 = (v2.y - v1.y + f2*v2.ys) / v1.ys
  191. f1 = (v2.x - v1.x +f2*v2.xs) / v1.xs = (v2.y - v1.y + f2*v2.ys) / v1.ys
  192. v1.ys*v2.x - v1.ys*v1.x + v1.ys*v2.xs*f2 = v1.xs*v2.y - v1.xs*v1.y + v1.xs*v2.ys*f2
  193. (v1.ys*v2.xs - v1.xs*v2.ys)*f2 = -v1.ys*v2.x + v1.ys*v1.x + v1.xs*v2.y - v1.xs*v1.y
  194. = v1.ys*(v1.x-v2.x) + v1.xs*(v2.y-v1.y)
  195. f2 = (v1.ys*(v1.x-v2.x) + v1.xs*(v2.y-v1.y)) / (v1.ys*v2.xs - v1.xs*v2.ys)
  196. #endif
  197. float   frac, num, den;
  198. den = v1->dy*v2->dx - v1->dx*v2->dy;
  199. if (den == 0)
  200. Error ("InterceptVector: parallel");
  201. num = (v1->pt.x - v2->pt.x)*v1->dy + (v2->pt.y - v1->pt.y)*v1->dx;
  202. frac = num / den;
  203. if (frac <= 0.0 || frac >= 1.0)
  204. Error ("InterceptVector: intersection outside line");
  205. return frac;
  206. }
  207. /*
  208. ==================
  209. =
  210. = CutLine
  211. =
  212. = Truncates the given worldline to the front side of the divline
  213. = and returns the cut off back side in a newly allocated worldline
  214. ==================
  215. */
  216. float round (float x)
  217. {
  218. if (x>0)
  219. {
  220. if (x - (int)x < 0.1)
  221. return (int)x;
  222. else if (x - (int)x > 0.9)
  223. return (int)x+1;
  224. else
  225. return x;
  226. }
  227. if ((int)x - x < 0.1)
  228. return (int)x;
  229. else if ((int)x - x > 0.9)
  230. return  (int)x - 1;
  231. return x;
  232. }
  233. line_t  *CutLine (line_t *wl, divline_t *bl)
  234. {
  235. int                     side;
  236. line_t          *new_p;
  237. divline_t       wld;
  238. float           frac;
  239. NXPoint         intr;
  240. int                     offset;
  241. cuts++;
  242. DivlineFromWorldline (&wld, wl);
  243. new_p = (line_t *)Alloc_Mem (sizeof(line_t));
  244. memset (new_p,0,sizeof(*new_p));
  245. *new_p = *wl;
  246. frac = InterceptVector (&wld, bl);
  247. #ifdef _STEVE_FIX_
  248. intr.x = wld.pt.x + (wld.dx*frac);
  249. intr.y = wld.pt.y + (wld.dy*frac);
  250. offset = wl->offset + (frac*sqrt(wld.dx*wld.dx+wld.dy*wld.dy));
  251. #else
  252. intr.x = wld.pt.x + round(wld.dx*frac);
  253. intr.y = wld.pt.y + round(wld.dy*frac);
  254. offset = wl->offset + round(frac*sqrt(wld.dx*wld.dx+wld.dy*wld.dy));
  255. #endif        
  256. side = PointOnSide (&wl->p1, bl);
  257. if (side == 0)
  258. {       /* line starts on front side */
  259. wl->p2 = intr;
  260. new_p->p1 = intr;
  261. new_p->offset = offset;
  262. }
  263. else
  264. {       /* line starts on back side */
  265. wl->p1 = intr;
  266. wl->offset = offset;
  267. new_p->p2 = intr;
  268. }
  269. return new_p;
  270. }
  271. /*
  272. ================
  273. =
  274. = EvaluateSplit
  275. =
  276. = Returns a number grading the quality of a split along the givent line
  277. = for the current list of lines.  Evaluation is halted as soon as it is
  278. = determined that a better split already exists
  279. =
  280. = A split is good if it divides the lines evenly without cutting many lines
  281. = A horizontal or vertical split is better than a sloping split
  282. =
  283. = The LOWER the returned value, the better.  If the split line does not divide
  284. = any of the lines at all, MAXINT will be returned
  285. ================
  286. */
  287. /*int EvaluateSplit (id lines_i, line_t *spliton, int bestgrade)
  288. */
  289. int EvaluateSplit(STORAGE *lines_i, line_t *spliton, int bestgrade)
  290. {
  291. int                             i,c,side;
  292. line_t                  *line_p;
  293. divline_t               divline;
  294. int                             frontcount, backcount, max, new;
  295. int                             grade;
  296. worldline_t             *wl;
  297. /*      wl = [linestore_i elementAt: spliton->linedef];
  298. */
  299. wl = (worldline_t *)linestore_i->data + spliton->linedef;
  300. #if 0
  301. if (wl->special == BSPSLIDEENDSPECIAL)
  302. return MAXINT;  /* NEVER split on this, because it moves */
  303. #endif
  304. DivlineFromWorldline (&divline, spliton);
  305. frontcount = backcount = 0;
  306. /*      c = [lines_i count];
  307. */
  308. c = lines_i->count;
  309. grade = 0;
  310. for (i=0 ; i<c ; i++)
  311. {
  312. /*              line_p = [lines_i elementAt:i];
  313. */
  314. line_p = (line_t *)lines_i->data + i;
  315. if (line_p == spliton)
  316. side = 0;
  317. else
  318. side = LineOnSide (line_p, &divline);
  319. switch (side)
  320. {
  321. case 0:
  322. frontcount++;
  323. break;
  324. case 1:
  325. backcount++;
  326. break;
  327. case -2:
  328. /*                      wl = [linestore_i elementAt: line_p->linedef];
  329. */
  330. wl = (worldline_t *)linestore_i->data + line_p->linedef;
  331. #if 0
  332. if (wl->special == BSPSLIDESIDESPECIAL)
  333. return MAXINT;  /* NEVER split this line, because it slides */
  334. #endif
  335. frontcount++;
  336. backcount++;
  337. break;
  338. }
  339. max = MAX(frontcount,backcount);
  340. new = (frontcount+backcount) - c;
  341. grade = max+new*8;
  342. if (grade > bestgrade)
  343. return grade;           /* might as well stop now */
  344. }
  345. if (frontcount == 0 || backcount == 0)
  346. return INT_MAX;                 /* line does not partition at all */
  347. return grade;
  348. }
  349. /*
  350. ================
  351. =
  352. = ExecuteSplit
  353. =
  354. = Actually splits the line list as EvaluateLines predicted
  355. ================
  356. */
  357. /*
  358. void ExecuteSplit (id lines_i, line_t *spliton
  359. , id frontlist_i, id backlist_i)
  360. */
  361. void ExecuteSplit(STORAGE *lines_i, line_t *spliton,
  362.   STORAGE *frontlist_i, STORAGE *backlist_i)
  363. {
  364. int                             i,c,side;
  365. line_t                  *line_p, *newline_p;
  366. divline_t               divline;
  367. DivlineFromWorldline (&divline, spliton);
  368. /*      c = [lines_i count];
  369. */
  370. c = lines_i->count;
  371. for (i=0 ; i<c ; i++)
  372. {
  373. /*              line_p = [lines_i elementAt:i];
  374. */
  375. line_p = (line_t *)lines_i->data + i;
  376. if (line_p == spliton)
  377. side = 0;
  378. else
  379. side = LineOnSide (line_p, &divline);
  380. switch (side)
  381. {
  382. case 0:
  383. /*                      [frontlist_i addElement: line_p];
  384. */
  385. memcpy((line_t *)frontlist_i->data + frontlist_i->count, line_p, sizeof(line_t));
  386. frontlist_i->count += 1;
  387. frontlist_i->data = (line_t *)MyRealloc(frontlist_i->data,
  388. sizeof(line_t) * (frontlist_i->count), sizeof(line_t) * (frontlist_i->count + 1));
  389. break;
  390. case 1:
  391. /*                      [backlist_i addElement: line_p];
  392. */
  393. memcpy((line_t *)backlist_i->data + backlist_i->count, line_p, sizeof(line_t));
  394. backlist_i->count += 1;
  395. backlist_i->data = (line_t *)MyRealloc(backlist_i->data,
  396. sizeof(line_t) * (backlist_i->count), sizeof(line_t) * (backlist_i->count + 1));
  397. break;
  398. case -2:
  399. newline_p = CutLine (line_p, &divline);
  400. /*                      [frontlist_i addElement: line_p];
  401. [backlist_i addElement: newline_p];
  402. */
  403. memcpy((line_t *)frontlist_i->data + frontlist_i->count, line_p, sizeof(line_t));
  404. frontlist_i->count += 1;
  405. frontlist_i->data = (line_t *)MyRealloc(frontlist_i->data,
  406. sizeof(line_t) * (frontlist_i->count), sizeof(line_t) * (frontlist_i->count + 1));
  407. memcpy((line_t *)backlist_i->data + backlist_i->count, newline_p, sizeof(line_t));
  408. backlist_i->count += 1;
  409. backlist_i->data = (line_t *)MyRealloc(backlist_i->data,
  410. sizeof(line_t) * (backlist_i->count), sizeof(line_t) * (backlist_i->count + 1));
  411. break;
  412. default:
  413. Error ("ExecuteSplit: bad side");
  414. }
  415. }
  416. }
  417. /*
  418. ================
  419. =
  420. = SplitCutBoxes
  421. =
  422. = Cuts a box in half along a line ****MADE BY MATT****
  423. ================
  424. */
  425. void SplitCutBoxes(STORAGE * cutbox_i, line_t * spliton, 
  426. STORAGE * frontlist_i, STORAGE * backlist_i) {
  427. divline_t divline;
  428. short point_count, cur_point, cur_side; 
  429. pvector2 cur_vec, next_vec; 
  430. vector2 new_vec;
  431. line_t cur_line;
  432. line_t * newline_p;
  433. DivlineFromWorldline(&divline, spliton);
  434. point_count=cutbox_i->count;
  435. cur_vec=(pvector2)cutbox_i->data+point_count-1;
  436. for (cur_point=0; cur_point<point_count; cur_point++) {
  437. next_vec=(pvector2)cutbox_i->data+cur_point;   
  438. LineFromPoints(&cur_line, cur_vec, next_vec);
  439. cur_side=LineOnSide(&cur_line, &divline); 
  440. switch (cur_side) {
  441. case 0:
  442. if (PointOnSide(&(cur_line.p2), &divline)==-1) {
  443. memcpy((pvector2)backlist_i->data+backlist_i->count, next_vec, sizeof(vector2));
  444. backlist_i->count++;
  445. backlist_i->data=(pvector2)MyRealloc(backlist_i->data, 
  446. sizeof(vector2) *(backlist_i->count),sizeof(vector2) *(backlist_i->count+1));
  447. }
  448. memcpy((pvector2)frontlist_i->data+frontlist_i->count, next_vec, sizeof(vector2));          
  449. frontlist_i->count++;                                                        
  450. frontlist_i->data=(pvector2)MyRealloc(frontlist_i->data, 
  451. sizeof(vector2) *(frontlist_i->count), sizeof(vector2) *(frontlist_i->count+1));
  452. break;
  453. case 1:
  454. if (PointOnSide(&(cur_line.p2), &divline)==-1) {
  455. memcpy((pvector2)frontlist_i->data+frontlist_i->count, next_vec, sizeof(vector2));
  456. frontlist_i->count++;
  457. frontlist_i->data=(pvector2)MyRealloc(frontlist_i->data, 
  458. sizeof(vector2) *(frontlist_i->count), sizeof(vector2) *(frontlist_i->count+1));
  459. }
  460. memcpy((pvector2)backlist_i->data+backlist_i->count, next_vec, sizeof(vector2));
  461. backlist_i->count++;
  462. backlist_i->data=(pvector2)MyRealloc(backlist_i->data, 
  463. sizeof(vector2) *(backlist_i->count), sizeof(vector2) *(backlist_i->count+1));
  464. break;
  465. case -2:   
  466. newline_p=CutLine(&cur_line, &divline);
  467. if ((newline_p->p2.x==next_vec->x) && (newline_p->p2.y==next_vec->y)) {     
  468. new_vec.x=newline_p->p1.x;
  469. new_vec.y=newline_p->p1.y;
  470. } else {                                                             
  471. new_vec.x=newline_p->p2.x;
  472. new_vec.y=newline_p->p2.y;
  473. }
  474. memcpy((pvector2)frontlist_i->data+frontlist_i->count, &new_vec, sizeof(vector2));
  475. frontlist_i->count++;
  476. frontlist_i->data=(pvector2)MyRealloc(frontlist_i->data, 
  477. sizeof(vector2) *(frontlist_i->count), sizeof(vector2) *(frontlist_i->count+1));
  478. memcpy((pvector2)backlist_i->data+backlist_i->count, &new_vec, sizeof(vector2));
  479. backlist_i->count++;
  480. backlist_i->data=(pvector2)MyRealloc(backlist_i->data, 
  481. sizeof(vector2) *(backlist_i->count), sizeof(vector2) *(backlist_i->count+1));
  482.  
  483. if ((newline_p->p2.x==next_vec->x) && (newline_p->p2.y==next_vec->y)) {
  484.  memcpy((pvector2)backlist_i->data+backlist_i->count, next_vec, sizeof(vector2));
  485.  backlist_i->count++;
  486.  backlist_i->data=(pvector2)MyRealloc(backlist_i->data, 
  487.  sizeof(vector2) *(backlist_i->count), sizeof(vector2) *(backlist_i->count+1));
  488. } else {
  489.  memcpy((pvector2)frontlist_i->data+frontlist_i->count, next_vec, sizeof(vector2));
  490.  frontlist_i->count++;
  491.  frontlist_i->data=(pvector2)MyRealloc(frontlist_i->data, 
  492.  sizeof(vector2) *(frontlist_i->count), sizeof(vector2) *(frontlist_i->count+1));
  493. }
  494. break;
  495. default:
  496.   Error("Bad Cut Box!");
  497.   break;
  498. }
  499. cur_vec=next_vec;
  500. }
  501. }
  502. /*                              
  503. ================
  504. =
  505. = BSPList
  506. =
  507. = Takes a storage of lines and recursively partitions the list
  508. = Returns a bspnode_t
  509. ================
  510. */
  511. /* float        gray = NX_WHITE; */
  512. float gray = 0;                                                            
  513. /* bspnode_t *BSPList (id lines_i)
  514. */
  515. bspnode_t *BSPList(STORAGE *lines_i, STORAGE * cutbox_i)
  516. {
  517. /*      id                              frontlist_i, backlist_i;
  518. */
  519. STORAGE *frontlist_i, *backlist_i;
  520. STORAGE *cutbacklist_i, *cutfrontlist_i;
  521. int                             i,c, step;
  522. line_t                  *line_p, *bestline_p;
  523. int                             v, bestv;
  524. bspnode_t               *node_p;
  525. /*
  526. if (draw)
  527. PSsetgray (gray);
  528. gray = 1.0 - gray;
  529. */
  530. node_p = (bspnode_t *)Alloc_Mem (sizeof(*node_p));
  531. memset (node_p, 0, sizeof(*node_p));
  532. /*
  533.  find the best line to partition on
  534. */
  535. /*      c = [lines_i count];
  536. */
  537. c = lines_i->count;
  538. bestv = INT_MAX;
  539. bestline_p = NULL;
  540. step = (c/40)+1;                /* set this to 1 for an exhaustive search */
  541. research:
  542. for (i=0 ; i<c ; i+=step)
  543. {
  544. /*              line_p = [lines_i elementAt:i];
  545. */
  546. line_p = (line_t *)lines_i->data + i;
  547. v = EvaluateSplit (lines_i, line_p, bestv);
  548. if (v<bestv)
  549. {
  550. bestv = v;
  551. bestline_p = line_p;
  552. }
  553. }
  554. /*
  555.  if none of the lines should be split, the remaining lines
  556.  are convex, and form a terminal node
  557. */
  558. /*
  559. printf ("bestv:%in",bestv);
  560. */
  561. if (bestv == INT_MAX)
  562. {
  563. if (step > 1)
  564. {       /* possible to get here with non convex area if BSPSLIDE specials
  565.  caused rejections */
  566. step = 1;
  567. goto research;
  568. }
  569. node_p->lines_i = lines_i;
  570. node_p->cutbox_i= cutbox_i;
  571. return node_p;
  572. }
  573. /*
  574.  divide the line list into two nodes along the best split line
  575. */
  576. DivlineFromWorldline (&node_p->divline, bestline_p);
  577. /*
  578. frontlist_i =
  579. [[Storage alloc]
  580. initCount:              0
  581. elementSize:    sizeof(line_t)
  582. description:    NULL];
  583. backlist_i =
  584. [[Storage alloc]
  585. initCount:              0
  586. elementSize:    sizeof(line_t)
  587. description:    NULL];
  588. */
  589. frontlist_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  590. frontlist_i->count = 0;
  591. frontlist_i->size = sizeof(line_t);
  592. frontlist_i->data = (line_t *)SafeMalloc(sizeof(line_t));
  593. backlist_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  594. backlist_i->count = 0;
  595. backlist_i->size = sizeof(line_t);
  596. backlist_i->data = (line_t *)SafeMalloc(sizeof(line_t));
  597. ExecuteSplit (lines_i, bestline_p, frontlist_i, backlist_i);
  598. cutfrontlist_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  599. cutfrontlist_i->count = 0;
  600. cutfrontlist_i->size = sizeof(vector2);
  601. cutfrontlist_i->data = (pvector2)SafeMalloc(sizeof(vector2));
  602. cutbacklist_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  603. cutbacklist_i->count = 0;
  604. cutbacklist_i->size = sizeof(vector2);
  605. cutbacklist_i->data = (pvector2)SafeMalloc(sizeof(vector2));
  606. SplitCutBoxes(cutbox_i, bestline_p, cutfrontlist_i, cutbacklist_i);
  607. /*
  608.  recursively divide the lists
  609. */
  610. node_p->side[0] = BSPList (frontlist_i, cutfrontlist_i);
  611. node_p->side[1] = BSPList (backlist_i, cutbacklist_i);
  612. return node_p;
  613. }
  614. /*
  615. =====================
  616. =
  617. = MakeSegs
  618. =
  619. =====================
  620. */
  621. STORAGE *initialcutbox_i;
  622. void MakeInitialCutBox() {
  623. pvector2 v1,v2,v3,v4;                                                      
  624. long min_x, min_y, max_x, max_y;
  625. pvector2 cur_vec;
  626. short counter;
  627. // Get min and max points of world be looping through vectors
  628. min_x=max_x=Vector_List[0].x;
  629. min_y=max_y=Vector_List[0].y;
  630. for (counter=1; counter < Number_Of_Vectors; counter++) {
  631. cur_vec=Vector_List+counter;
  632. if (cur_vec->x < min_x)
  633. min_x=cur_vec->x;
  634. if (cur_vec->y < min_y)
  635. min_y=cur_vec->y;
  636. if (cur_vec->x > max_x)
  637. max_x=cur_vec->x;
  638. if (cur_vec->y > max_y)
  639. max_y=cur_vec->y;
  640. }
  641. initialcutbox_i=(STORAGE *)SafeMalloc(sizeof(STORAGE));
  642. initialcutbox_i->count=4;
  643. initialcutbox_i->size=4*sizeof(vector2);
  644. initialcutbox_i->data=(pvector2)SafeMalloc(4 * sizeof(vector2));
  645. v1=(pvector2)initialcutbox_i->data+0;
  646. v2=(pvector2)initialcutbox_i->data+1;
  647. v3=(pvector2)initialcutbox_i->data+2;
  648. v4=(pvector2)initialcutbox_i->data+3;
  649. v1->x=min_x;
  650. v1->y=min_y;
  651. v2->x=min_x;
  652. v2->y=max_y;
  653. v3->x=max_x;
  654. v3->y=max_y;
  655. v4->x=max_x;
  656. v4->y=min_y;
  657. }
  658. /* id segstore_i;
  659. */
  660. STORAGE *segstore_i;
  661. void MakeSegs (void)
  662. {
  663. int                             i, count;
  664. worldline_t             *wl;
  665. /* line_t   li;
  666. */
  667. line_t                  *li;
  668. /*
  669. segstore_i =
  670. [[Storage alloc]
  671. initCount:              0
  672. elementSize:    sizeof(line_t)
  673. description:    NULL];
  674. */
  675. segstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  676. segstore_i->data = (line_t *)SafeMalloc(sizeof(line_t));
  677. segstore_i->count = 0;
  678. segstore_i->size = sizeof(line_t);
  679. /*
  680. count = [linestore_i count];
  681. wl = [linestore_i elementAt:0];
  682. */
  683. count = linestore_i->count;
  684. wl = linestore_i->data;
  685. li = segstore_i->data;
  686. for (i= 0 ; i<count ; i++, wl++)
  687. {
  688. li->p1 = wl->p1;
  689. li->p2 = wl->p2;
  690. li->linedef = i;
  691. li->side = 0;
  692. li->offset = 0;
  693. li->grouped = false;
  694. /*              [segstore_i addElement: &li];
  695. */
  696. segstore_i->count += 1;
  697. segstore_i->data = (line_t *)MyRealloc(segstore_i->data,
  698. sizeof(line_t) * (segstore_i->count), sizeof(line_t) * (segstore_i->count + 1));
  699. li = (line_t *)segstore_i->data + segstore_i->count;
  700. if (wl->flags & ML_TWOSIDED)
  701. {
  702. li->p1 = wl->p2;
  703. li->p2 = wl->p1;
  704. li->linedef = i;
  705. li->side = 1;
  706. li->offset = 0;
  707. li->grouped = false;
  708. /*                      [segstore_i addElement: &li];
  709. */
  710. segstore_i->count += 1;
  711. segstore_i->data = (line_t *)MyRealloc(segstore_i->data,
  712. sizeof(line_t) * (segstore_i->count), sizeof(line_t) * (segstore_i->count + 1));
  713. li = (line_t *)segstore_i->data + segstore_i->count;
  714. }
  715. }
  716. }
  717. /*
  718. =====================
  719. =
  720. = BuildBSP
  721. =
  722. =====================
  723. */
  724. bspnode_t       *startnode;
  725. void BuildBSP (void)
  726. {
  727. MakeSegs ();
  728.   MakeInitialCutBox();
  729. cuts = 0;
  730. startnode = BSPList (segstore_i, initialcutbox_i);
  731. }