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

游戏

开发平台:

Visual C++

  1. /* bspstruc.c */
  2. #include "ray.h"
  3. #include "globals.h"
  4. #include "idbsp.h"
  5. #include "sortseg.h"
  6. #include <mem.h>
  7.   
  8. #define Get_Sec_From_SSec(x) ((Seg_List+((x)->seg_start))->ld->s[(short)(Seg_List+((x)->seg_start))->left_sidedef]->sec)
  9.   
  10. /*
  11. id              secstore_i;
  12. id              mapvertexstore_i;
  13. id              subsecstore_i;
  14. id              maplinestore_i;
  15. id              nodestore_i;
  16. id              mapthingstore_i;
  17. id              ldefstore_i;
  18. id              sdefstore_i;
  19. */
  20. STORAGE *subsecstore_i;
  21. STORAGE *maplinestore_i;
  22. STORAGE *nodestore_i;
  23. void * MyRealloc(void * ptr, long old_size, long new_size) {
  24. void * temp_ptr=SafeMalloc(new_size);
  25. memmove(temp_ptr, ptr, old_size);
  26. Free_Mem(ptr);
  27. return temp_ptr;
  28. }
  29. /*
  30. ===============================================================================
  31. PROCESSING
  32. ===============================================================================
  33. */
  34. /*
  35. =================
  36. =
  37. = LineFromSeg
  38. =
  39. =================
  40. */
  41. void LineFromSeg(mapseg_t * seg, line_t * line) {
  42. memset(line, 0, sizeof(line));
  43. line->p1.x=Vector_List[seg->v1].x;
  44. line->p1.y=Vector_List[seg->v1].y;
  45. line->p2.x=Vector_List[seg->v2].x;
  46. line->p2.y=Vector_List[seg->v2].y;
  47. }
  48. /*
  49. =================
  50. =
  51. = UniqueVertex
  52. =
  53. = Returns the vertex number, adding a new vertex if needed
  54. =================
  55. */
  56. int UniqueVertex (int x, int y)
  57. {
  58. int                             i, count;
  59. vector2             mv;
  60. pvector2 mvp;
  61. mv.x = x;
  62. mv.y = y;
  63. /* see if an identical vertex already exists */
  64. /*
  65. count = [mapvertexstore_i count];
  66. mvp = [mapvertexstore_i elementAt:0];
  67. */
  68. count = Number_Of_Vectors;
  69. mvp=Vector_List;
  70. for (i=0 ; i<count ; i++, mvp++)
  71. if (mvp->x == mv.x && mvp->y == mv.y)
  72. return i;
  73. /*      [mapvertexstore_i addElement: &mv]; */
  74. Number_Of_Vectors++;
  75. Vector_List = (pvector2)MyRealloc(Vector_List,
  76. sizeof(vector2) * (Number_Of_Vectors-1),
  77.   sizeof(vector2) * (Number_Of_Vectors));
  78. memcpy(Vector_List+Number_Of_Vectors-1, &mv,                         
  79. sizeof(vector2));
  80. return count;
  81. }
  82. /*
  83. =============================================================================
  84. */
  85. float   bbox[4];
  86. /*
  87. =================
  88. =
  89. = AddPointToBBox
  90. =
  91. =================
  92. */
  93. void AddPointToBBox (float x, float y)
  94. {
  95. if (x < bbox[BOXLEFT])
  96. bbox[BOXLEFT] = x;
  97. if (x > bbox[BOXRIGHT])
  98. bbox[BOXRIGHT] = x;
  99. if (y > bbox[BOXTOP])
  100. bbox[BOXTOP] = y;
  101. if (y < bbox[BOXBOTTOM])
  102. bbox[BOXBOTTOM] = y;
  103. }
  104. /*
  105. =================
  106. =
  107. = ProcessLines
  108. =
  109. = Adds the lines in a subsector to the mapline storage
  110. =================
  111. */
  112. /* void ProcessLines (id store_i) */
  113. void ProcessLines(STORAGE *store_i)
  114. {
  115. int                     i,count;
  116. line_t          *wline;
  117. mapseg_t        line;
  118. short           angle;
  119. float           fangle;
  120. bbox[BOXLEFT] = INT_MAX;
  121. bbox[BOXRIGHT] = INT_MIN;
  122. bbox[BOXTOP] = INT_MIN;
  123. bbox[BOXBOTTOM] = INT_MAX;
  124. /*      count = [store_i count]; */
  125. count = store_i->count;
  126. for (i=0 ; i<count ; i++)
  127. {
  128. /*              wline = [store_i elementAt: i]; */
  129. wline = (line_t *)store_i->data + i;
  130. if (wline->grouped)
  131. printf ("ERROR: line regroupedn");
  132. wline->grouped = true;
  133. memset (&line, 0, sizeof(line));
  134. AddPointToBBox (wline->p1.x, wline->p1.y);
  135. AddPointToBBox (wline->p2.x, wline->p2.y);
  136. line.v1 = UniqueVertex (wline->p1.x, wline->p1.y);
  137. line.v2 = UniqueVertex (wline->p2.x, wline->p2.y);
  138. line.linedef = wline->linedef;
  139. line.side = wline->side;
  140. line.offset = wline->offset;
  141. fangle = atan2 (wline->p2.y - wline->p1.y, wline->p2.x - wline->p1.x);
  142. /************************ CHANGED BY MATT! *********************************/                
  143. angle = (short)(fangle/(PI*2)*ANGLE_360);
  144. if (angle<0) angle+=ANGLE_360; // get rid of negative angles
  145. /************************ END CHANGED BY MATT! *****************************/
  146. line.angle = angle;
  147. /*              [maplinestore_i addElement: &line]; */
  148. memcpy((mapseg_t *)maplinestore_i->data + maplinestore_i->count, &line,
  149. sizeof(line));
  150. maplinestore_i->count += 1;
  151. maplinestore_i->data = (mapseg_t *)MyRealloc(maplinestore_i->data,
  152. sizeof(mapseg_t) * (maplinestore_i->count),
  153.  sizeof(mapseg_t) * (maplinestore_i->count+1));
  154. }
  155. }
  156. /*
  157. =================
  158. =
  159. = FinishCut
  160. =
  161. = Cuts a box agains lines in sub sector ****MADE BY MATT****
  162. =================
  163. */
  164. STORAGE * FinishCut(mapsubsector_t * cur_ssec, STORAGE * cutbox_i)
  165. {
  166. STORAGE * new_front;
  167. STORAGE * back_temp;
  168. STORAGE * cur_list;
  169. short cur_seg_index;             
  170. mapseg_t * cur_seg;
  171. line_t spliton;
  172. cur_list=cutbox_i;
  173. for (cur_seg_index=0; cur_seg_index<cur_ssec->numsegs; cur_seg_index++) {
  174. cur_seg=(mapseg_t *)maplinestore_i->data+cur_ssec->firstseg+cur_seg_index;        
  175. LineFromSeg(cur_seg, &spliton); 
  176. new_front=(STORAGE *)SafeMalloc(sizeof(STORAGE));
  177. new_front->count = 0;
  178. new_front->size = sizeof(vector2);
  179. new_front->data = (pvector2)SafeMalloc(sizeof(vector2));
  180. back_temp=(STORAGE *)SafeMalloc(sizeof(STORAGE));
  181. back_temp->count = 0;
  182. back_temp->size = sizeof(vector2);
  183. back_temp->data = (pvector2)SafeMalloc(sizeof(vector2));
  184. SplitCutBoxes(cur_list, &spliton, new_front, back_temp);
  185. Free_Mem(back_temp->data);
  186. Free_Mem(back_temp);
  187. Free_Mem(cur_list->data);
  188. Free_Mem(cur_list);
  189. cur_list=new_front;
  190. }
  191. return cur_list;
  192. }
  193. /*
  194. =================
  195. =
  196. = Makes alternate bound box, using cut box
  197. =
  198. =================
  199. */
  200. void Make_Alt_BBox(mapsubsector_t * cur_ssec) {
  201. pvector2 cur_vec;
  202. short count, counter;
  203. bbox[BOXLEFT] = INT_MAX;
  204. bbox[BOXRIGHT] = INT_MIN;
  205. bbox[BOXTOP] = INT_MIN;
  206. bbox[BOXBOTTOM] = INT_MAX;
  207.   count=cur_ssec->cutbox->count;
  208.   for (counter=0; counter<count; counter++) {
  209.   cur_vec=(pvector2)cur_ssec->cutbox->data+counter;
  210.   AddPointToBBox(cur_vec->x, cur_vec->y);
  211. }
  212. }
  213. /*         
  214. =================
  215. =
  216. = ProcessSubsector
  217. =
  218. =================
  219. */
  220. /* int ProcessSubsector (id wmaplinestore_i) */
  221. int ProcessSubsector(STORAGE *wmaplinestore_i, STORAGE *cutbox_i)
  222. {
  223. int                             count;
  224. worldline_t             *linedef;
  225. line_t                  *wline;
  226. mapsubsector_t  sub;
  227. memset (&sub,0,sizeof(sub));
  228. /*      count = [wmaplinestore_i count]; */
  229. count = wmaplinestore_i->count;
  230. if (count < 1)
  231. Error ("ProcessSubsector: count = %i",count);
  232. /*      wline = [wmaplinestore_i elementAt: 0]; */
  233. wline = wmaplinestore_i->data;
  234. /*      linedef = [linestore_i elementAt: wline->linedef]; */
  235. linedef = (worldline_t *)linestore_i->data + wline->linedef;
  236. sub.numsegs = count;
  237. /*      sub.firstseg = [maplinestore_i count]; */
  238. sub.firstseg = maplinestore_i->count;
  239. ProcessLines (wmaplinestore_i);
  240. sub.cutbox=FinishCut(&sub, cutbox_i); 
  241.   Make_Alt_BBox(&sub);
  242. /* add the new subsector
  243. [subsecstore_i addElement: &sub];
  244. */
  245. memcpy((mapsubsector_t *)subsecstore_i->data + subsecstore_i->count, &sub,
  246. sizeof(mapsubsector_t));
  247. subsecstore_i->count += 1;
  248. subsecstore_i->data = (mapsubsector_t *)MyRealloc(subsecstore_i->data,
  249.   sizeof(mapsubsector_t) * (subsecstore_i->count),
  250. sizeof(mapsubsector_t) * (subsecstore_i->count + 1));
  251. /*      return [subsecstore_i count]-1; */
  252. return subsecstore_i->count - 1;
  253. }
  254. /*
  255. =================
  256. =
  257. = ProcessNode
  258. =
  259. =================
  260. */
  261. int ProcessNode (bspnode_t *node, short *totalbox)
  262. {
  263. short           subbox[2][4];
  264. int                     i, r;
  265. mapnode_t       mnode;
  266. memset (&mnode,0,sizeof(mnode));
  267. if (node->lines_i)      /* NF_SUBSECTOR flags a subsector */
  268. {
  269. r = ProcessSubsector (node->lines_i, node->cutbox_i);
  270. for (i=0 ; i<4 ; i++)
  271. totalbox[i] = bbox[i];
  272. return r | NF_SUBSECTOR;
  273. }
  274. mnode.x =node->divline.pt.x;
  275. mnode.y =node->divline.pt.y;
  276. mnode.dx =node->divline.dx;
  277. mnode.dy =node->divline.dy;
  278. r = ProcessNode(node->side[0], subbox[0]);
  279. mnode.children[0] =r;
  280. for (i=0 ; i<4 ; i++)
  281. mnode.bbox[0][i] =subbox[0][i];
  282. r = ProcessNode (node->side[1],subbox[1]);
  283. mnode.children[1] =r;
  284. for (i=0 ; i<4 ; i++)
  285. mnode.bbox[1][i] =subbox[1][i];
  286. totalbox[BOXLEFT] = MIN(subbox[0][BOXLEFT], subbox[1][BOXLEFT]);
  287. totalbox[BOXTOP] = MAX(subbox[0][BOXTOP], subbox[1][BOXTOP]);
  288. totalbox[BOXRIGHT] = MAX(subbox[0][BOXRIGHT], subbox[1][BOXRIGHT]);
  289. totalbox[BOXBOTTOM] = MIN(subbox[0][BOXBOTTOM], subbox[1][BOXBOTTOM]);
  290. /*      [nodestore_i addElement: &mnode]; */
  291. memcpy((mapnode_t *)nodestore_i->data + nodestore_i->count, &mnode, sizeof(mapnode_t));
  292. nodestore_i->count += 1;
  293. nodestore_i->data = (mapnode_t *)MyRealloc(nodestore_i->data,
  294.   sizeof(mapnode_t) * (nodestore_i->count),
  295. sizeof(mapnode_t) * (nodestore_i->count + 1));
  296. /*      return [nodestore_i count] - 1; */
  297. return nodestore_i->count - 1;
  298. }
  299. /*
  300. =================
  301. =
  302. = ProcessNodes
  303. =
  304. = Recursively builds the nodes, subsectors, and line lists,
  305. = then writes the lumps
  306. =================
  307. */
  308. void ProcessNodes (void)
  309. {
  310. short   worldbounds[4];
  311. /*
  312. subsecstore_i = [[Storage alloc]
  313. initCount:              0
  314. elementSize:    sizeof(mapsubsector_t)
  315. description:    NULL];
  316. maplinestore_i = [[Storage alloc]
  317. initCount:              0
  318. elementSize:    sizeof(mapseg_t)
  319. description:    NULL];
  320. nodestore_i = [[Storage alloc]
  321. initCount:              0
  322. elementSize:    sizeof(mapnode_t)
  323. description:    NULL];
  324. */
  325. subsecstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  326. subsecstore_i->data = (mapsubsector_t *)SafeMalloc(sizeof(mapsubsector_t));
  327. subsecstore_i->count = 0;
  328. subsecstore_i->size = sizeof(mapsubsector_t);
  329. maplinestore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  330. maplinestore_i->data = (mapseg_t *)SafeMalloc(sizeof(mapseg_t));
  331. maplinestore_i->count = 0;
  332. maplinestore_i->size = sizeof(mapseg_t);
  333. nodestore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
  334. nodestore_i->data = (mapnode_t *)SafeMalloc(sizeof(mapnode_t));
  335. nodestore_i->count = 0;
  336. nodestore_i->size = sizeof(mapnode_t);
  337. ProcessNode (startnode, worldbounds);
  338. }
  339. /*
  340. =============================================================================
  341. */
  342. /*
  343. ==================
  344. =
  345. = ConvertNodes
  346. =
  347. = Converts data to My format ****MADE BY MATT****
  348. ==================
  349. */
  350. void ConvertNodes() {
  351. short counter;
  352. pseg cur_seg;
  353. pssector cur_ssec;
  354. bsp_node * cur_node;
  355. prectl cur_rect;
  356. mapseg_t * cur_doom_seg;
  357. mapsubsector_t * cur_doom_ssec;
  358. mapnode_t * cur_doom_node;
  359. psorted_vector_type sorted_list;
  360. // Seg conversion
  361. Number_Of_Segs=maplinestore_i->count;
  362. Seg_List=(pseg)SafeMalloc(Number_Of_Segs * sizeof(seg));
  363. for (counter=0; counter<Number_Of_Segs; counter++) {
  364. cur_seg=Seg_List+counter;
  365. cur_doom_seg=(mapseg_t *)maplinestore_i->data+counter;
  366. cur_seg->v[0]=cur_doom_seg->v1;
  367. cur_seg->v[1]=cur_doom_seg->v2;
  368. cur_seg->angle=cur_doom_seg->angle;
  369. cur_seg->ld=Ld_List+cur_doom_seg->linedef;
  370. cur_seg->left_sidedef=(cur_doom_seg->side > 0 ? TRUE : FALSE);
  371. cur_seg->linedef_offset=cur_doom_seg->offset;
  372. }
  373. Free_Mem(maplinestore_i->data);
  374. Free_Mem(maplinestore_i);
  375. // SubSector conversion
  376. Number_Of_SSectors=subsecstore_i->count;
  377. SS_List=(pssector)SafeMalloc(Number_Of_SSectors * sizeof(ssector));
  378. for (counter=0; counter<Number_Of_SSectors; counter++) {
  379. cur_ssec=SS_List+counter;
  380. cur_doom_ssec=(mapsubsector_t *)subsecstore_i->data+counter;
  381. cur_ssec->seg_start=cur_doom_ssec->firstseg;
  382. cur_ssec->seg_end=cur_doom_ssec->firstseg+cur_doom_ssec->numsegs-1;
  383. cur_ssec->flags=Get_Sec_From_SSec(cur_ssec)->flags;
  384. if (cur_ssec->flags & VOXEL_SSECTOR) {
  385. sorted_list=(psorted_vector_type)SafeMalloc(sizeof(sorted_vector_type));
  386. sorted_list->vector_count=cur_doom_ssec->cutbox->count;
  387. sorted_list->vectors=cur_doom_ssec->cutbox->data;
  388. cur_ssec->extra_data=(pdata)sorted_list;
  389. } else { 
  390. Free_Mem(cur_doom_ssec->cutbox->data);
  391. Free_Mem(cur_doom_ssec->cutbox);
  392. cur_ssec->extra_data=NULL;
  393. }
  394. cur_ssec->objects=NULL;
  395. cur_ssec->num_objects=0;                  
  396. }
  397. Free_Mem(subsecstore_i->data);
  398. Free_Mem(subsecstore_i);
  399. // Node conversion
  400. Number_Of_Nodes=nodestore_i->count;
  401. bsp_start_node=nodestore_i->count-1;
  402. bsp_tree=(bsp_node *)SafeMalloc(Number_Of_Nodes * sizeof(bsp_node));
  403. for (counter=0; counter<Number_Of_Nodes; counter++) {
  404. cur_node=bsp_tree+counter;
  405. cur_doom_node=(mapnode_t *)nodestore_i->data+counter;
  406. cur_node->x1=cur_doom_node->x;
  407. cur_node->y1=cur_doom_node->y;
  408. cur_node->x2=cur_doom_node->x+cur_doom_node->dx;
  409. cur_node->y2=cur_doom_node->y+cur_doom_node->dy;
  410. cur_rect=&(cur_node->left_bound);
  411. cur_rect->top=cur_doom_node->bbox[1][BOXTOP];
  412. cur_rect->left=cur_doom_node->bbox[1][BOXLEFT];
  413. cur_rect->bottom=cur_doom_node->bbox[1][BOXBOTTOM];
  414. cur_rect->right=cur_doom_node->bbox[1][BOXRIGHT];
  415. cur_rect=&(cur_node->right_bound);
  416. cur_rect->top=cur_doom_node->bbox[0][BOXTOP];
  417. cur_rect->left=cur_doom_node->bbox[0][BOXLEFT];
  418. cur_rect->bottom=cur_doom_node->bbox[0][BOXBOTTOM];
  419. cur_rect->right=cur_doom_node->bbox[0][BOXRIGHT];
  420. cur_node->left_child=cur_doom_node->children[1];
  421. cur_node->right_child=cur_doom_node->children[0];
  422. } /* endfor */
  423. Free_Mem(nodestore_i->data);
  424. Free_Mem(nodestore_i);
  425. }
  426. /*
  427. ==================
  428. =
  429. = Make_Line_List
  430. =
  431. = Makes linedefs usable by bsp generator ****MADE BY MATT*****
  432. ==================
  433. */
  434. void Make_Line_List() {
  435. short counter;
  436. plinedef cur_ld;
  437. worldline_t * cur_doom_ld;
  438. linestore_i=(STORAGE *)SafeMalloc(sizeof(STORAGE));
  439. linestore_i->count=Number_Of_Linedefs;
  440. linestore_i->size=Number_Of_Linedefs * sizeof(worldline_t);
  441. linestore_i->data=(worldline_t *)SafeMalloc(linestore_i->size);
  442. for (counter=0; counter<Number_Of_Linedefs; counter++) {
  443. cur_ld=Ld_List+counter;
  444. cur_doom_ld=(worldline_t *)linestore_i->data+counter;
  445. cur_doom_ld->p1.x=Vector_List[cur_ld->v[0]].x;
  446. cur_doom_ld->p1.y=Vector_List[cur_ld->v[0]].y;
  447. cur_doom_ld->p2.x=Vector_List[cur_ld->v[1]].x;
  448. cur_doom_ld->p2.y=Vector_List[cur_ld->v[1]].y;
  449. cur_doom_ld->tag=cur_ld->tag;
  450. cur_doom_ld->special=cur_ld->tag_type;
  451. cur_doom_ld->flags=cur_ld->attributes;
  452. }
  453. }
  454.  
  455. /*                                      
  456. ==================
  457. =
  458. = ConvBSP
  459. =
  460. ==================
  461. */
  462. void ConvBSP (void)
  463. {
  464. ProcessNodes ();
  465. ConvertNodes();
  466. }