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