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
21 #include "shapes.h"
22
23 #include <list>
24
25 #include "DPoint.h"
26 #include "DPlane.h"
27
28 #include "str.h"
29 #include "misc.h"
30 #include "funchandlers.h"
31
32 #include "iundo.h"
33 #include "ishaders.h"
34 #include "ientity.h"
35 #include "ieclass.h"
36 #include "ipatch.h"
37 #include "qerplugin.h"
38
39 #include <vector>
40 #include <list>
41 #include <map>
42 #include <algorithm>
43 #include <stdlib.h>
44 #include <time.h>
45
46 #include "scenelib.h"
47 #include "texturelib.h"
48
49 //#include "dialogs-gtk.h"
50
51 /************************
52 Cube Diagram
53 ************************/
54
55 /*
56
57 7 ----- 5
58 /| /|
59 / | / |
60 / | / |
61 4 ----- 6 |
62 | 2|_|___|8
63 | / | /
64 | / | / ----> WEST, definitely
65 ||/ | /
66 1|_____|/3
67
68 */
69
70 /************************
71 Global Variables
72 ************************/
73
74 vec3_t g_Origin = {0.0f, 0.0f, 0.0f};
75
76 extern bool bFacesAll[];
77
78 /************************
79 Helper Functions
80 ************************/
81
Deg2Rad(float angle)82 float Deg2Rad( float angle ){
83 return (float)( angle * Q_PI / 180 );
84 }
85
AddFaceWithTexture(scene::Node & brush,vec3_t va,vec3_t vb,vec3_t vc,const char * texture,bool detail)86 void AddFaceWithTexture( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc, const char* texture, bool detail ){
87 _QERFaceData faceData;
88 FillDefaultTexture( &faceData, va, vb, vc, texture );
89 if ( detail ) {
90 faceData.contents |= FACE_DETAIL;
91 }
92 GlobalBrushCreator().Brush_addFace( brush, faceData );
93 }
94
AddFaceWithTextureScaled(scene::Node & brush,vec3_t va,vec3_t vb,vec3_t vc,const char * texture,bool bVertScale,bool bHorScale,float minX,float minY,float maxX,float maxY)95 void AddFaceWithTextureScaled( scene::Node& brush, vec3_t va, vec3_t vb, vec3_t vc,
96 const char* texture, bool bVertScale, bool bHorScale,
97 float minX, float minY, float maxX, float maxY ){
98 qtexture_t* pqtTexInfo;
99
100 // TTimo: there used to be a call to pfnHasShader here
101 // this was not necessary. In Radiant everything is shader.
102 // If a texture doesn't have a shader script, a default shader object is used.
103 // The IShader object was leaking also
104 // collect texture info: sizes, etc
105 IShader* i = GlobalShaderSystem().getShaderForName( texture );
106 pqtTexInfo = i->getTexture(); // shader width/height doesn't come out properly
107
108 if ( pqtTexInfo ) {
109 float scale[2] = {0.5f, 0.5f};
110 float shift[2] = {0, 0};
111
112 if ( bHorScale ) {
113 float width = maxX - minX;
114
115 scale[0] = width / pqtTexInfo->width;
116 shift[0] = -(float)( (int)maxX % (int)width ) / scale[0];
117 }
118
119 if ( bVertScale ) {
120 float height = maxY - minY;
121
122 scale[1] = height / pqtTexInfo->height;
123 shift[1] = (float)( (int)minY % (int)height ) / scale[1];
124 }
125
126 _QERFaceData addFace;
127 FillDefaultTexture( &addFace, va, vb, vc, texture );
128 addFace.m_texdef.scale[0] = scale[0];
129 addFace.m_texdef.scale[1] = scale[1];
130 addFace.m_texdef.shift[0] = shift[0];
131 addFace.m_texdef.shift[1] = shift[1];
132
133 GlobalBrushCreator().Brush_addFace( brush, addFace );
134 }
135 else
136 {
137 // shouldn't even get here, as default missing texture should be returned if
138 // texture doesn't exist, but just in case
139 AddFaceWithTexture( brush, va, vb, vc, texture, false );
140 globalErrorStream() << "BobToolz::Invalid Texture Name-> " << texture;
141 }
142 // the IShader is not kept referenced, DecRef it
143 i->DecRef();
144 }
145
146 /************************
147 --Main Functions--
148 ************************/
149
Build_Wedge(int dir,vec3_t min,vec3_t max,bool bUp)150 void Build_Wedge( int dir, vec3_t min, vec3_t max, bool bUp ){
151 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
152
153 vec3_t v1, v2, v3, v5, v6, v7, v8;
154 VectorCopy( min, v1 );
155 VectorCopy( min, v2 );
156 VectorCopy( min, v3 );
157 VectorCopy( max, v5 );
158 VectorCopy( max, v6 );
159 VectorCopy( max, v7 );
160 VectorCopy( max, v8 );
161
162 v2[0] = max[0];
163 v3[1] = max[1];
164
165 v6[0] = min[0];
166 v7[1] = min[1];
167 v8[2] = min[2];
168
169 if ( bUp ) {
170
171 if ( dir != MOVE_EAST ) {
172 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
173 }
174
175 if ( dir != MOVE_WEST ) {
176 AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
177 }
178
179 if ( dir != MOVE_NORTH ) {
180 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
181 }
182
183 if ( dir != MOVE_SOUTH ) {
184 AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
185 }
186
187 AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
188
189 if ( dir == MOVE_EAST ) {
190 AddFaceWithTexture( newBrush, v1, v3, v5, "textures/common/caulk", false );
191 }
192
193 if ( dir == MOVE_WEST ) {
194 AddFaceWithTexture( newBrush, v2, v6, v8, "textures/common/caulk", false );
195 }
196
197 if ( dir == MOVE_NORTH ) {
198 AddFaceWithTexture( newBrush, v1, v6, v5, "textures/common/caulk", false );
199 }
200
201 if ( dir == MOVE_SOUTH ) {
202 AddFaceWithTexture( newBrush, v7, v3, v8, "textures/common/caulk", false );
203 }
204 }
205 else
206 {
207 if ( dir != MOVE_WEST ) {
208 AddFaceWithTexture( newBrush, v7, v5, v8, "textures/common/caulk", false );
209 }
210
211 if ( dir != MOVE_EAST ) {
212 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
213 }
214
215 if ( dir != MOVE_NORTH ) {
216 AddFaceWithTexture( newBrush, v3, v8, v6, "textures/common/caulk", false );
217 }
218
219 if ( dir != MOVE_SOUTH ) {
220 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
221 }
222
223
224 AddFaceWithTexture( newBrush, v6, v5, v7, "textures/common/caulk", false );
225
226 if ( dir == MOVE_WEST ) {
227 AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", false );
228 }
229
230 if ( dir == MOVE_EAST ) {
231 AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", false );
232 }
233
234 if ( dir == MOVE_NORTH ) {
235 AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", false );
236 }
237
238 if ( dir == MOVE_SOUTH ) {
239 AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", false );
240 }
241 }
242
243 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
244 }
245
246 //-----------------------------------------------------------------------------------
247 //-----------------------------------------------------------------------------------
248
Build_StairStep_Wedge(int dir,vec3_t min,vec3_t max,const char * mainTexture,const char * riserTexture,bool detail)249 void Build_StairStep_Wedge( int dir, vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, bool detail ){
250 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
251
252 //----- Build Outer Bounds ---------
253
254 vec3_t v1, v2, v3, v5, v6, v7, v8;
255 VectorCopy( min, v1 );
256 VectorCopy( min, v2 );
257 VectorCopy( min, v3 );
258 VectorCopy( max, v5 );
259 VectorCopy( max, v6 );
260 VectorCopy( max, v7 );
261 VectorCopy( max, v8 );
262
263 v2[0] = max[0];
264 v3[1] = max[1];
265
266 v6[0] = min[0];
267 v7[1] = min[1];
268
269 v8[2] = min[2];
270 //v8 needed this time, becoz of sloping faces (2-4-6-8)
271
272 //----------------------------------
273
274 AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, detail );
275
276 if ( dir != MOVE_EAST ) {
277 if ( dir == MOVE_WEST ) {
278 AddFaceWithTexture( newBrush, v5, v2, v7, riserTexture, detail );
279 }
280 else{
281 AddFaceWithTexture( newBrush, v5, v2, v7, "textures/common/caulk", detail );
282 }
283 }
284
285 if ( dir != MOVE_WEST ) {
286 if ( dir == MOVE_EAST ) {
287 AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, detail );
288 }
289 else{
290 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", detail );
291 }
292 }
293
294 if ( dir != MOVE_NORTH ) {
295 if ( dir == MOVE_SOUTH ) {
296 AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, detail );
297 }
298 else{
299 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", detail );
300 }
301 }
302
303 if ( dir != MOVE_SOUTH ) {
304 if ( dir == MOVE_NORTH ) {
305 AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, detail );
306 }
307 else{
308 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", detail );
309 }
310 }
311
312
313 if ( dir == MOVE_EAST ) {
314 AddFaceWithTexture( newBrush, v1, v5, v3, "textures/common/caulk", detail );
315 }
316
317 if ( dir == MOVE_WEST ) {
318 AddFaceWithTexture( newBrush, v2, v8, v6, "textures/common/caulk", detail );
319 }
320
321 if ( dir == MOVE_NORTH ) {
322 AddFaceWithTexture( newBrush, v1, v5, v6, "textures/common/caulk", detail );
323 }
324
325 if ( dir == MOVE_SOUTH ) {
326 AddFaceWithTexture( newBrush, v7, v8, v3, "textures/common/caulk", detail );
327 }
328
329 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
330 }
331
332 //-----------------------------------------------------------------------------------
333 //-----------------------------------------------------------------------------------
334
335 // internal use only, to get a box without finishing construction
Build_Get_BoundingCube_Selective(vec3_t min,vec3_t max,char * texture,bool * useFaces)336 scene::Node& Build_Get_BoundingCube_Selective( vec3_t min, vec3_t max, char* texture, bool* useFaces ){
337 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
338
339 //----- Build Outer Bounds ---------
340
341 vec3_t v1, v2, v3, v5, v6, v7;
342 VectorCopy( min, v1 );
343 VectorCopy( min, v2 );
344 VectorCopy( min, v3 );
345 VectorCopy( max, v5 );
346 VectorCopy( max, v6 );
347 VectorCopy( max, v7 );
348
349 v2[0] = max[0];
350 v3[1] = max[1];
351
352 v6[0] = min[0];
353 v7[1] = min[1];
354
355 //----------------------------------
356
357 //----- Add Six Cube Faces ---------
358
359 if ( useFaces[0] ) {
360 AddFaceWithTexture( newBrush, v1, v2, v3, texture, false );
361 }
362 if ( useFaces[1] ) {
363 AddFaceWithTexture( newBrush, v1, v3, v6, texture, false );
364 }
365 if ( useFaces[2] ) {
366 AddFaceWithTexture( newBrush, v1, v7, v2, texture, false );
367 }
368
369 if ( useFaces[3] ) {
370 AddFaceWithTexture( newBrush, v5, v6, v3, texture, false );
371 }
372 if ( useFaces[4] ) {
373 AddFaceWithTexture( newBrush, v5, v2, v7, texture, false );
374 }
375 if ( useFaces[5] ) {
376 AddFaceWithTexture( newBrush, v5, v7, v6, texture, false );
377 }
378
379 //----------------------------------
380
381 return newBrush;
382 }
383
Build_Get_BoundingCube(vec3_t min,vec3_t max,char * texture)384 scene::Node& Build_Get_BoundingCube( vec3_t min, vec3_t max, char* texture ){
385 return Build_Get_BoundingCube_Selective( min, max, texture, bFacesAll );
386 }
387
388 //-----------------------------------------------------------------------------------
389 //-----------------------------------------------------------------------------------
390
Build_StairStep(vec3_t min,vec3_t max,const char * mainTexture,const char * riserTexture,int direction)391 void Build_StairStep( vec3_t min, vec3_t max, const char* mainTexture, const char* riserTexture, int direction ){
392 NodeSmartReference newBrush( GlobalBrushCreator().createBrush() );
393
394 //----- Build Outer Bounds ---------
395
396 vec3_t v1, v2, v3, v5, v6, v7;
397 VectorCopy( min, v1 );
398 VectorCopy( min, v2 );
399 VectorCopy( min, v3 );
400 VectorCopy( max, v5 );
401 VectorCopy( max, v6 );
402 VectorCopy( max, v7 );
403
404 v2[0] = max[0];
405 v3[1] = max[1];
406
407 v6[0] = min[0];
408 v7[1] = min[1];
409
410 //----------------------------------
411
412 AddFaceWithTexture( newBrush, v6, v5, v7, mainTexture, false );
413 // top gets current texture
414
415
416 if ( direction == MOVE_EAST ) {
417 AddFaceWithTexture( newBrush, v1, v3, v6, riserTexture, false );
418 }
419 else{
420 AddFaceWithTexture( newBrush, v1, v3, v6, "textures/common/caulk", false );
421 }
422 // west facing side, etc...
423
424
425 if ( direction == MOVE_NORTH ) {
426 AddFaceWithTexture( newBrush, v1, v7, v2, riserTexture, false );
427 }
428 else{
429 AddFaceWithTexture( newBrush, v1, v7, v2, "textures/common/caulk", false );
430 }
431
432 if ( direction == MOVE_SOUTH ) {
433 AddFaceWithTexture( newBrush, v3, v5, v6, riserTexture, false );
434 }
435 else{
436 AddFaceWithTexture( newBrush, v3, v5, v6, "textures/common/caulk", false );
437 }
438
439 if ( direction == MOVE_WEST ) {
440 AddFaceWithTexture( newBrush, v7, v5, v2, riserTexture, false );
441 }
442 else{
443 AddFaceWithTexture( newBrush, v7, v5, v2, "textures/common/caulk", false );
444 }
445
446
447 AddFaceWithTexture( newBrush, v1, v2, v3, "textures/common/caulk", false );
448 // base is caulked
449
450 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( newBrush );
451 // finish brush
452 }
453
454 //-----------------------------------------------------------------------------------
455 //-----------------------------------------------------------------------------------
456
BuildDoorsX2(vec3_t min,vec3_t max,bool bSclMainHor,bool bSclMainVert,bool bSclTrimHor,bool bSclTrimVert,const char * mainTexture,const char * trimTexture,int direction)457 void BuildDoorsX2( vec3_t min, vec3_t max,
458 bool bSclMainHor, bool bSclMainVert,
459 bool bSclTrimHor, bool bSclTrimVert,
460 const char* mainTexture, const char* trimTexture,
461 int direction ){
462 int xy;
463 if ( direction == 0 ) {
464 xy = 0;
465 }
466 else{
467 xy = 1;
468 }
469
470 //----- Build Outer Bounds ---------
471
472 vec3_t v1, v2, v3, v5, v6, v7, ve_1, ve_2, ve_3;
473 VectorCopy( min, v1 );
474 VectorCopy( min, v2 );
475 VectorCopy( min, v3 );
476 VectorCopy( max, v5 );
477 VectorCopy( max, v6 );
478 VectorCopy( max, v7 );
479
480 v2[0] = max[0];
481 v3[1] = max[1];
482
483 v6[0] = min[0];
484 v7[1] = min[1];
485
486 float width = ( max[xy] - min[xy] ) / 2;
487
488 if ( direction == 0 ) {
489 VectorCopy( v1, ve_1 );
490 VectorCopy( v3, ve_2 );
491 VectorCopy( v6, ve_3 );
492 }
493 else
494 {
495 VectorCopy( v7, ve_1 );
496 VectorCopy( v1, ve_2 );
497 VectorCopy( v2, ve_3 );
498 }
499
500 ve_1[xy] += width;
501 ve_2[xy] += width;
502 ve_3[xy] += width;
503
504 //----------------------------------
505
506 NodeSmartReference newBrush1( GlobalBrushCreator().createBrush() );
507 NodeSmartReference newBrush2( GlobalBrushCreator().createBrush() );
508
509 AddFaceWithTexture( newBrush1, v1, v2, v3, "textures/common/caulk", false );
510 AddFaceWithTexture( newBrush1, v5, v7, v6, "textures/common/caulk", false );
511
512 AddFaceWithTexture( newBrush2, v1, v2, v3, "textures/common/caulk", false );
513 AddFaceWithTexture( newBrush2, v5, v7, v6, "textures/common/caulk", false );
514
515 if ( direction == 0 ) {
516 AddFaceWithTexture( newBrush1, v1, v3, v6, "textures/common/caulk", false );
517 AddFaceWithTexture( newBrush2, v5, v2, v7, "textures/common/caulk", false );
518 }
519 else
520 {
521 AddFaceWithTexture( newBrush1, v1, v7, v2, "textures/common/caulk", false );
522 AddFaceWithTexture( newBrush2, v5, v6, v3, "textures/common/caulk", false );
523 }
524
525 if ( direction == 0 ) {
526 AddFaceWithTextureScaled( newBrush1, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
527 min[0], min[2], max[0], max[2] );
528 AddFaceWithTextureScaled( newBrush1, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
529 max[0], min[2], min[0], max[2] );
530
531
532 AddFaceWithTextureScaled( newBrush2, v1, v7, v2, mainTexture, bSclMainVert, bSclMainHor,
533 min[0], min[2], max[0], max[2] );
534 AddFaceWithTextureScaled( newBrush2, v5, v6, v3, mainTexture, bSclMainVert, bSclMainHor,
535 max[0], min[2], min[0], max[2] ); // flip max/min to reverse tex dir
536
537
538
539 AddFaceWithTextureScaled( newBrush1, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
540 min[1], min[2], max[1], max[2] );
541
542 AddFaceWithTextureScaled( newBrush2, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
543 max[1], min[2], min[1], max[2] );
544 }
545 else
546 {
547 AddFaceWithTextureScaled( newBrush1, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
548 min[1], min[2], max[1], max[2] );
549 AddFaceWithTextureScaled( newBrush1, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
550 max[1], min[2], min[1], max[2] );
551
552
553 AddFaceWithTextureScaled( newBrush2, v1, v3, v6, mainTexture, bSclMainVert, bSclMainHor,
554 min[1], min[2], max[1], max[2] );
555 AddFaceWithTextureScaled( newBrush2, v5, v2, v7, mainTexture, bSclMainVert, bSclMainHor,
556 max[1], min[2], min[1], max[2] ); // flip max/min to reverse tex dir
557
558
559 AddFaceWithTextureScaled( newBrush1, ve_1, ve_2, ve_3, trimTexture, bSclTrimVert, bSclTrimHor,
560 min[0], min[2], max[0], max[2] );
561
562 AddFaceWithTextureScaled( newBrush2, ve_3, ve_2, ve_1, trimTexture, bSclTrimVert, bSclTrimHor,
563 max[0], min[2], min[0], max[2] );
564 }
565
566 //----------------------------------
567
568
569 EntityClass* doorClass = GlobalEntityClassManager().findOrInsert( "func_door", true );
570 NodeSmartReference pEDoor1( GlobalEntityCreator().createEntity( doorClass ) );
571 NodeSmartReference pEDoor2( GlobalEntityCreator().createEntity( doorClass ) );
572
573 if ( direction == 0 ) {
574 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "180" );
575 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "360" );
576 }
577 else
578 {
579 Node_getEntity( pEDoor1 )->setKeyValue( "angle", "270" );
580 Node_getEntity( pEDoor2 )->setKeyValue( "angle", "90" );
581 }
582
583 srand( (unsigned)time( NULL ) );
584
585 char teamname[256];
586 sprintf( teamname, "t%i", rand() );
587 Node_getEntity( pEDoor1 )->setKeyValue( "team", teamname );
588 Node_getEntity( pEDoor2 )->setKeyValue( "team", teamname );
589
590 Node_getTraversable( pEDoor1 )->insert( newBrush1 );
591 Node_getTraversable( pEDoor2 )->insert( newBrush2 );
592
593 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor1 );
594 Node_getTraversable( GlobalSceneGraph().root() )->insert( pEDoor2 );
595
596 // ResetCurrentTexture();
597 }
598
599 //-----------------------------------------------------------------------------------
600 //-----------------------------------------------------------------------------------
601
MakeBevel(vec3_t vMin,vec3_t vMax)602 void MakeBevel( vec3_t vMin, vec3_t vMax ){
603 NodeSmartReference patch( GlobalPatchCreator().createPatch() );
604 GlobalPatchCreator().Patch_resize( patch, 3, 3 );
605 GlobalPatchCreator().Patch_setShader( patch, "textures/common/caulk" );
606 PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch );
607 vec3_t x_3, y_3, z_3;
608 x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0];
609 y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1];
610 z_3[0] = vMin[2]; z_3[1] = ( vMax[2] + vMin[2] ) / 2; z_3[2] = vMax[2];
611 /*
612 x_3[0] = 0; x_3[1] = 0; x_3[2] = 64;
613 y_3[0] = 0; y_3[1] = 64; y_3[2] = 64;
614 z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/
615 for ( int i = 0; i < 3; i++ )
616 {
617 for ( int j = 0; j < 3; j++ )
618 {
619 PatchControl& p = matrix( i, j );
620 p.m_vertex[0] = x_3[i];
621 p.m_vertex[1] = y_3[i];
622 p.m_vertex[2] = z_3[j];
623 }
624 }
625 //does invert the matrix, else the patch face is on wrong side.
626 for ( int i = 0 ; i < 3 ; i++ )
627 {
628 for ( int j = 0; j < 1; j++ )
629 {
630 PatchControl& p = matrix( i,2 - j );
631 PatchControl& q = matrix( i, j );
632 std::swap( p.m_vertex, q.m_vertex );
633 //std::swap(p.m_texcoord, q.m_texcoord);
634 }
635 }
636 GlobalPatchCreator().Patch_controlPointsChanged( patch );
637 //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code..
638 //NaturalTexture(patch);
639 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( patch );
640 }
641
BuildCornerStairs(vec3_t vMin,vec3_t vMax,int nSteps,const char * mainTexture,const char * riserTex)642 void BuildCornerStairs( vec3_t vMin, vec3_t vMax, int nSteps, const char* mainTexture, const char* riserTex ){
643 vec3_t* topPoints = new vec3_t[nSteps + 1];
644 vec3_t* botPoints = new vec3_t[nSteps + 1];
645
646 //bool bFacesUse[6] = {true, true, false, true, false, false};
647
648 vec3_t centre;
649 VectorCopy( vMin, centre );
650 centre[0] = vMax[0];
651
652 int height = (int)( vMax[2] - vMin[2] ) / nSteps;
653
654 vec3_t vTop, vBot;
655 VectorCopy( vMax, vTop );
656 VectorCopy( vMin, vBot );
657 vTop[2] = vMin[2] + height;
658
659 int i;
660 for ( i = 0; i <= nSteps; i++ )
661 {
662 VectorCopy( centre, topPoints[i] );
663 VectorCopy( centre, botPoints[i] );
664
665 topPoints[i][2] = vMax[2];
666 botPoints[i][2] = vMin[2];
667
668 topPoints[i][0] -= 10 * sinf( Q_PI * i / ( 2 * nSteps ) );
669 topPoints[i][1] += 10 * cosf( Q_PI * i / ( 2 * nSteps ) );
670
671 botPoints[i][0] = topPoints[i][0];
672 botPoints[i][1] = topPoints[i][1];
673 }
674
675 vec3_t tp[3];
676 for ( int j = 0; j < 3; j++ )
677 VectorCopy( topPoints[j], tp[j] );
678
679 for ( i = 0; i < nSteps; i++ )
680 {
681 NodeSmartReference brush( GlobalBrushCreator().createBrush() );
682 vec3_t v1, v2, v3, v5, v6, v7;
683 VectorCopy( vBot, v1 );
684 VectorCopy( vBot, v2 );
685 VectorCopy( vBot, v3 );
686 VectorCopy( vTop, v5 );
687 VectorCopy( vTop, v6 );
688 VectorCopy( vTop, v7 );
689
690 v2[0] = vTop[0];
691 v3[1] = vTop[1];
692
693 v6[0] = vBot[0];
694 v7[1] = vBot[1];
695
696 AddFaceWithTexture( brush, v1, v2, v3, "textures/common/caulk", false );
697 AddFaceWithTexture( brush, v1, v3, v6, "textures/common/caulk", false );
698 AddFaceWithTexture( brush, v5, v6, v3, "textures/common/caulk", false );
699
700 for ( int j = 0; j < 3; j++ )
701 tp[j][2] = vTop[2];
702
703 AddFaceWithTexture( brush, tp[2], tp[1], tp[0], mainTexture, false );
704
705 AddFaceWithTexture( brush, centre, botPoints[i + 1], topPoints[i + 1], "textures/common/caulk", false );
706 AddFaceWithTexture( brush, centre, topPoints[i], botPoints[i], riserTex, false );
707
708 Node_getTraversable( GlobalRadiant().getMapWorldEntity() )->insert( brush );
709
710 vTop[2] += height;
711 vBot[2] += height;
712 }
713
714 delete[] topPoints;
715 delete[] botPoints;
716
717 vMin[2] += height;
718 vMax[2] += height;
719 MakeBevel( vMin, vMax );
720 }
721