SetBrush.m 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035
  1. #import "qedefs.h"
  2. @implementation SetBrush
  3. /*
  4. ==================
  5. textureAxisFromPlane
  6. ==================
  7. */
  8. #if 1
  9. vec3_t baseaxis[18] =
  10. {
  11. {0,0,1}, {1,0,0}, {0,-1,0}, // floor
  12. {0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
  13. {1,0,0}, {0,1,0}, {0,0,-1}, // west wall
  14. {-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
  15. {0,1,0}, {1,0,0}, {0,0,-1}, // south wall
  16. {0,-1,0}, {1,0,0}, {0,0,-1} // north wall
  17. };
  18. #else
  19. vec3_t baseaxis[18] =
  20. {
  21. {0,0,1}, {1,0,0}, {0,-1,0}, // floor
  22. {0,0,-1}, {1,0,0}, {0,1,0}, // ceiling
  23. {1,0,0}, {0,1,0}, {0,0,-1}, // west wall
  24. {-1,0,0}, {0,-1,0}, {0,0,-1}, // east wall
  25. {0,1,0}, {-1,0,0}, {0,0,-1}, // south wall
  26. {0,-1,0}, {1,0,0}, {0,0,-1} // north wall
  27. };
  28. #endif
  29. float TextureAxisFromPlane(plane_t *pln, float *xv, float *yv)
  30. {
  31. int bestaxis;
  32. float dot,best;
  33. int i;
  34. best = 0;
  35. bestaxis = 0;
  36. for (i=0 ; i<6 ; i++)
  37. {
  38. dot = DotProduct (pln->normal, baseaxis[i*3]);
  39. if (dot > best)
  40. {
  41. best = dot;
  42. bestaxis = i;
  43. }
  44. }
  45. VectorCopy (baseaxis[bestaxis*3+1], xv);
  46. VectorCopy (baseaxis[bestaxis*3+2], yv);
  47. return lightaxis[bestaxis>>1];
  48. }
  49. #define BOGUS_RANGE 18000
  50. /*
  51. =================
  52. CheckFace
  53. Note: this will not catch 0 area polygons
  54. =================
  55. */
  56. void CheckFace (face_t *f)
  57. {
  58. int i, j;
  59. float *p1, *p2;
  60. float d, edgedist;
  61. vec3_t dir, edgenormal;
  62. winding_t *w;
  63. w = f->w;
  64. if (!w)
  65. Error ("CheckFace: no winding");
  66. if (w->numpoints < 3)
  67. Error ("CheckFace: %i points",w->numpoints);
  68. for (i=0 ; i<w->numpoints ; i++)
  69. {
  70. p1 = w->points[i];
  71. for (j=0 ; j<3 ; j++)
  72. if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
  73. Error ("CheckFace: BUGUS_RANGE: %f",p1[j]);
  74. j = i+1 == w->numpoints ? 0 : i+1;
  75. // check the point is on the face plane
  76. d = DotProduct (p1, f->plane.normal) - f->plane.dist;
  77. if (d < -ON_EPSILON || d > ON_EPSILON)
  78. Error ("CheckFace: point off plane");
  79. // check the edge isn't degenerate
  80. p2 = w->points[j];
  81. VectorSubtract (p2, p1, dir);
  82. if (VectorLength (dir) < ON_EPSILON)
  83. Error ("CheckFace: degenerate edge");
  84. CrossProduct (f->plane.normal, dir, edgenormal);
  85. VectorNormalize (edgenormal);
  86. edgedist = DotProduct (p1, edgenormal);
  87. edgedist += ON_EPSILON;
  88. // all other points must be on front side
  89. for (j=0 ; j<w->numpoints ; j++)
  90. {
  91. if (j == i)
  92. continue;
  93. d = DotProduct (w->points[j], edgenormal);
  94. if (d > edgedist)
  95. Error ("CheckFace: non-convex");
  96. }
  97. }
  98. }
  99. /*
  100. =============================================================================
  101. TURN PLANES INTO GROUPS OF FACES
  102. =============================================================================
  103. */
  104. /*
  105. ==================
  106. NewWinding
  107. ==================
  108. */
  109. winding_t *NewWinding (int points)
  110. {
  111. winding_t *w;
  112. int size;
  113. if (points > MAX_POINTS_ON_WINDING)
  114. Error ("NewWinding: %i points", points);
  115. size = (int)((winding_t *)0)->points[points];
  116. w = malloc (size);
  117. memset (w, 0, size);
  118. return w;
  119. }
  120. /*
  121. ==================
  122. CopyWinding
  123. ==================
  124. */
  125. winding_t *CopyWinding (winding_t *w)
  126. {
  127. int size;
  128. winding_t *c;
  129. size = (int)((winding_t *)0)->points[w->numpoints];
  130. c = malloc (size);
  131. memcpy (c, w, size);
  132. return c;
  133. }
  134. /*
  135. ==================
  136. ClipWinding
  137. Clips the winding to the plane, returning the new winding on the positive side
  138. Frees the input winding.
  139. ==================
  140. */
  141. winding_t *ClipWinding (winding_t *in, plane_t *split)
  142. {
  143. float dists[MAX_POINTS_ON_WINDING];
  144. int sides[MAX_POINTS_ON_WINDING];
  145. int counts[3];
  146. float dot;
  147. int i, j;
  148. float *p1, *p2, *mid;
  149. winding_t *neww;
  150. int maxpts;
  151. counts[0] = counts[1] = counts[2] = 0;
  152. // determine sides for each point
  153. for (i=0 ; i<in->numpoints ; i++)
  154. {
  155. dot = DotProduct (in->points[i], split->normal);
  156. dot -= split->dist;
  157. dists[i] = dot;
  158. if (dot > ON_EPSILON)
  159. sides[i] = SIDE_FRONT;
  160. else if (dot < -ON_EPSILON)
  161. sides[i] = SIDE_BACK;
  162. else
  163. {
  164. sides[i] = SIDE_ON;
  165. }
  166. counts[sides[i]]++;
  167. }
  168. sides[i] = sides[0];
  169. dists[i] = dists[0];
  170. if (!counts[0] && !counts[1])
  171. return in;
  172. if (!counts[0])
  173. {
  174. free (in);
  175. return NULL;
  176. }
  177. if (!counts[1])
  178. return in;
  179. maxpts = in->numpoints+4; // can't use counts[0]+2 because
  180. // of fp grouping errors
  181. neww = NewWinding (maxpts);
  182. for (i=0 ; i<in->numpoints ; i++)
  183. {
  184. p1 = in->points[i];
  185. mid = neww->points[neww->numpoints];
  186. if (sides[i] == SIDE_FRONT || sides[i] == SIDE_ON)
  187. {
  188. VectorCopy (p1, mid);
  189. mid[3] = p1[3];
  190. mid[4] = p1[4];
  191. neww->numpoints++;
  192. if (sides[i] == SIDE_ON)
  193. continue;
  194. mid = neww->points[neww->numpoints];
  195. }
  196. if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  197. continue;
  198. // generate a split point
  199. if (i == in->numpoints - 1)
  200. p2 = in->points[0];
  201. else
  202. p2 = p1 + 5;
  203. neww->numpoints++;
  204. dot = dists[i] / (dists[i]-dists[i+1]);
  205. for (j=0 ; j<3 ; j++)
  206. { // avoid round off error when possible
  207. if (split->normal[j] == 1)
  208. mid[j] = split->dist;
  209. else if (split->normal[j] == -1)
  210. mid[j] = -split->dist;
  211. mid[j] = p1[j] + dot*(p2[j]-p1[j]);
  212. }
  213. mid[3] = p1[3] + dot*(p2[3]-p1[3]);
  214. mid[4] = p1[4] + dot*(p2[4]-p1[4]);
  215. }
  216. if (neww->numpoints > maxpts)
  217. Error ("ClipWinding: points exceeded estimate");
  218. // free the original winding
  219. free (in);
  220. return neww;
  221. }
  222. /*
  223. =================
  224. BasePolyForPlane
  225. There has GOT to be a better way of doing this...
  226. =================
  227. */
  228. winding_t *BasePolyForPlane (face_t *f)
  229. {
  230. int i, x;
  231. float max, v;
  232. vec3_t org, vright, vup;
  233. vec3_t xaxis, yaxis;
  234. winding_t *w;
  235. texturedef_t *td;
  236. plane_t *p;
  237. float ang, sinv, cosv;
  238. float s, t, ns, nt;
  239. p = &f->plane;
  240. // find the major axis
  241. max = -BOGUS_RANGE;
  242. x = -1;
  243. for (i=0 ; i<3; i++)
  244. {
  245. v = fabs(p->normal[i]);
  246. if (v > max)
  247. {
  248. x = i;
  249. max = v;
  250. }
  251. }
  252. if (x==-1)
  253. Error ("BasePolyForPlane: no axis found");
  254. VectorCopy (vec3_origin, vup);
  255. switch (x)
  256. {
  257. case 0:
  258. case 1:
  259. vup[2] = 1;
  260. break;
  261. case 2:
  262. vup[0] = 1;
  263. break;
  264. }
  265. v = DotProduct (vup, p->normal);
  266. VectorMA (vup, -v, p->normal, vup);
  267. VectorNormalize (vup);
  268. VectorScale (p->normal, p->dist, org);
  269. CrossProduct (vup, p->normal, vright);
  270. VectorScale (vup, 8192, vup);
  271. VectorScale (vright, 8192, vright);
  272. // project a really big axis aligned box onto the plane
  273. w = NewWinding (4);
  274. w->numpoints = 4;
  275. VectorSubtract (org, vright, w->points[0]);
  276. VectorAdd (w->points[0], vup, w->points[0]);
  277. VectorAdd (org, vright, w->points[1]);
  278. VectorAdd (w->points[1], vup, w->points[1]);
  279. VectorAdd (org, vright, w->points[2]);
  280. VectorSubtract (w->points[2], vup, w->points[2]);
  281. VectorSubtract (org, vright, w->points[3]);
  282. VectorSubtract (w->points[3], vup, w->points[3]);
  283. // set texture values
  284. f->light = TextureAxisFromPlane(&f->plane, xaxis, yaxis);
  285. td = &f->texture;
  286. // rotate axis
  287. ang = td->rotate / 180 * M_PI;
  288. sinv = sin(ang);
  289. cosv = cos(ang);
  290. if (!td->scale[0])
  291. td->scale[0] = 1;
  292. if (!td->scale[1])
  293. td->scale[1] = 1;
  294. for (i=0 ; i<4 ; i++)
  295. {
  296. s = DotProduct (w->points[i], xaxis);
  297. t = DotProduct (w->points[i], yaxis);
  298. ns = cosv * s - sinv * t;
  299. nt = sinv * s + cosv * t;
  300. w->points[i][3] = ns/td->scale[0] + td->shift[0];
  301. w->points[i][4] = nt/td->scale[1] + td->shift[1];
  302. }
  303. return w;
  304. }
  305. /*
  306. ===========
  307. calcWindings
  308. recalc the faces and mins / maxs from the planes
  309. If a face has a NULL winding, it is an overconstraining plane and
  310. can be removed.
  311. ===========
  312. */
  313. - calcWindings
  314. {
  315. int i,j, k;
  316. float v;
  317. face_t *f;
  318. winding_t *w;
  319. plane_t plane;
  320. vec3_t t1, t2, t3;
  321. BOOL useplane[MAX_FACES];
  322. bmins[0] = bmins[1] = bmins[2] = 99999;
  323. bmaxs[0] = bmaxs[1] = bmaxs[2] = -99999;
  324. invalid = NO;
  325. [self freeWindings];
  326. for (i=0 ; i<MAX_FACES ; i++)
  327. {
  328. f = &faces[i];
  329. // calc a plane from the points
  330. for (j=0 ; j<3 ; j++)
  331. {
  332. t1[j] = f->planepts[0][j] - f->planepts[1][j];
  333. t2[j] = f->planepts[2][j] - f->planepts[1][j];
  334. t3[j] = f->planepts[1][j];
  335. }
  336. CrossProduct(t1,t2, f->plane.normal);
  337. if (VectorCompare (f->plane.normal, vec3_origin))
  338. {
  339. useplane[i] = NO;
  340. break;
  341. }
  342. VectorNormalize (f->plane.normal);
  343. f->plane.dist = DotProduct (t3, f->plane.normal);
  344. // if the plane duplicates another plane, ignore it
  345. // (assume it is a brush being edited that will be fixed)
  346. useplane[i] = YES;
  347. for (j=0 ; j< i ; j++)
  348. {
  349. if ( f->plane.normal[0] == faces[j].plane.normal[0]
  350. && f->plane.normal[1] == faces[j].plane.normal[1]
  351. && f->plane.normal[2] == faces[j].plane.normal[2]
  352. && f->plane.dist == faces[j].plane.dist )
  353. {
  354. useplane[i] = NO;
  355. break;
  356. }
  357. }
  358. }
  359. for (i=0 ; i<numfaces ; i++)
  360. {
  361. if (!useplane[i])
  362. continue; // duplicate plane
  363. f = &faces[i];
  364. w = BasePolyForPlane (f);
  365. for (j=0 ; j<numfaces && w ; j++)
  366. {
  367. if (j == i)
  368. continue;
  369. // flip the plane, because we want to keep the back side
  370. VectorSubtract (vec3_origin, faces[j].plane.normal, plane.normal);
  371. plane.dist = -faces[j].plane.dist;
  372. w = ClipWinding (w, &plane);
  373. }
  374. f->w = w;
  375. if (w)
  376. {
  377. CheckFace (f);
  378. for (j=0 ; j<w->numpoints ; j++)
  379. {
  380. for (k=0 ; k<3 ; k++)
  381. {
  382. v = w->points[j][k];
  383. if (fabs(v - rint(v)) < FP_EPSILON)
  384. v = w->points[j][k] = rint(v);
  385. if (v < bmins[k])
  386. bmins[k] = v;
  387. if (v > bmaxs[k])
  388. bmaxs[k] = v;
  389. }
  390. }
  391. }
  392. }
  393. if (bmins[0] == 99999)
  394. {
  395. invalid = YES;
  396. VectorCopy (vec3_origin, bmins);
  397. VectorCopy (vec3_origin, bmaxs);
  398. return nil;
  399. }
  400. return self;
  401. }
  402. //============================================================================
  403. /*
  404. ===========
  405. initOwner:::
  406. ===========
  407. */
  408. - initOwner: own mins:(float *)mins maxs:(float *)maxs texture:(texturedef_t *)tex
  409. {
  410. [super init];
  411. parent = own;
  412. [self setTexturedef: tex];
  413. [self setMins: mins maxs: maxs];
  414. return self;
  415. }
  416. - setMins:(float *)mins maxs:(float *)maxs
  417. {
  418. int i, j;
  419. vec3_t pts[4][2];
  420. for (i=0 ; i<3 ; i++)
  421. {
  422. if (maxs[i] - mins[i] <= 0)
  423. {
  424. VectorCopy (mins, bmins);
  425. VectorCopy (maxs, bmaxs);
  426. invalid = YES;
  427. numfaces = 0;
  428. return self;
  429. }
  430. }
  431. pts[0][0][0] = mins[0];
  432. pts[0][0][1] = mins[1];
  433. pts[1][0][0] = mins[0];
  434. pts[1][0][1] = maxs[1];
  435. pts[2][0][0] = maxs[0];
  436. pts[2][0][1] = maxs[1];
  437. pts[3][0][0] = maxs[0];
  438. pts[3][0][1] = mins[1];
  439. for (i=0 ; i<4 ; i++)
  440. {
  441. pts[i][0][2] = mins[2];
  442. pts[i][1][0] = pts[i][0][0];
  443. pts[i][1][1] = pts[i][0][1];
  444. pts[i][1][2] = maxs[2];
  445. }
  446. numfaces = 6;
  447. for (i=0 ; i<4 ; i++)
  448. {
  449. j = (i+1)%4;
  450. faces[i].planepts[0][0] = pts[j][1][0];
  451. faces[i].planepts[0][1] = pts[j][1][1];
  452. faces[i].planepts[0][2] = pts[j][1][2];
  453. faces[i].planepts[1][0] = pts[i][1][0];
  454. faces[i].planepts[1][1] = pts[i][1][1];
  455. faces[i].planepts[1][2] = pts[i][1][2];
  456. faces[i].planepts[2][0] = pts[i][0][0];
  457. faces[i].planepts[2][1] = pts[i][0][1];
  458. faces[i].planepts[2][2] = pts[i][0][2];
  459. }
  460. faces[4].planepts[0][0] = pts[0][1][0];
  461. faces[4].planepts[0][1] = pts[0][1][1];
  462. faces[4].planepts[0][2] = pts[0][1][2];
  463. faces[4].planepts[1][0] = pts[1][1][0];
  464. faces[4].planepts[1][1] = pts[1][1][1];
  465. faces[4].planepts[1][2] = pts[1][1][2];
  466. faces[4].planepts[2][0] = pts[2][1][0];
  467. faces[4].planepts[2][1] = pts[2][1][1];
  468. faces[4].planepts[2][2] = pts[2][1][2];
  469. faces[5].planepts[0][0] = pts[2][0][0];
  470. faces[5].planepts[0][1] = pts[2][0][1];
  471. faces[5].planepts[0][2] = pts[2][0][2];
  472. faces[5].planepts[1][0] = pts[1][0][0];
  473. faces[5].planepts[1][1] = pts[1][0][1];
  474. faces[5].planepts[1][2] = pts[1][0][2];
  475. faces[5].planepts[2][0] = pts[0][0][0];
  476. faces[5].planepts[2][1] = pts[0][0][1];
  477. faces[5].planepts[2][2] = pts[0][0][2];
  478. [self calcWindings];
  479. return self;
  480. }
  481. - parent
  482. {
  483. return parent;
  484. }
  485. - setParent: (id)p
  486. {
  487. parent = p;
  488. return self;
  489. }
  490. - setEntityColor: (vec3_t)color
  491. {
  492. VectorCopy (color, entitycolor);
  493. return self;
  494. }
  495. - freeWindings
  496. {
  497. int i;
  498. for (i=0 ; i<MAX_FACES ; i++)
  499. if (faces[i].w)
  500. {
  501. free (faces[i].w);
  502. faces[i].w = NULL;
  503. }
  504. return self;
  505. }
  506. - copyFromZone:(NXZone *)zone
  507. {
  508. id new;
  509. [self freeWindings];
  510. new = [super copyFromZone: zone];
  511. [self calcWindings];
  512. [new calcWindings];
  513. return new;
  514. }
  515. - free
  516. {
  517. [self freeWindings];
  518. return [super free];
  519. }
  520. /*
  521. ===========
  522. initOwner: fromTokens
  523. ===========
  524. */
  525. int numsb;
  526. - initFromTokens: own
  527. {
  528. face_t *f;
  529. int i,j;
  530. [self init];
  531. parent = own;
  532. f = faces;
  533. numfaces = 0;
  534. do
  535. {
  536. if (!GetToken (true))
  537. break;
  538. if (!strcmp (token, "}") )
  539. break;
  540. for (i=0 ; i<3 ; i++)
  541. {
  542. if (i != 0)
  543. GetToken (true);
  544. if (strcmp (token, "(") )
  545. Error ("parsing map file");
  546. for (j=0 ; j<3 ; j++)
  547. {
  548. GetToken (false);
  549. f->planepts[i][j] = atoi(token);
  550. }
  551. GetToken (false);
  552. if (strcmp (token, ")") )
  553. Error ("parsing map file");
  554. }
  555. GetToken (false);
  556. strcpy (f->texture.texture, token);
  557. GetToken (false);
  558. f->texture.shift[0] = atof(token);
  559. GetToken (false);
  560. f->texture.shift[1] = atof(token);
  561. GetToken (false);
  562. f->texture.rotate = atof(token);
  563. GetToken (false);
  564. f->texture.scale[0] = atof(token);
  565. GetToken (false);
  566. f->texture.scale[1] = atof(token);
  567. #if 0
  568. flags = atoi(token);
  569. flags &= 7;
  570. f->texture.rotate = 0;
  571. f->texture.scale[0] = 1;
  572. f->texture.scale[1] = 1;
  573. #define TEX_FLIPAXIS 1
  574. #define TEX_FLIPS 2
  575. #define TEX_FLIPT 4
  576. if (flags & TEX_FLIPAXIS)
  577. {
  578. f->texture.rotate = 90;
  579. if ( !(flags & TEX_FLIPT) )
  580. f->texture.scale[0] = -1;
  581. if (flags & TEX_FLIPS)
  582. f->texture.scale[1] = -1;
  583. }
  584. else
  585. {
  586. if (flags & TEX_FLIPS)
  587. f->texture.scale[0] = -1;
  588. if (flags & TEX_FLIPT)
  589. f->texture.scale[1] = -1;
  590. }
  591. #endif
  592. f++;
  593. numfaces++;
  594. } while (1);
  595. numsb++;
  596. [self calcWindings];
  597. return self;
  598. }
  599. /*
  600. ===========
  601. writeToFILE
  602. ===========
  603. */
  604. - writeToFILE: (FILE *)f region: (BOOL)reg
  605. {
  606. int i,j;
  607. face_t *fa;
  608. texturedef_t *td;
  609. if (reg && regioned)
  610. return self;
  611. fprintf (f, "{\n");
  612. for (i=0 ; i<numfaces ; i++)
  613. {
  614. fa = &faces[i];
  615. for (j=0 ; j<3 ; j++)
  616. fprintf (f,"( %d %d %d ) ", (int)fa->planepts[j][0], (int)fa->planepts[j][1], (int)fa->planepts[j][2]);
  617. td = &fa->texture;
  618. fprintf (f,"%s %d %d %d %f %f\n", td->texture, (int)td->shift[0], (int)td->shift[1], (int)td->rotate, td->scale[0], td->scale[1]);
  619. }
  620. fprintf (f, "}\n");
  621. return self;
  622. }
  623. /*
  624. ==============================================================================
  625. INTERACTION
  626. ==============================================================================
  627. */
  628. - getMins: (vec3_t)mins maxs: (vec3_t)maxs
  629. {
  630. VectorCopy (bmins, mins);
  631. VectorCopy (bmaxs, maxs);
  632. return self;
  633. }
  634. - (BOOL)selected
  635. {
  636. return selected;
  637. }
  638. - setSelected: (BOOL)s
  639. {
  640. selected = s;
  641. return self;
  642. }
  643. - (BOOL)regioned
  644. {
  645. return regioned;
  646. }
  647. - setRegioned: (BOOL)s
  648. {
  649. regioned = s;
  650. return self;
  651. }
  652. /*
  653. ===========
  654. setTexturedef
  655. ===========
  656. */
  657. - setTexturedef: (texturedef_t *)tex
  658. {
  659. int i;
  660. for (i=0 ; i<MAX_FACES ; i++)
  661. {
  662. faces[i].texture = *tex;
  663. faces[i].qtexture = NULL; // recache next render
  664. }
  665. [self calcWindings]; // in case texture coords changed
  666. return self;
  667. }
  668. - setTexturedef: (texturedef_t *)tex forFace:(int)f
  669. {
  670. if ( (unsigned)f > numfaces)
  671. Error ("setTexturedef:forFace: bad face number %i",f);
  672. faces[f].texture = *tex;
  673. faces[f].qtexture = NULL; // recache next render
  674. [self calcWindings]; // in case texture coords changed
  675. return self;
  676. }
  677. /*
  678. ===========
  679. texturedef
  680. ===========
  681. */
  682. - (texturedef_t *)texturedef
  683. {
  684. return &faces[0].texture;
  685. }
  686. - (texturedef_t *)texturedefForFace: (int)f
  687. {
  688. return &faces[f].texture;
  689. }
  690. /*
  691. ===========
  692. removeIfInvalid
  693. So created veneers don't stay around
  694. ===========
  695. */
  696. - removeIfInvalid
  697. {
  698. int i, j;
  699. for (i=0 ; i<numfaces ; i++)
  700. {
  701. if (faces[i].w)
  702. continue;
  703. for (j=i+1 ; j<numfaces ; j++)
  704. faces[j-1] = faces[j];
  705. i--;
  706. numfaces--;
  707. }
  708. for ( ; i<MAX_FACES ; i++)
  709. faces[i].w = NULL;
  710. if (numfaces<4)
  711. {
  712. invalid = YES;
  713. [self remove];
  714. return nil;
  715. }
  716. return self;
  717. }
  718. /*
  719. ===========
  720. containsPoint
  721. ===========
  722. */
  723. - (BOOL)containsPoint: (vec3_t)pt
  724. {
  725. int i;
  726. for (i=0 ; i<numfaces ; i++)
  727. if (DotProduct (faces[i].plane.normal, pt) >= faces[i].plane.dist)
  728. return NO;
  729. return YES;
  730. }
  731. /*
  732. ===========
  733. clipRay
  734. ===========
  735. */
  736. - clipRay: (vec3_t)p1 : (vec3_t) p2
  737. :(vec3_t)frontpoint : (int *)f_face
  738. :(vec3_t)backpoint : (int *)b_face
  739. {
  740. int frontface, backface;
  741. int i, j;
  742. face_t *f;
  743. float d1, d2, m;
  744. float *start;
  745. start = p1;
  746. frontface = -2;
  747. backface = -2;
  748. f = faces;
  749. for (i=0 ; i<numfaces ; i++, f++)
  750. {
  751. if (!f->w)
  752. continue; // clipped off plane
  753. d1 = DotProduct (p1, f->plane.normal) - f->plane.dist;
  754. d2 = DotProduct (p2, f->plane.normal) - f->plane.dist;
  755. if (d1 >= 0 && d2 >= 0)
  756. { // the entire ray is in front of the polytope
  757. *f_face = -1;
  758. *b_face = -1;
  759. return self;
  760. }
  761. if (d1 > 0 && d2 < 0)
  762. { // new front plane
  763. frontface = i;
  764. m = d1 / (d1-d2);
  765. for (j=0 ; j<3 ; j++)
  766. frontpoint[j] = p1[j] + m*(p2[j]-p1[j]);
  767. p1 = frontpoint;
  768. }
  769. if (d1 < 0 && d2 > 0)
  770. { // new back plane
  771. backface = i;
  772. m = d1 / (d1-d2);
  773. for (j=0 ; j<3 ; j++)
  774. backpoint[j] = p1[j] + m*(p2[j]-p1[j]);
  775. p2 = backpoint;
  776. }
  777. }
  778. *f_face = frontface;
  779. *b_face = backface;
  780. return self;
  781. }
  782. /*
  783. ===========
  784. hitByRay
  785. ===========
  786. */
  787. - hitByRay: (vec3_t)p1 : (vec3_t) p2 : (float *)time : (int *)face
  788. {
  789. vec3_t frontpoint, backpoint, dir;
  790. int frontface, backface;
  791. if (regioned)
  792. {
  793. *time = -1;
  794. *face = -1;
  795. return self;
  796. }
  797. [self clipRay: p1 : p2 : frontpoint: &frontface : backpoint : &backface];
  798. if (frontface == -2 && backface == -2)
  799. { // entire ray is inside the brush, select first face
  800. *time = 0;
  801. *face = 0;
  802. return self;
  803. }
  804. if (frontface < 0)
  805. { // ray started inside the polytope, don't select it
  806. *time = -1;
  807. *face = -1;
  808. return self;
  809. }
  810. VectorSubtract (p2, p1, dir);
  811. VectorNormalize (dir);
  812. VectorSubtract (frontpoint, p1, frontpoint);
  813. *time = DotProduct (frontpoint, dir);
  814. if (*time < 0)
  815. Error ("hitByRay: negative t");
  816. *face = frontface;
  817. return self;
  818. }
  819. /*
  820. ==============================================================================
  821. DRAWING ROUTINES
  822. ==============================================================================
  823. */
  824. BOOL fakebrush;
  825. - drawConnections
  826. {
  827. id obj;
  828. int c, i;
  829. vec3_t dest, origin;
  830. vec3_t mid;
  831. vec3_t forward, right;
  832. char *targname;
  833. vec3_t min, max, temp;
  834. char targ[64];
  835. strcpy (targ, [parent valueForQKey: "target"]);
  836. if (!targ || !targ[0])
  837. return self;
  838. origin[0] = (bmins[0] + bmaxs[0]) /2;
  839. origin[1] = (bmins[1] + bmaxs[1]) /2;
  840. c = [map_i count];
  841. for (i=0 ; i<c ; i++)
  842. {
  843. obj = [map_i objectAt: i];
  844. targname = [obj valueForQKey: "targetname"];
  845. if (strcmp (targ, targname))
  846. continue;
  847. [[obj objectAt:0] getMins: min maxs: max];
  848. dest[0] = (min[0] + max[0]) /2;
  849. dest[1] = (min[1] + max[1]) /2;
  850. XYmoveto (origin);
  851. XYlineto (dest);
  852. forward[0] = dest[0] - origin[0];
  853. forward[1] = dest[1] - origin[1];
  854. forward[2] = 0;
  855. if (!forward[0] && !forward[1])
  856. continue;
  857. VectorNormalize (forward);
  858. forward[0] = 8*forward[0];
  859. forward[1] = 8*forward[1];
  860. right[0] = forward[1];
  861. right[1] = -forward[0];
  862. mid[0] = (dest[0] + origin[0])/2;
  863. mid[1] = (dest[1] + origin[1])/2;
  864. temp[0] = mid[0] + right[0] - forward[0];
  865. temp[1] = mid[1] + right[1] - forward[1];
  866. XYmoveto (temp);
  867. XYlineto (mid);
  868. temp[0] = mid[0] - right[0] - forward[0];
  869. temp[1] = mid[1] - right[1] - forward[1];
  870. XYlineto (temp);
  871. }
  872. return self;
  873. }
  874. - (BOOL)fakeBrush: (SEL)call
  875. {
  876. id copy;
  877. face_t face;
  878. if (!selected || fakebrush)
  879. return NO;
  880. if (![clipper_i getFace: &face])
  881. return NO;
  882. fakebrush = YES;
  883. copy = [self copy];
  884. copy = [copy addFace: &face];
  885. if (copy)
  886. {
  887. [copy perform:call];
  888. [copy free];
  889. }
  890. fakebrush = NO;
  891. return YES;
  892. }
  893. /*
  894. ===========
  895. XYDrawSelf
  896. ===========
  897. */
  898. - XYDrawSelf
  899. {
  900. int i, j;
  901. winding_t *w;
  902. vec3_t mid, end, s1, s2;
  903. char *val;
  904. float ang;
  905. id worldent, currentent;
  906. BOOL keybrush;
  907. if ([self fakeBrush: @selector(XYDrawSelf)])
  908. return self;
  909. [xyview_i addToScrollRange: bmins[0] : bmins[1]];
  910. [xyview_i addToScrollRange: bmaxs[0] : bmaxs[1]];
  911. worldent = [map_i objectAt: 0];
  912. currentent = [map_i currentEntity];
  913. if (parent != worldent && self == [parent objectAt: 0])
  914. keybrush = YES;
  915. else
  916. keybrush = NO;
  917. if (parent != worldent && worldent == currentent)
  918. linecolor (entitycolor[0], entitycolor[1], entitycolor[2]);
  919. else if (selected)
  920. linecolor (1,0,0); // selected
  921. else if (parent == currentent)
  922. linecolor (0,0,0); // unselected, but in same entity
  923. else
  924. linecolor (0,0.5,0); // other entity green
  925. if (keybrush)
  926. [self drawConnections]; // target line
  927. if (!selected &&
  928. ( bmaxs[0] < xy_draw_rect.origin.x
  929. || bmaxs[1] < xy_draw_rect.origin.y
  930. || bmins[0] > xy_draw_rect.origin.x + xy_draw_rect.size.width
  931. || bmins[1] > xy_draw_rect.origin.y + xy_draw_rect.size.height) )
  932. return self; // off view, don't bother
  933. for (i=0 ; i<numfaces ; i++)
  934. {
  935. w = faces[i].w;
  936. if (!w)
  937. continue;
  938. if (DotProduct (faces[i].plane.normal,xy_viewnormal) > -VECTOR_EPSILON)
  939. continue;
  940. XYmoveto (w->points[w->numpoints-1]);
  941. for (j=0 ; j<w->numpoints ; j++)
  942. XYlineto (w->points[j]);
  943. }
  944. if (keybrush)
  945. {
  946. // angle arrow
  947. val = [parent valueForQKey: "angle"];
  948. if (val && val[0])
  949. {
  950. ang = atof(val) * M_PI / 180;
  951. if (ang > 0) // negative values are up/down flags
  952. {
  953. mid[0] = (bmins[0]+bmaxs[0])/2;
  954. mid[1] = (bmins[1]+bmaxs[1])/2;
  955. end[0] = mid[0] + 16*cos(ang);
  956. end[1] = mid[1] + 16*sin(ang);
  957. s1[0] = mid[0] + 12*cos(ang+0.4);
  958. s1[1] = mid[1] + 12*sin(ang+0.4);
  959. s2[0] = mid[0] + 12*cos(ang-0.4);
  960. s2[1] = mid[1] + 12*sin(ang-0.4);
  961. XYmoveto ( mid);
  962. XYlineto ( end );
  963. XYmoveto ( s1);
  964. XYlineto ( end );
  965. XYlineto ( s2 );
  966. }
  967. }
  968. }
  969. return self;
  970. }
  971. /*
  972. ===========
  973. ZDrawSelf
  974. ===========
  975. */
  976. - ZDrawSelf
  977. {
  978. int i;
  979. vec3_t p1, p2;
  980. vec3_t frontpoint, backpoint;
  981. int frontface, backface;
  982. qtexture_t *q;
  983. if ([self fakeBrush: @selector(ZDrawSelf)])
  984. return self;
  985. [zview_i addToHeightRange: bmins[2]];
  986. [zview_i addToHeightRange: bmaxs[2]];
  987. if (selected)
  988. {
  989. PSmoveto (1, bmaxs[2]);
  990. PSlineto (23, bmaxs[2]);
  991. PSlineto (23, bmins[2]);
  992. PSlineto (1, bmins[2]);
  993. PSlineto (1, bmaxs[2]);
  994. PSsetrgbcolor (1,0,0);
  995. PSstroke ();
  996. }
  997. [zview_i getPoint: (NXPoint *)p1];
  998. for (i=0 ; i<2 ; i++)
  999. if (bmins[i] >= p1[i] || bmaxs[i] <= p1[i])
  1000. return self;
  1001. p1[2] = 4096;
  1002. p2[0] = p1[0];
  1003. p2[1] = p1[1];
  1004. p2[2] = -4096;
  1005. [self clipRay: p1 : p2 : frontpoint: &frontface : backpoint : &backface];
  1006. if (frontface == -1 || backface == -1)
  1007. return self;
  1008. q = TEX_ForName (faces[frontface].texture.texture);
  1009. PSmoveto (-8, frontpoint[2]);
  1010. PSlineto (8, frontpoint[2]);
  1011. PSlineto (8, backpoint[2]);
  1012. PSlineto (-8, backpoint[2]);
  1013. PSlineto (-8, frontpoint[2]);
  1014. PSsetrgbcolor (q->flatcolor.chan[0]/255.0
  1015. , q->flatcolor.chan[1]/255.0
  1016. , q->flatcolor.chan[2]/255.0);
  1017. PSfill ();
  1018. PSmoveto (-12, frontpoint[2]);
  1019. PSlineto (12, frontpoint[2]);
  1020. PSlineto (12, backpoint[2]);
  1021. PSlineto (-12, backpoint[2]);
  1022. PSlineto (-12, frontpoint[2]);
  1023. PSsetrgbcolor (0,0,0);
  1024. PSstroke ();
  1025. return self;
  1026. }
  1027. /*
  1028. ===========
  1029. CameraDrawSelf
  1030. ===========
  1031. */
  1032. - CameraDrawSelf
  1033. {
  1034. int i, j;
  1035. winding_t *w;
  1036. id worldent, currentent;
  1037. if ([self fakeBrush: @selector(CameraDrawSelf)])
  1038. return self;
  1039. worldent = [map_i objectAt: 0];
  1040. currentent = [map_i currentEntity];
  1041. if (parent != worldent && worldent == currentent)
  1042. linecolor (entitycolor[0], entitycolor[1], entitycolor[2]);
  1043. else if (selected)
  1044. linecolor (1,0,0);
  1045. else if (parent == [map_i currentEntity])
  1046. linecolor (0,0,0);
  1047. else
  1048. linecolor (0,0.5,0);
  1049. for (i=0 ; i<numfaces ; i++)
  1050. {
  1051. w = faces[i].w;
  1052. if (!w)
  1053. continue;
  1054. CameraMoveto (w->points[w->numpoints-1]);
  1055. for (j=0 ; j<w->numpoints ; j++)
  1056. CameraLineto (w->points[j]);
  1057. }
  1058. return self;
  1059. }
  1060. /*
  1061. ===========
  1062. XYRenderSelf
  1063. ===========
  1064. */
  1065. - XYRenderSelf
  1066. {
  1067. int i;
  1068. if ([self fakeBrush: @selector(XYRenderSelf)])
  1069. return self;
  1070. for (i=0 ; i<numfaces ; i++)
  1071. REN_DrawXYFace (&faces[i]);
  1072. return self;
  1073. }
  1074. /*
  1075. ===========
  1076. CameraRenderSelf
  1077. ===========
  1078. */
  1079. - CameraRenderSelf
  1080. {
  1081. int i;
  1082. BOOL olddraw;
  1083. extern qtexture_t badtex;
  1084. pixel32_t p;
  1085. if ([self fakeBrush: @selector(CameraRenderSelf)])
  1086. return self;
  1087. // hack to draw entity boxes as single flat color
  1088. if ( ![parent modifiable] )
  1089. {
  1090. olddraw = r_drawflat;
  1091. r_drawflat = YES;
  1092. p = badtex.flatcolor;
  1093. badtex.flatcolor.chan[0] = entitycolor[0]*255;
  1094. badtex.flatcolor.chan[1] = entitycolor[1]*255;
  1095. badtex.flatcolor.chan[2] = entitycolor[2]*255;
  1096. for (i=0 ; i<numfaces ; i++)
  1097. REN_DrawCameraFace (&faces[i]);
  1098. badtex.flatcolor = p;
  1099. r_drawflat = olddraw;
  1100. }
  1101. else
  1102. {
  1103. for (i=0 ; i<numfaces ; i++)
  1104. REN_DrawCameraFace (&faces[i]);
  1105. }
  1106. return self;
  1107. }
  1108. /*
  1109. ==============================================================================
  1110. SINGLE BRUSH ACTIONS
  1111. ==============================================================================
  1112. */
  1113. face_t *dragface, *dragface2;
  1114. int numcontrolpoints;
  1115. float *controlpoints[MAX_FACES*3];
  1116. - (BOOL)checkModifiable
  1117. {
  1118. // int i;
  1119. if ( [parent modifiable] )
  1120. return YES;
  1121. // don't stretch spawned entities, move all points
  1122. #if 0
  1123. numcontrolpoints = numfaces*3;
  1124. for (i=0 ; i<numcontrolpoints ; i++)
  1125. controlpoints[i] = faces[i/3].planepts[i%3];
  1126. #endif
  1127. return NO;
  1128. }
  1129. - getZdragface: (vec3_t)dragpoint
  1130. {
  1131. int i, j;
  1132. float d;
  1133. if (![self checkModifiable])
  1134. return self;
  1135. numcontrolpoints = 0;
  1136. for (i=0 ; i<numfaces ; i++)
  1137. {
  1138. if (!faces[i].w)
  1139. continue;
  1140. if (faces[i].plane.normal[2] == 1)
  1141. d = dragpoint[2] - faces[i].plane.dist;
  1142. else if (faces[i].plane.normal[2] == -1)
  1143. d = -faces[i].plane.dist - dragpoint[2];
  1144. else
  1145. continue;
  1146. if (d <= 0)
  1147. continue;
  1148. for (j=0 ; j<3 ; j++)
  1149. {
  1150. controlpoints[numcontrolpoints] = faces[i].planepts[j];
  1151. numcontrolpoints++;
  1152. }
  1153. }
  1154. return self;
  1155. }
  1156. - getXYdragface: (vec3_t)dragpoint
  1157. {
  1158. int i,j;
  1159. float d;
  1160. numcontrolpoints = 0;
  1161. if (![self checkModifiable])
  1162. return self;
  1163. for (i=0 ; i<numfaces ; i++)
  1164. {
  1165. if (!faces[i].w)
  1166. continue;
  1167. if (faces[i].plane.normal[2])
  1168. continue;
  1169. d = DotProduct(faces[i].plane.normal, dragpoint) - faces[i].plane.dist;
  1170. if (d <= 0)
  1171. continue;
  1172. for (j=0 ; j<3 ; j++)
  1173. {
  1174. controlpoints[numcontrolpoints] = faces[i].planepts[j];
  1175. numcontrolpoints++;
  1176. }
  1177. }
  1178. return self;
  1179. }
  1180. - getXYShearPoints: (vec3_t)dragpoint
  1181. {
  1182. int i,j, k;
  1183. int facectl;
  1184. float d;
  1185. int numdragplanes;
  1186. BOOL dragplane[MAX_FACES];
  1187. winding_t *w;
  1188. face_t *f;
  1189. BOOL onplane[MAX_POINTS_ON_WINDING];
  1190. if (![self checkModifiable])
  1191. return self;
  1192. numcontrolpoints = 0;
  1193. numdragplanes = 0;
  1194. for (i=0 ; i<numfaces ; i++)
  1195. {
  1196. dragplane[i] = NO;
  1197. if (!faces[i].w)
  1198. continue;
  1199. // if (faces[i].plane.normal[2])
  1200. // continue;
  1201. d = DotProduct(faces[i].plane.normal, dragpoint) - faces[i].plane.dist;
  1202. if (d <= -ON_EPSILON)
  1203. continue;
  1204. dragplane[i] = YES;
  1205. numdragplanes++;
  1206. }
  1207. // find faces that just share an edge with a drag plane
  1208. for (i=0 ; i<numfaces ; i++)
  1209. {
  1210. f = &faces[i];
  1211. w = f->w;
  1212. if (!w)
  1213. continue;
  1214. if (dragplane[i] && numdragplanes == 1)
  1215. {
  1216. for (j=0 ; j<3 ; j++)
  1217. {
  1218. controlpoints[numcontrolpoints] = faces[i].planepts[j];
  1219. numcontrolpoints++;
  1220. }
  1221. continue;
  1222. }
  1223. if (!dragplane[i] && numdragplanes > 1)
  1224. continue;
  1225. facectl = 0;
  1226. for (j=0 ; j<w->numpoints ; j++)
  1227. {
  1228. onplane[j] = NO;
  1229. for (k=0 ; k<numfaces ; k++)
  1230. {
  1231. if (!dragplane[k])
  1232. continue;
  1233. if (k == i)
  1234. continue;
  1235. d = DotProduct (w->points[j], faces[k].plane.normal)
  1236. - faces[k].plane.dist;
  1237. if (fabs(d) > ON_EPSILON)
  1238. continue;
  1239. onplane[j] = YES;
  1240. facectl++;
  1241. break;
  1242. }
  1243. }
  1244. if (facectl == 0)
  1245. continue;
  1246. // find one or two static points to go with the controlpoints
  1247. // and change the plane points
  1248. k = 0;
  1249. for (j=0 ; j<w->numpoints ; j++)
  1250. {
  1251. if (!onplane[j])
  1252. continue;
  1253. if (facectl >= 2 && !onplane[(j+1)%w->numpoints])
  1254. continue;
  1255. if (facectl == 3 && !onplane[(j+2)%w->numpoints])
  1256. continue;
  1257. VectorCopy (w->points[j], f->planepts[k]);
  1258. controlpoints[numcontrolpoints] = f->planepts[k];
  1259. numcontrolpoints++;
  1260. k++;
  1261. if (facectl >= 2)
  1262. {
  1263. VectorCopy (w->points[(j+1)%w->numpoints], f->planepts[k]);
  1264. controlpoints[numcontrolpoints] = f->planepts[k];
  1265. numcontrolpoints++;
  1266. k++;
  1267. }
  1268. if (facectl == 3)
  1269. {
  1270. VectorCopy (w->points[(j+2)%w->numpoints], f->planepts[k]);
  1271. controlpoints[numcontrolpoints] = f->planepts[k];
  1272. numcontrolpoints++;
  1273. k++;
  1274. }
  1275. break;
  1276. }
  1277. for ( ; j<w->numpoints && k != 3 ; j++)
  1278. if (!onplane[j])
  1279. {
  1280. VectorCopy (w->points[j], f->planepts[k]);
  1281. k++;
  1282. }
  1283. for (j=0 ; j<w->numpoints && k != 3 ; j++)
  1284. if (!onplane[j])
  1285. {
  1286. VectorCopy (w->points[j], f->planepts[k]);
  1287. k++;
  1288. }
  1289. if (k != 3)
  1290. {
  1291. // Error ("getXYShearPoints: didn't get three points on plane");
  1292. numcontrolpoints = 0;
  1293. return self;
  1294. }
  1295. for (j=0 ; j<3 ; j++)
  1296. for (k=0 ; k<3 ; k++)
  1297. f->planepts[j][k] = rint(f->planepts[j][k]);
  1298. }
  1299. return self;
  1300. }
  1301. /*
  1302. ==============================================================================
  1303. MULTIPLE BRUSH ACTIONS
  1304. ==============================================================================
  1305. */
  1306. vec3_t region_min, region_max;
  1307. /*
  1308. ===========
  1309. newRegion
  1310. Set the regioned flag based on if the object is containted in region_min/max
  1311. ===========
  1312. */
  1313. - newRegion
  1314. {
  1315. int i;
  1316. char *name;
  1317. // filter away entities
  1318. if (parent != [map_i objectAt: 0])
  1319. {
  1320. if (filter_entities)
  1321. {
  1322. regioned = YES;
  1323. return self;
  1324. }
  1325. name = [parent valueForQKey: "classname"];
  1326. if ( (filter_light && !strncmp(name,"light",5) )
  1327. || (filter_path && !strncmp(name,"path",4) ) )
  1328. {
  1329. regioned = YES;
  1330. return self;
  1331. }
  1332. }
  1333. else if (filter_world)
  1334. {
  1335. regioned = YES;
  1336. return self;
  1337. }
  1338. if (filter_clip_brushes && !strcasecmp(faces[0].texture.texture, "clip"))
  1339. {
  1340. regioned = YES;
  1341. return self;
  1342. }
  1343. if (filter_water_brushes && faces[0].texture.texture[0] == '*')
  1344. {
  1345. regioned = YES;
  1346. return self;
  1347. }
  1348. for (i=0 ; i<3 ; i++)
  1349. {
  1350. if (region_min[i] >= bmaxs[i] || region_max[i] <= bmins[i])
  1351. {
  1352. if (selected)
  1353. [self deselect];
  1354. regioned = YES;
  1355. return self;
  1356. }
  1357. }
  1358. regioned = NO;
  1359. return self;
  1360. }
  1361. vec3_t select_min, select_max;
  1362. - selectPartial
  1363. {
  1364. int i;
  1365. for (i=0 ; i<3 ; i++)
  1366. if (select_min[i] >= bmaxs[i] || select_max[i] <= bmins[i])
  1367. return self;
  1368. selected = YES;
  1369. return self;
  1370. }
  1371. - selectComplete
  1372. {
  1373. int i;
  1374. for (i=0 ; i<3 ; i++)
  1375. if (select_min[i] > bmins[i] || select_max[i] < bmaxs[i])
  1376. return self;
  1377. selected = YES;
  1378. return self;
  1379. }
  1380. - regionPartial
  1381. {
  1382. int i;
  1383. for (i=0 ; i<3 ; i++)
  1384. if (select_min[i] >= bmaxs[i] || select_max[i] <= bmins[i])
  1385. return self;
  1386. selected = YES;
  1387. return self;
  1388. }
  1389. - regionComplete
  1390. {
  1391. int i;
  1392. for (i=0 ; i<3 ; i++)
  1393. if (select_min[i] > bmins[i] || select_max[i] < bmaxs[i])
  1394. return self;
  1395. selected = YES;
  1396. return self;
  1397. }
  1398. id sb_newowner;
  1399. - moveToEntity
  1400. {
  1401. id eclass;
  1402. float *c;
  1403. [parent removeObject: self];
  1404. parent = sb_newowner;
  1405. // hack to allow them to be copied to another map
  1406. if ( [parent respondsTo:@selector(valueForQKey:)])
  1407. {
  1408. eclass = [entity_classes_i classForName: [parent valueForQKey: "classname"]];
  1409. c = [eclass drawColor];
  1410. [self setEntityColor: c];
  1411. }
  1412. [parent addObject: self];
  1413. return self;
  1414. }
  1415. vec3_t sb_translate;
  1416. - translate
  1417. {
  1418. int i, j;
  1419. // move the planes
  1420. for (i=0; i<numfaces ; i++)
  1421. for (j=0 ; j<3 ; j++)
  1422. {
  1423. VectorAdd (faces[i].planepts[j], sb_translate, faces[i].planepts[j]);
  1424. }
  1425. [self calcWindings];
  1426. return self;
  1427. }
  1428. vec3_t sb_mins, sb_maxs;
  1429. - addToBBox
  1430. {
  1431. int k;
  1432. if (numfaces < 4)
  1433. return self;
  1434. for (k=0 ; k<3 ; k++)
  1435. {
  1436. if (bmins[k] < sb_mins[k])
  1437. sb_mins[k] = bmins[k];
  1438. if (bmaxs[k] > sb_maxs[k])
  1439. sb_maxs[k] = bmaxs[k];
  1440. }
  1441. return self;
  1442. }
  1443. - flushTextures
  1444. { // call when texture palette changes
  1445. int i;
  1446. for (i=0 ; i<MAX_FACES ; i++)
  1447. faces[i].qtexture = NULL;
  1448. [self calcWindings];
  1449. return self;
  1450. }
  1451. - select
  1452. {
  1453. [map_i setCurrentEntity: parent];
  1454. selected = YES;
  1455. return self;
  1456. }
  1457. - deselect
  1458. {
  1459. selected = NO;
  1460. // the last selected brush determines
  1461. if (invalid)
  1462. printf ("WARNING: deselected invalid brush\n");
  1463. [map_i setCurrentMinZ: bmins[2]];
  1464. [map_i setCurrentMaxZ: bmaxs[2]];
  1465. return self;
  1466. }
  1467. - remove
  1468. {
  1469. // the last selected brush determines
  1470. if (!invalid)
  1471. {
  1472. [map_i setCurrentMinZ: bmins[2]];
  1473. [map_i setCurrentMaxZ: bmaxs[2]];
  1474. }
  1475. [parent removeObject: self];
  1476. [self free];
  1477. return nil;
  1478. }
  1479. vec3_t sel_x, sel_y, sel_z;
  1480. vec3_t sel_org;
  1481. - transform
  1482. {
  1483. int i,j;
  1484. vec3_t old;
  1485. float *p;
  1486. for (i=0 ; i<numfaces ; i++)
  1487. for (j=0 ; j<3 ; j++)
  1488. {
  1489. p = faces[i].planepts[j];
  1490. VectorCopy (p, old);
  1491. VectorSubtract (old, sel_org, old);
  1492. p[0] = DotProduct (old, sel_x);
  1493. p[1] = DotProduct (old, sel_y);
  1494. p[2] = DotProduct (old, sel_z);
  1495. VectorAdd (p, sel_org, p);
  1496. }
  1497. [self calcWindings];
  1498. return self;
  1499. }
  1500. - flipNormals // used after an inside-out transform (flip x/y/z)
  1501. {
  1502. int i;
  1503. vec3_t temp;
  1504. for (i=0 ; i<numfaces ; i++)
  1505. {
  1506. VectorCopy (faces[i].planepts[0], temp);
  1507. VectorCopy (faces[i].planepts[2], faces[i].planepts[0]);
  1508. VectorCopy (temp, faces[i].planepts[2]);
  1509. }
  1510. [self calcWindings];
  1511. return self;
  1512. }
  1513. - carveByClipper
  1514. {
  1515. face_t face;
  1516. if (![clipper_i getFace: &face])
  1517. return self;
  1518. [self addFace: &face];
  1519. return self;
  1520. }
  1521. - takeCurrentTexture
  1522. {
  1523. texturedef_t td;
  1524. [texturepalette_i getTextureDef: &td];
  1525. [self setTexturedef: &td];
  1526. return self;
  1527. }
  1528. float sb_floor_dir, sb_floor_dist;
  1529. - feetToFloor
  1530. {
  1531. float oldz;
  1532. vec3_t p1, p2;
  1533. int frontface, backface;
  1534. vec3_t frontpoint, backpoint;
  1535. float dist;
  1536. [cameraview_i getOrigin: p1];
  1537. VectorCopy (p1, p2);
  1538. oldz = p1[2] - 48;
  1539. p1[2] = 4096;
  1540. p2[2] = -4096;
  1541. [self clipRay: p1 : p2 : frontpoint : &frontface : backpoint : &backface];
  1542. if (frontface == -1)
  1543. return self;
  1544. dist = frontpoint[2] - oldz;
  1545. if (sb_floor_dir == 1)
  1546. {
  1547. if (dist > 0 && dist < sb_floor_dist)
  1548. sb_floor_dist = dist;
  1549. }
  1550. else
  1551. {
  1552. if (dist < 0 && dist > sb_floor_dist)
  1553. sb_floor_dist = dist;
  1554. }
  1555. return self;
  1556. }
  1557. /*
  1558. ===============================================================================
  1559. BRUSH SUBTRACTION
  1560. ===============================================================================
  1561. */
  1562. vec3_t carvemin, carvemax;
  1563. int numcarvefaces;
  1564. face_t *carvefaces;
  1565. id carve_in, carve_out;
  1566. // returns the new brush formed after the addition of the given plane
  1567. // nil is returned if it faced all of the original setbrush
  1568. - addFace: (face_t *)f
  1569. {
  1570. if (numfaces == MAX_FACES)
  1571. Error ("addFace: numfaces == MAX_FACES");
  1572. faces[numfaces] = *f;
  1573. faces[numfaces].texture = faces[0].texture;
  1574. faces[numfaces].qtexture = NULL;
  1575. faces[numfaces].w = NULL;
  1576. numfaces++;
  1577. [self calcWindings];
  1578. // remove any degenerate faces
  1579. return [self removeIfInvalid];
  1580. }
  1581. - clipByFace: (face_t *)fa front:(id *)f back:(id *)b
  1582. {
  1583. id front, back;
  1584. face_t fb;
  1585. vec3_t temp;
  1586. fb = *fa;
  1587. VectorCopy (fb.planepts[0], temp);
  1588. VectorCopy (fb.planepts[2], fb.planepts[0]);
  1589. VectorCopy (temp, fb.planepts[2]);
  1590. front = [self copy];
  1591. back = [self copy];
  1592. *b = [back addFace: fa];
  1593. *f = [front addFace: &fb];
  1594. return self;
  1595. }
  1596. - carve
  1597. {
  1598. int i;
  1599. id front, back;
  1600. #if 0
  1601. if ( (i = NXMallocCheck()) )
  1602. Error ("MallocCheck failure");
  1603. #endif
  1604. // check bboxes
  1605. for (i=0 ; i<3 ; i++)
  1606. if (bmins[i] >= carvemax[i] || bmaxs[i] <= carvemin[i])
  1607. {
  1608. [carve_out addObject: self];
  1609. return self;
  1610. }
  1611. // carve by the planes
  1612. back = self;
  1613. for (i=0 ; i<numcarvefaces ; i++)
  1614. {
  1615. [back clipByFace: &carvefaces[i] front:&front back:&back];
  1616. if (front)
  1617. [carve_out addObject: front];
  1618. if (!back)
  1619. return nil; // nothing completely inside
  1620. }
  1621. [carve_in addObject: back];
  1622. return self;
  1623. }
  1624. /*
  1625. ==================
  1626. setCarveVars
  1627. ==================
  1628. */
  1629. - setCarveVars
  1630. {
  1631. VectorCopy (bmins, carvemin);
  1632. VectorCopy (bmaxs, carvemax);
  1633. numcarvefaces = numfaces;
  1634. carvefaces = faces;
  1635. return self;
  1636. }
  1637. - (int) getNumBrushFaces
  1638. {
  1639. return numfaces;
  1640. }
  1641. - (face_t *) getBrushFace: (int)which
  1642. {
  1643. return &faces[which];
  1644. }
  1645. @end