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