]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/DShape.cpp
misc nix
[xonotic/netradiant.git] / contrib / bobtoolz / DShape.cpp
1 /*
2 BobToolz plugin for GtkRadiant
3 Copyright (C) 2001 Gordon Biggans
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 // DShape.cpp: implementation of the DShape class.
21 //
22 //////////////////////////////////////////////////////////////////////
23
24 #include "StdAfx.h"
25 #include "DShape.h"
26
27 //#include "dialogs-gtk.h"
28
29 #include "misc.h"
30 #include "shapes.h"
31
32 //////////////////////////////////////////////////////////////////////
33 // Construction/Destruction
34 //////////////////////////////////////////////////////////////////////
35
36 bool bFacesAll[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
37
38 DShape::DShape()
39 {
40         m_nNextBrush = 0;
41 }
42
43 DShape::~DShape()
44 {
45
46 }
47
48 void DShape::BuildRegularPrism(vec3_t min, vec3_t max, int nSides, bool bAlignTop)
49 {
50         vec3_t vc[MAX_POLYGON_FACES+2], vd[MAX_POLYGON_FACES+2];
51
52         vec3_t radius;
53         vec3_t origin;
54
55         VectorSubtract(max, min, radius);
56         VectorScale(radius, 0.5f, radius);
57         // calc 3d radius and origin
58         VectorAdd(max, min, origin);
59         VectorScale(origin, 0.5f, origin);
60
61         float phase = 0.0f;
62
63         if(bAlignTop)
64         {
65                 phase = -(Q_PI/nSides);
66                 VectorScale(radius, static_cast< float >( 1/cos(phase) ), radius);
67         }
68
69         //----- Build Polygon Vertices -----
70
71         int i;
72         for(i = 0; i < nSides; i++)
73         {
74                 VectorCopy(origin, vc[i]);
75                 VectorCopy(origin, vd[i]);
76                 
77                 vc[i][2] = min[2];
78                 vd[i][2] = max[2];
79
80                 vc[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
81                 vc[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
82
83                 vd[i][0] = vc[i][0];
84                 vd[i][1] = vc[i][1];
85         }
86
87         VectorCopy(vc[0], vc[nSides]);
88         VectorCopy(vd[0], vd[nSides]);
89         VectorCopy(vc[1], vc[nSides+1]);
90         VectorCopy(vd[1], vd[nSides+1]);
91         
92         //----------------------------------
93
94         DBrush* pB = m_Container.GetWorldSpawn()->NewBrush(m_nNextBrush++);
95
96         for(i = 1; i <= nSides; i++)
97                 pB->AddFace(vc[i-1], vc[i], vd[i], GetCurrentTexture(), FALSE);
98
99         pB->AddFace(vc[2], vc[1], vc[0], "textures/common/caulk", FALSE);
100         pB->AddFace(vd[0], vd[1], vd[2], "textures/common/caulk", FALSE);
101 }
102
103 void DShape::Commit()
104 {
105         m_Container.GetWorldSpawn()->FixBrushes(FALSE);
106         m_Container.BuildInRadiant(TRUE);
107 }
108
109 void DShape::BuildInversePrism(vec3_t min, vec3_t max, int nSides, bool bAlignTop)
110 {
111         vec3_t va[MAX_POLYGON_FACES+1], vb[MAX_POLYGON_FACES+1];
112         vec3_t radius;
113         vec3_t origin;
114
115         VectorSubtract(max, min, radius);
116         VectorScale(radius, 0.5f, radius);
117         // calc 3d radius and origin
118         VectorAdd(max, min, origin);
119         VectorScale(origin, 0.5f, origin);
120
121         float phase = 0.0f;
122
123         if(bAlignTop)
124         {
125                 phase = -(Q_PI/nSides);
126                 VectorScale(radius, static_cast< float >( 1/cos(phase) ), radius);
127         }
128
129         //----- Build Polygon Vertices -----
130
131         int i;
132         for(i = 0; i < nSides; i++)
133         {
134                 VectorCopy(origin, va[i]);
135                 VectorCopy(origin, vb[i]);
136
137                 va[i][2] = min[2];
138                 vb[i][2] = max[2];
139
140                 va[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
141                 va[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
142
143                 vb[i][0] = va[i][0];
144                 vb[i][1] = va[i][1];
145         }
146
147         VectorCopy(va[0], va[nSides]);
148         VectorCopy(vb[0], vb[nSides]);
149         
150         //----------------------------------
151
152         for(i = 1; i <= nSides; i++)
153         {
154                 DBrush* pB = GetBoundingCube(min, max, "textures/common/caulk");
155
156                 vec3_t top, bottom;
157                 VectorCopy(va[i-1], top);
158                 VectorCopy(va[i], bottom);
159
160                 if(va[i-1][1] > va[i][1])
161                 {
162                         top[0] += 5;
163                         bottom[0] += 5;
164                 }
165                 else    // flip direction of plane on crossover
166                 {
167                         top[0] -= 5;
168                         bottom[0] -= 5;
169                 }
170                 
171                 if(top[1] != bottom[1]) // internal line is flat already if true
172                 {                       
173                         pB->AddFace(va[i-1], top, vb[i-1], "textures/common/caulk", FALSE);
174                         pB->AddFace(va[i], vb[i], bottom, "textures/common/caulk", FALSE);
175                 }       // add cut-off planes
176
177                 pB->AddFace(va[i-1], vb[i-1], vb[i], GetCurrentTexture(), FALSE);
178                 // add internal polygon plane
179         }
180 }
181
182 void DShape::BuildBorderedPrism(vec3_t min, vec3_t max, int nSides, int nBorder, bool bAlignTop)
183 {
184         vec3_t va[MAX_POLYGON_FACES+2], vb[MAX_POLYGON_FACES+2];
185         vec3_t vc[MAX_POLYGON_FACES+2], vd[MAX_POLYGON_FACES+2];
186
187         vec3_t radius;
188         vec3_t origin;
189
190         VectorSubtract(max, min, radius);
191         VectorScale(radius, 0.5f, radius);
192         // calc 3d radius and origin
193         VectorAdd(max, min, origin);
194         VectorScale(origin, 0.5f, origin);
195
196         if(nBorder >= Min(radius[0], radius[1]))
197         {
198 //              DoMessageBox("Border is too large", "Error", MB_OK);
199                 return;
200         }
201
202         float phase = 0.0f;
203
204         if(bAlignTop)
205         {
206                 phase = -(Q_PI/nSides);
207                 VectorScale(radius, static_cast< float >( 1/cos(phase) ), radius);
208         }
209
210         //----- Build Polygon Vertices -----
211
212         int i;
213         for(i = 0; i < nSides; i++)
214         {
215                 VectorCopy(origin, va[i]);
216                 VectorCopy(origin, vb[i]);
217                 VectorCopy(origin, vc[i]);
218                 VectorCopy(origin, vd[i]);
219
220                 va[i][2] = min[2];
221                 vb[i][2] = max[2];
222
223                 va[i][0] += (radius[0] - nBorder) * sinf( ( 2 * Q_PI * i / nSides ) + phase );
224                 va[i][1] += (radius[1] - nBorder) * cosf( ( 2 * Q_PI * i / nSides ) + phase );
225
226                 vb[i][0] = va[i][0];
227                 vb[i][1] = va[i][1];
228
229
230                 
231                 vc[i][2] = min[2];
232                 vd[i][2] = max[2];
233
234                 vc[i][0] += radius[0] * sinf( ( 2 * Q_PI * i / nSides ) + phase );
235                 vc[i][1] += radius[1] * cosf( ( 2 * Q_PI * i / nSides ) + phase );
236
237                 vd[i][0] = vc[i][0];
238                 vd[i][1] = vc[i][1];
239         }
240
241         VectorCopy(va[0], va[nSides]);
242         VectorCopy(vb[0], vb[nSides]);
243         VectorCopy(va[1], va[nSides+1]);
244         VectorCopy(vb[1], vb[nSides+1]);
245
246         VectorCopy(vc[0], vc[nSides]);
247         VectorCopy(vd[0], vd[nSides]);
248         VectorCopy(vc[1], vc[nSides+1]);
249         VectorCopy(vd[1], vd[nSides+1]);
250         
251         //----------------------------------
252
253         for(i = 1; i <= nSides; i++)
254         {
255                 DBrush* pB = GetBoundingCube(min, max, "textures/common/caulk");
256
257                 pB->AddFace(origin, vc[i-1], vd[i-1], "textures/common/caulk", FALSE);
258                 pB->AddFace(origin, vd[i], vc[i], "textures/common/caulk", FALSE); 
259
260                 pB->AddFace(vc[i-1], vc[i], vd[i], GetCurrentTexture(), FALSE);
261                 pB->AddFace(vb[i], va[i], va[i-1], GetCurrentTexture(), FALSE);
262         }
263 }
264
265 DBrush* DShape::GetBoundingCube_Ext(vec3_t min, vec3_t max, const char *textureName, bool* bUseFaces, bool detail)
266 {
267         DBrush* pB = new DBrush;
268         //----- Build Outer Bounds ---------
269
270         vec3_t v1, v2, v3, v5, v6, v7;
271         VectorCopy(min, v1);
272         VectorCopy(min, v2);
273         VectorCopy(min, v3);
274         VectorCopy(max, v5);
275         VectorCopy(max, v6);
276         VectorCopy(max, v7);
277
278         v2[0] = max[0];
279         v3[1] = max[1];
280
281         v6[0] = min[0];
282         v7[1] = min[1];
283
284         //----------------------------------
285
286         //----- Add Six Cube Faces ---------
287
288         if(bUseFaces[0])
289                 pB->AddFace(v1, v2, v3, textureName, detail);
290         if(bUseFaces[1])
291                 pB->AddFace(v1, v3, v6, textureName, detail);
292         if(bUseFaces[2])
293                 pB->AddFace(v1, v7, v2, textureName, detail);
294
295         if(bUseFaces[3])
296                 pB->AddFace(v5, v6, v3, textureName, detail);
297         if(bUseFaces[4])
298                 pB->AddFace(v5, v2, v7, textureName, detail);
299         if(bUseFaces[5])
300                 pB->AddFace(v5, v7, v6, textureName, detail);
301
302         //----------------------------------
303
304         return pB;
305 }
306
307 DBrush* DShape::GetBoundingCube(vec3_t min, vec3_t max, const char *textureName, DEntity* ent, bool* bUseFaces)
308 {
309         DBrush* pB;
310         if(ent == NULL)
311                 pB = m_Container.GetWorldSpawn()->NewBrush(m_nNextBrush++);
312         else
313                 pB = ent->NewBrush(m_nNextBrush++);
314
315         //----- Build Outer Bounds ---------
316
317         vec3_t v1, v2, v3, v5, v6, v7;
318         VectorCopy(min, v1);
319         VectorCopy(min, v2);
320         VectorCopy(min, v3);
321         VectorCopy(max, v5);
322         VectorCopy(max, v6);
323         VectorCopy(max, v7);
324
325         v2[0] = max[0];
326         v3[1] = max[1];
327
328         v6[0] = min[0];
329         v7[1] = min[1];
330
331         //----------------------------------
332
333         //----- Add Six Cube Faces ---------
334
335         if(bUseFaces[0])
336                 pB->AddFace(v1, v2, v3, textureName, FALSE);
337         if(bUseFaces[1])
338                 pB->AddFace(v1, v3, v6, textureName, FALSE);
339         if(bUseFaces[2])
340                 pB->AddFace(v1, v7, v2, textureName, FALSE);
341
342         if(bUseFaces[3])
343                 pB->AddFace(v5, v6, v3, textureName, FALSE);
344         if(bUseFaces[4])
345                 pB->AddFace(v5, v2, v7, textureName, FALSE);
346         if(bUseFaces[5])
347                 pB->AddFace(v5, v7, v6, textureName, FALSE);
348
349         //----------------------------------
350
351         return pB;
352 }
353
354 bool DShape::BuildPit(vec3_t min, vec3_t max)
355 {
356         if((max[2] - min[2]) < 196)
357                 return FALSE;
358
359         srand(time(NULL));
360
361         vec3_t centre;
362         VectorAdd(min, max, centre);
363         VectorScale(centre, 0.5f, centre);
364
365         char buffer[256];
366
367         int team = (rand()%10000)+5000;
368
369 // ************* SPEAKER ***************
370         sprintf(buffer, "t%i_1", team);
371
372 // trigger for speaker
373         vec3_t triggerVoiceBtm;
374         VectorCopy(min, triggerVoiceBtm);
375         triggerVoiceBtm[2] = max[2] - 16;
376
377         DEntity* triggerVoice = m_Container.AddEntity("trigger_multiple");
378         GetBoundingCube(triggerVoiceBtm, max, "textures/common/trigger", triggerVoice);
379         triggerVoice->AddEPair("target", buffer);
380 //--------------------
381
382 // target for speaker
383         vec3_t voiceOrigin;
384         VectorCopy(centre, voiceOrigin);
385         voiceOrigin[2] = max[2]+16;
386
387
388         DEntity* targetVoice = m_Container.AddEntity("target_speaker");
389         targetVoice->AddEPair("targetname", buffer);
390
391         sprintf(buffer, "%f %f %f", voiceOrigin[0], voiceOrigin[1], voiceOrigin[2]);
392         targetVoice->AddEPair("origin", buffer);
393         targetVoice->AddEPair("spawnflags", "8");
394         targetVoice->AddEPair("noise", "*falling1.wav");
395 //--------------------
396
397 // *********** END SPEAKER *************
398
399 // ********* POWERUP REMOVAL ***********
400         sprintf(buffer, "t%i_2", team);
401
402 // trigger for powerup removal
403         vec3_t triggerPwrRmvTop, triggerPwrRmvBtm;
404         VectorCopy(min, triggerPwrRmvBtm);
405         VectorCopy(max, triggerPwrRmvTop);
406
407         triggerPwrRmvTop[2] = triggerVoiceBtm[2] - 64;
408         triggerPwrRmvBtm[2] = triggerPwrRmvTop[2] - 16;
409
410         DEntity* triggerPwrRmv = m_Container.AddEntity("trigger_multiple");
411         GetBoundingCube(triggerPwrRmvBtm, triggerPwrRmvTop, "textures/common/trigger", triggerPwrRmv);
412         triggerPwrRmv->AddEPair("target", buffer);
413 //--------------------
414
415 // target for powerup removal
416         vec3_t pwrRmvOrigin;
417         VectorCopy(centre, pwrRmvOrigin);
418         pwrRmvOrigin[2] = triggerPwrRmvTop[2]+16;
419
420         DEntity* targetPwrRmv = m_Container.AddEntity("target_remove_powerups");
421         targetPwrRmv->AddEPair("targetname", buffer);
422
423         sprintf(buffer, "%f %f %f", pwrRmvOrigin[0], pwrRmvOrigin[1], pwrRmvOrigin[2]);
424         targetPwrRmv->AddEPair("origin", buffer);
425 //--------------------
426
427 // ****** END POWERUP REMOVAL ********
428
429 // ********* DAMAGE ***********
430
431 // trigger for damage
432         vec3_t triggerDmgTop, triggerDmgBtm;
433         VectorCopy(min, triggerDmgBtm);
434         VectorCopy(max, triggerDmgTop);
435
436         triggerDmgBtm[2] = min[2] + 64;
437         triggerDmgTop[2] = triggerDmgBtm[2] + 16;
438
439         DEntity* triggerDmg = m_Container.AddEntity("trigger_hurt");
440         GetBoundingCube(triggerDmgBtm, triggerDmgTop, "textures/common/trigger", triggerDmg);
441         triggerDmg->AddEPair("dmg", "9999");
442         triggerDmg->AddEPair("spawnflags", "12");
443 //--------------------
444
445 // ****** END DAMAGE ********
446
447 // ********* NODROP ***********
448
449         vec3_t nodropTop;
450         VectorCopy(max, nodropTop);
451
452         nodropTop[2] = min[2] + 64;
453
454         GetBoundingCube(min, nodropTop, "textures/common/nodrop");
455
456 // ****** END NODROP ********
457
458         return TRUE;
459 }