]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/genmap.cpp
my own uncrustify run
[xonotic/netradiant.git] / contrib / gtkgensurf / genmap.cpp
1 /*
2    GenSurf plugin for GtkRadiant
3    Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
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 #include <math.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include "gensurf.h"
24
25 double xmin,xmax,ymin,ymax,zmin,zmax;
26 double backface;
27 extern double dh, dv;
28 FILE  *fmap;
29 XYZ xyz[MAX_ROWS + 1][MAX_ROWS + 1];
30 int contents;
31 int surface[3];
32
33 #include "iundo.h"
34
35 #include "refcounted_ptr.h"
36
37 #include <vector>
38 #include <list>
39 #include <map>
40 #include <algorithm>
41
42 #include "scenelib.h"
43
44 scene::Node* h_func_group;
45 scene::Node* h_worldspawn;
46
47
48 //=============================================================
49 // Hydra : snap-to-grid begin
50 double CalculateSnapValue( double value ){
51         long snapvalue;
52
53         // simple uncomplicated snapping, rounding both UP and DOWN to the nearest
54         // grid unit.
55         if ( SnapToGrid > 0 ) {
56                 snapvalue = (int)value / SnapToGrid;
57                 if ( (long)value % SnapToGrid < ( SnapToGrid / 2 ) ) { // Snap Downwards if less than halfway between to grid units
58                         value = snapvalue * SnapToGrid;
59                 }
60                 else{ // Snap Upwards if more than halfway between to grid units
61                         value = ( snapvalue + 1 ) * SnapToGrid;
62                 }
63         }
64         return value;
65 }
66 // Hydra : snap-to-grid end
67
68 //=============================================================
69 bool ValidSurface(){
70         if ( WaveType == WAVE_BITMAP && !gbmp.colors ) {
71                 return FALSE;
72         }
73         if ( NH  < 1 ) {
74                 return FALSE;
75         }
76         if ( NH  > MAX_ROWS ) {
77                 return FALSE;
78         }
79         if ( NV  < 1 ) {
80                 return FALSE;
81         }
82         if ( NV  > MAX_ROWS ) {
83                 return FALSE;
84         }
85         if ( Hll >= Hur ) {
86                 return FALSE;
87         }
88         if ( Vll >= Vur ) {
89                 return FALSE;
90         }
91         return TRUE;
92 }
93
94 //=============================================================
95 int MapPatches(){
96         int NH_remain;
97         int NV_remain;
98         int NH_patch;
99         int NV_patch;
100         int BrushNum = 0;
101         int i, j, k1, k2, k3;
102         int i0, j0, ii;
103         char szOops[128];
104
105         dh = ( Hur - Hll ) / NH;
106         dv = ( Vur - Vll ) / NV;
107
108         // Generate control points in pp array to give desired values currently
109         // in p array.
110         switch ( Plane )
111         {
112         case PLANE_XY0:
113         case PLANE_XY1:
114                 k1 = 0;
115                 k2 = 1;
116                 k3 = 2;
117                 break;
118         case PLANE_XZ0:
119         case PLANE_XZ1:
120                 k1 = 0;
121                 k2 = 2;
122                 k3 = 1;
123                 break;
124         case PLANE_YZ0:
125         case PLANE_YZ1:
126                 k1 = 1;
127                 k2 = 2;
128                 k3 = 0;
129                 break;
130         }
131         for ( i = 0; i <= NH; i++ )
132         {
133                 for ( j = 0; j <= NV; j++ )
134                 {
135                         xyz[i][j].pp[k1] = xyz[i][j].p[k1];
136                         xyz[i][j].pp[k2] = xyz[i][j].p[k2];
137                 }
138         }
139         for ( i = 0; i <= NH; i += 2 )
140         {
141                 for ( j = 0; j <= NV; j += 2 )
142                         xyz[i][j].pp[k3] = xyz[i][j].p[k3];
143         }
144         for ( i = 1; i < NH; i += 2 )
145         {
146                 for ( j = 0; j <= NV; j += 2 )
147                 {
148                         xyz[i][j].pp[k3] = ( 4 * xyz[i][j].p[k3] - xyz[i - 1][j].p[k3] - xyz[i + 1][j].p[k3] ) / 2;
149                 }
150         }
151         for ( j = 1; j < NV; j += 2 )
152         {
153                 for ( i = 0; i <= NH; i += 2 )
154                 {
155                         xyz[i][j].pp[k3] = ( 4 * xyz[i][j].p[k3] - xyz[i][j - 1].p[k3] - xyz[i][j + 1].p[k3] ) / 2;
156                 }
157         }
158         for ( i = 1; i < NH; i += 2 )
159         {
160                 for ( j = 1; j < NV; j += 2 )
161                 {
162                         xyz[i][j].pp[k3] = ( 16 * xyz[i][j].p[k3] - xyz[i - 1][j - 1].p[k3] - 2 * xyz[i][j - 1].p[k3]
163                                                                  - xyz[i + 1][j - 1].p[k3] - 2 * xyz[i - 1][j].p[k3] - 2 * xyz[i + 1][j].p[k3]
164                                                                  - xyz[i - 1][j + 1].p[k3] - 2 * xyz[i][j + 1].p[k3] - xyz[i + 1][j + 1].p[k3] ) / 4;
165                 }
166         }
167
168         NH_remain = NH + 1;
169         i0 = 0;
170         while ( NH_remain > 1 )
171         {
172                 if ( ( ( NH_remain - 1 ) % 14 ) == 0 ) {
173                         NH_patch = 15;
174                 }
175                 else if ( ( ( NH_remain - 1 ) % 12 ) == 0 ) {
176                         NH_patch = 13;
177                 }
178                 else if ( ( ( NH_remain - 1 ) % 10 ) == 0 ) {
179                         NH_patch = 11;
180                 }
181                 else if ( ( ( NH_remain - 1 ) % 8 ) == 0 ) {
182                         NH_patch = 9;
183                 }
184                 else if ( ( ( NH_remain - 1 ) % 6 ) == 0 ) {
185                         NH_patch = 7;
186                 }
187                 else if ( ( ( NH_remain - 1 ) % 4 ) == 0 ) {
188                         NH_patch = 5;
189                 }
190                 else if ( ( ( NH_remain - 1 ) % 2 ) == 0 ) {
191                         NH_patch = 3;
192                 }
193                 else if ( NH_remain > 16 ) {
194                         NH_patch = 7;
195                 }
196                 else if ( NH_remain > 4 ) {
197                         NH_patch = 5;
198                 }
199                 else{
200                         NH_patch = 3;
201                 }
202                 while ( NH_patch > 3 && ( NH_patch - 1 ) * dh > 512 )
203                         NH_patch -= 2;
204                 NH_remain -= ( NH_patch - 1 );
205                 if ( NH_remain < 0 ) {
206                         sprintf( szOops,"Oops... screwed up with NH=%d",NH );
207                         g_FuncTable.m_pfnMessageBox( NULL,szOops,"Uh oh" );
208                 }
209                 NV_remain = NV + 1;
210                 j0 = 0;
211                 while ( NV_remain > 1 )
212                 {
213                         if ( ( ( NV_remain - 1 ) % 14 ) == 0 ) {
214                                 NV_patch = 15;
215                         }
216                         else if ( ( ( NV_remain - 1 ) % 12 ) == 0 ) {
217                                 NV_patch = 13;
218                         }
219                         else if ( ( ( NV_remain - 1 ) % 10 ) == 0 ) {
220                                 NV_patch = 11;
221                         }
222                         else if ( ( ( NV_remain - 1 ) % 8 ) == 0 ) {
223                                 NV_patch = 9;
224                         }
225                         else if ( ( ( NV_remain - 1 ) % 6 ) == 0 ) {
226                                 NV_patch = 7;
227                         }
228                         else if ( ( ( NV_remain - 1 ) % 4 ) == 0 ) {
229                                 NV_patch = 5;
230                         }
231                         else if ( ( ( NV_remain - 1 ) % 2 ) == 0 ) {
232                                 NV_patch = 3;
233                         }
234                         else if ( NV_remain > 16 ) {
235                                 NV_patch = 7;
236                         }
237                         else if ( NV_remain > 4 ) {
238                                 NV_patch = 5;
239                         }
240                         else{
241                                 NV_patch = 3;
242                         }
243                         while ( NV_patch > 3 && ( NV_patch - 1 ) * dh > 512 )
244                                 NV_patch -= 2;
245                         NV_remain -= ( NV_patch - 1 );
246                         if ( NV_remain < 0 ) {
247                                 sprintf( szOops,"Oops... screwed up with NV=%d",NV );
248                                 g_FuncTable.m_pfnMessageBox( NULL,szOops,"Uh oh" );
249                         }
250
251                         scene::Node* patch = MakePatch();
252 #if 0
253                         b->pPatch->setDims( NH_patch, NV_patch );
254                         for ( i = 0; i < NH_patch; i++ )
255                         {
256                                 switch ( Plane )
257                                 {
258                                 case PLANE_XY1:
259                                 case PLANE_XZ0:
260                                 case PLANE_YZ1:
261                                         ii = i0 + NH_patch - 1 - i;
262                                         break;
263                                 default:
264                                         ii = i0 + i;
265                                 }
266                                 for ( j = 0; j < NV_patch; j++ )
267                                 {
268                                         b->pPatch->ctrlAt( COL,i,j )[0] = (float)xyz[ii][j0 + j].pp[0];
269                                         b->pPatch->ctrlAt( COL,i,j )[1] = (float)xyz[ii][j0 + j].pp[1];
270                                         b->pPatch->ctrlAt( COL,i,j )[2] = (float)xyz[ii][j0 + j].pp[2];
271                                         b->pPatch->ctrlAt( COL,i,j )[3] = (float)i;
272                                         b->pPatch->ctrlAt( COL,i,j )[4] = (float)j;
273                                 }
274                         }
275                         b->pPatch->UpdateCachedData();
276 #endif
277                         BrushNum++;
278                         j0 += NV_patch - 1;
279                 }
280                 i0 += NH_patch - 1;
281         }
282         return BrushNum;
283 }
284
285 //=============================================================
286 void MapBrushes(){
287         char hint[128];
288         char skip[128];
289         char sidetext[64];
290         char surftext[64];
291         char surftext2[64];
292         char surft[64];
293         float Steep;
294         vec3_t PlaneNormal,SurfNormal;
295         vec3_t t[2];
296         int i, j, k;
297         int surf;
298         bool CheckAngle;
299         BRUSH brush;
300         XYZ v[8];
301
302         strcpy( surftext,Texture[Game][0] );
303         strcpy( sidetext,( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
304         strcpy( surftext2,( strlen( Texture[Game][2] ) ? Texture[Game][2] : Texture[Game][0] ) );
305
306         // if surftext2 is identical to surftext, there's no need to
307         // check surface angle
308         if ( !g_strcasecmp( surftext,surftext2 ) ) {
309                 CheckAngle = FALSE;
310         }
311         else
312         {
313                 CheckAngle = TRUE;
314                 Steep = (float)cos( (double)SlantAngle / 57.2957795 );
315                 switch ( Plane )
316                 {
317                 case PLANE_XY0: PlaneNormal[0] = 0.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
318                 case PLANE_XY1: PlaneNormal[0] = 0.; PlaneNormal[1] = 0.; PlaneNormal[2] = -1.; break;
319                 case PLANE_XZ0: PlaneNormal[0] = 0.; PlaneNormal[1] = 1.; PlaneNormal[2] = 1.; break;
320                 case PLANE_XZ1: PlaneNormal[0] = 0.; PlaneNormal[1] = -1.; PlaneNormal[2] = 1.; break;
321                 case PLANE_YZ0: PlaneNormal[0] = 1.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
322                 case PLANE_YZ1: PlaneNormal[0] = -1.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
323                 }
324         }
325
326         OpenFuncGroup();
327
328         for ( i = 0; i < NH; i++ )
329         {
330                 for ( j = 0; j < NV; j++ )
331                 {
332                         if ( ( i + j ) % 2 ) {
333                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
334                                 switch ( Plane )
335                                 {
336                                 case PLANE_XY1:
337                                 case PLANE_XZ1:
338                                 case PLANE_YZ1:
339                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
340                                         VectorCopy( xyz[i + 1][j + 1].p, v[2].p );
341                                         break;
342                                 default:
343                                         VectorCopy( xyz[i + 1][j + 1].p, v[1].p );
344                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
345                                 }
346                         }
347                         else
348                         {
349                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
350                                 switch ( Plane )
351                                 {
352                                 case PLANE_XY1:
353                                 case PLANE_XZ1:
354                                 case PLANE_YZ1:
355                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
356                                         VectorCopy( xyz[i  ][j + 1].p, v[2].p );
357                                         break;
358                                 default:
359                                         VectorCopy( xyz[i  ][j + 1].p, v[1].p );
360                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
361                                 }
362                         }
363                         VectorCopy( v[0].p,v[3].p );
364                         VectorCopy( v[1].p,v[4].p );
365                         VectorCopy( v[2].p,v[5].p );
366                         switch ( Plane )
367                         {
368                         case PLANE_XZ0:
369                         case PLANE_XZ1:
370                                 v[0].p[1] = backface;
371                                 v[1].p[1] = backface;
372                                 v[2].p[1] = backface;
373                                 break;
374                         case PLANE_YZ0:
375                         case PLANE_YZ1:
376                                 v[3].p[0] = backface;
377                                 v[4].p[0] = backface;
378                                 v[5].p[0] = backface;
379                                 break;
380                         default:
381                                 v[3].p[2] = backface;
382                                 v[4].p[2] = backface;
383                                 v[5].p[2] = backface;
384                         }
385
386                         brush.Number   = i * NV * 2 + j * 2;
387                         brush.NumFaces = 5;
388                         XYZtoV( &v[0],&brush.face[0].v[0] );
389                         XYZtoV( &v[3],&brush.face[0].v[1] );
390                         XYZtoV( &v[4],&brush.face[0].v[2] );
391                         strcpy( brush.face[0].texture,
392                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
393                         brush.face[0].Shift[0] = (float)TexOffset[0];
394                         brush.face[0].Shift[1] = (float)TexOffset[1];
395                         brush.face[0].Rotate   = 0.;
396                         brush.face[0].Scale[0] = (float)TexScale[0];
397                         brush.face[0].Scale[1] = (float)TexScale[1];
398                         brush.face[0].Contents = contents;
399                         brush.face[0].Surface  = surface[1];
400                         brush.face[0].Value    = 0;
401
402                         XYZtoV( &v[1],&brush.face[1].v[0] );
403                         XYZtoV( &v[4],&brush.face[1].v[1] );
404                         XYZtoV( &v[5],&brush.face[1].v[2] );
405                         strcpy( brush.face[1].texture,
406                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
407                         brush.face[1].Shift[0] = (float)TexOffset[0];
408                         brush.face[1].Shift[1] = (float)TexOffset[1];
409                         brush.face[1].Rotate   = 0.;
410                         brush.face[1].Scale[0] = (float)TexScale[0];
411                         brush.face[1].Scale[1] = (float)TexScale[1];
412                         brush.face[1].Contents = contents;
413                         brush.face[1].Surface  = surface[1];
414                         brush.face[1].Value    = 0;
415
416                         XYZtoV( &v[2],&brush.face[2].v[0] );
417                         XYZtoV( &v[5],&brush.face[2].v[1] );
418                         XYZtoV( &v[3],&brush.face[2].v[2] );
419                         strcpy( brush.face[2].texture,
420                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
421                         brush.face[2].Shift[0] = (float)TexOffset[0];
422                         brush.face[2].Shift[1] = (float)TexOffset[1];
423                         brush.face[2].Rotate   = 0.;
424                         brush.face[2].Scale[0] = (float)TexScale[0];
425                         brush.face[2].Scale[1] = (float)TexScale[1];
426                         brush.face[2].Contents = contents;
427                         brush.face[2].Surface  = surface[1];
428                         brush.face[2].Value    = 0;
429
430                         if ( CheckAngle && ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ) ) {
431                                 XYZVectorSubtract( v[4].p,v[3].p,t[0] );
432                                 XYZVectorSubtract( v[5].p,v[4].p,t[1] );
433                                 CrossProduct( t[0],t[1],SurfNormal );
434                                 VectorNormalize( SurfNormal,SurfNormal );
435                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
436                                         strcpy( surft,surftext2 );
437                                         surf = surface[2];
438                                 }
439                                 else
440                                 {
441                                         strcpy( surft,surftext );
442                                         surf = surface[0];
443                                 }
444                         }
445                         else
446                         {
447                                 strcpy( surft,surftext );
448                                 surf = surface[0];
449                         }
450
451                         XYZtoV( &v[3],&brush.face[3].v[0] );
452                         XYZtoV( &v[5],&brush.face[3].v[1] );
453                         XYZtoV( &v[4],&brush.face[3].v[2] );
454                         strcpy( brush.face[3].texture,
455                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext ) );
456                         brush.face[3].Shift[0] = (float)TexOffset[0];
457                         brush.face[3].Shift[1] = (float)TexOffset[1];
458                         brush.face[3].Rotate   = 0.;
459                         brush.face[3].Scale[0] = (float)TexScale[0];
460                         brush.face[3].Scale[1] = (float)TexScale[1];
461                         brush.face[3].Contents = contents;
462                         brush.face[3].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1] );
463                         brush.face[3].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0 );
464
465                         if ( CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1 ) {
466                                 XYZVectorSubtract( v[2].p,v[0].p,t[0] );
467                                 XYZVectorSubtract( v[1].p,v[2].p,t[1] );
468                                 CrossProduct( t[0],t[1],SurfNormal );
469                                 VectorNormalize( SurfNormal,SurfNormal );
470                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
471                                         strcpy( surft,surftext2 );
472                                         surf = surface[2];
473                                 }
474                                 else
475                                 {
476                                         strcpy( surft,surftext );
477                                         surf = surface[0];
478                                 }
479                         }
480                         else
481                         {
482                                 strcpy( surft,surftext );
483                                 surf = surface[0];
484                         }
485
486                         XYZtoV( &v[0],&brush.face[4].v[0] );
487                         XYZtoV( &v[1],&brush.face[4].v[1] );
488                         XYZtoV( &v[2],&brush.face[4].v[2] );
489                         strcpy( brush.face[4].texture,
490                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft ) );
491                         brush.face[4].Shift[0] = (float)TexOffset[0];
492                         brush.face[4].Shift[1] = (float)TexOffset[1];
493                         brush.face[4].Rotate   = 0.;
494                         brush.face[4].Scale[0] = (float)TexScale[0];
495                         brush.face[4].Scale[1] = (float)TexScale[1];
496                         brush.face[4].Contents = contents;
497                         brush.face[4].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf );
498                         brush.face[4].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2 );
499
500                         MakeBrush( &brush );
501                         if ( ( i + j ) % 2 ) {
502                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
503                                 switch ( Plane )
504                                 {
505                                 case PLANE_XY1:
506                                 case PLANE_XZ1:
507                                 case PLANE_YZ1:
508                                         VectorCopy( xyz[i  ][j  ].p,v[1].p );
509                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
510                                         break;
511                                 default:
512                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
513                                         VectorCopy( xyz[i  ][j  ].p,v[2].p );
514                                 }
515                         }
516                         else
517                         {
518                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
519                                 switch ( Plane )
520                                 {
521                                 case PLANE_XY1:
522                                 case PLANE_XZ1:
523                                 case PLANE_YZ1:
524                                         VectorCopy( xyz[i + 1][j  ].p,v[1].p );
525                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
526                                         break;
527                                 default:
528                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
529                                         VectorCopy( xyz[i + 1][j  ].p,v[2].p );
530                                 }
531                         }
532                         VectorCopy( v[0].p,v[3].p );
533                         VectorCopy( v[1].p,v[4].p );
534                         VectorCopy( v[2].p,v[5].p );
535                         switch ( Plane )
536                         {
537                         case PLANE_XZ0:
538                         case PLANE_XZ1:
539                                 v[0].p[1] = backface;
540                                 v[1].p[1] = backface;
541                                 v[2].p[1] = backface;
542                                 break;
543                         case PLANE_YZ0:
544                         case PLANE_YZ1:
545                                 v[3].p[0] = backface;
546                                 v[4].p[0] = backface;
547                                 v[5].p[0] = backface;
548                                 break;
549                         default:
550                                 v[3].p[2] = backface;
551                                 v[4].p[2] = backface;
552                                 v[5].p[2] = backface;
553                         }
554                         brush.Number   = i * NV * 2 + j * 2 + 1;
555                         brush.NumFaces = 5;
556                         XYZtoV( &v[0],&brush.face[0].v[0] );
557                         XYZtoV( &v[3],&brush.face[0].v[1] );
558                         XYZtoV( &v[4],&brush.face[0].v[2] );
559                         strcpy( brush.face[0].texture,
560                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
561                         brush.face[0].Shift[0] = (float)TexOffset[0];
562                         brush.face[0].Shift[1] = (float)TexOffset[1];
563                         brush.face[0].Rotate   = 0.;
564                         brush.face[0].Scale[0] = (float)TexScale[0];
565                         brush.face[0].Scale[1] = (float)TexScale[1];
566                         brush.face[0].Contents = contents;
567                         brush.face[0].Surface  = surface[1];
568                         brush.face[0].Value    = 0;
569
570                         XYZtoV( &v[1],&brush.face[1].v[0] );
571                         XYZtoV( &v[4],&brush.face[1].v[1] );
572                         XYZtoV( &v[5],&brush.face[1].v[2] );
573                         strcpy( brush.face[1].texture,
574                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
575                         brush.face[1].Shift[0] = (float)TexOffset[0];
576                         brush.face[1].Shift[1] = (float)TexOffset[1];
577                         brush.face[1].Rotate   = 0.;
578                         brush.face[1].Scale[0] = (float)TexScale[0];
579                         brush.face[1].Scale[1] = (float)TexScale[1];
580                         brush.face[1].Contents = contents;
581                         brush.face[1].Surface  = surface[1];
582                         brush.face[1].Value    = 0;
583
584                         XYZtoV( &v[2],&brush.face[2].v[0] );
585                         XYZtoV( &v[5],&brush.face[2].v[1] );
586                         XYZtoV( &v[3],&brush.face[2].v[2] );
587                         strcpy( brush.face[2].texture,
588                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
589                         brush.face[2].Shift[0] = (float)TexOffset[0];
590                         brush.face[2].Shift[1] = (float)TexOffset[1];
591                         brush.face[2].Rotate   = 0.;
592                         brush.face[2].Scale[0] = (float)TexScale[0];
593                         brush.face[2].Scale[1] = (float)TexScale[1];
594                         brush.face[2].Contents = contents;
595                         brush.face[2].Surface  = surface[1];
596                         brush.face[2].Value    = 0;
597
598                         if ( CheckAngle && ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ) ) {
599                                 XYZVectorSubtract( v[4].p,v[3].p,t[0] );
600                                 XYZVectorSubtract( v[5].p,v[4].p,t[1] );
601                                 CrossProduct( t[0],t[1],SurfNormal );
602                                 VectorNormalize( SurfNormal,SurfNormal );
603                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
604                                         strcpy( surft,surftext2 );
605                                         surf = surface[2];
606                                 }
607                                 else
608                                 {
609                                         strcpy( surft,surftext );
610                                         surf = surface[0];
611                                 }
612                         }
613                         else
614                         {
615                                 strcpy( surft,surftext );
616                                 surf = surface[0];
617                         }
618                         XYZtoV( &v[3],&brush.face[3].v[0] );
619                         XYZtoV( &v[5],&brush.face[3].v[1] );
620                         XYZtoV( &v[4],&brush.face[3].v[2] );
621                         strcpy( brush.face[3].texture,
622                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext ) );
623                         brush.face[3].Shift[0] = (float)TexOffset[0];
624                         brush.face[3].Shift[1] = (float)TexOffset[1];
625                         brush.face[3].Rotate   = 0.;
626                         brush.face[3].Scale[0] = (float)TexScale[0];
627                         brush.face[3].Scale[1] = (float)TexScale[1];
628                         brush.face[3].Contents = contents;
629                         brush.face[3].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1] );
630                         brush.face[3].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0 );
631
632                         if ( CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1 ) {
633                                 XYZVectorSubtract( v[2].p,v[0].p,t[0] );
634                                 XYZVectorSubtract( v[1].p,v[2].p,t[1] );
635                                 CrossProduct( t[0],t[1],SurfNormal );
636                                 VectorNormalize( SurfNormal,SurfNormal );
637                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
638                                         strcpy( surft,surftext2 );
639                                         surf = surface[2];
640                                 }
641                                 else
642                                 {
643                                         strcpy( surft,surftext );
644                                         surf = surface[0];
645                                 }
646                         }
647                         else
648                         {
649                                 strcpy( surft,surftext );
650                                 surf = surface[0];
651                         }
652                         XYZtoV( &v[0],&brush.face[4].v[0] );
653                         XYZtoV( &v[1],&brush.face[4].v[1] );
654                         XYZtoV( &v[2],&brush.face[4].v[2] );
655                         strcpy( brush.face[4].texture,
656                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft ) );
657                         brush.face[4].Shift[0] = (float)TexOffset[0];
658                         brush.face[4].Shift[1] = (float)TexOffset[1];
659                         brush.face[4].Rotate   = 0.;
660                         brush.face[4].Scale[0] = (float)TexScale[0];
661                         brush.face[4].Scale[1] = (float)TexScale[1];
662                         brush.face[4].Contents = contents;
663                         brush.face[4].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf );
664                         brush.face[4].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2 );
665
666                         MakeBrush( &brush );
667                 }
668         }
669         CloseFuncGroup();
670
671         if ( AddHints || GimpHints ) {
672                 int detail, i1, j1, N;
673                 double front;
674
675                 switch ( Game )
676                 {
677                 case HALFLIFE:
678                         strcpy( hint,"HINT" );
679                         strcpy( skip,"HINT" );
680                         break;
681                 case SIN:
682                         strcpy( hint,"generic/misc/hint" );
683                         strcpy( skip,"generic/misc/skip" );
684                         break;
685                 case HERETIC2:
686                         strcpy( hint,"general/hint" );
687                         strcpy( skip,"general/hint" ); // Heretic2 doesn't have a skip texture
688                         break;
689                 case KINGPIN:
690                         strcpy( hint,"common/0_hint" );
691                         strcpy( skip,"common/0_skip" );
692                         break;
693                 case GENESIS3D:
694                         strcpy( hint,"hint" );
695                         strcpy( skip,"hint" );
696                         break;
697                 case QUAKE3:
698                         strcpy( hint,"textures/common/hint" );
699                         strcpy( skip,"textures/common/skip" );
700                         break;
701                 default:
702                         strcpy( hint,"e1u1/hint" );
703                         strcpy( skip,"e1u1/skip" );
704                 }
705
706                 OpenFuncGroup();
707
708                 if ( AddHints == 1 ) {
709                         detail = CONTENTS_DETAIL;
710                         N = 0;
711                         for ( i = 0; i < NH; i++ )
712                         {
713                                 i1 = i + 1;
714
715                                 for ( j = 0; j < NV; j++ )
716                                 {
717
718                                         // For detail hint brushes, no need to use a hint brush over
719                                         // EVERY grid square... it would be redundant. Instead use
720                                         // a checkerboard pattern
721                                         if ( ( i + j ) % 2 ) {
722                                                 continue;
723                                         }
724
725                                         j1 = j + 1;
726
727                                         VectorCopy( xyz[i  ][j  ].p, v[0].p );
728                                         switch ( Plane )
729                                         {
730                                         case PLANE_XY1:
731                                         case PLANE_XZ1:
732                                         case PLANE_YZ1:
733                                                 VectorCopy( xyz[i1][j ].p, v[1].p );
734                                                 VectorCopy( xyz[i1][j1].p, v[2].p );
735                                                 VectorCopy( xyz[i ][j1].p, v[3].p );
736                                                 break;
737                                         default:
738                                                 VectorCopy( xyz[i ][j1].p, v[1].p );
739                                                 VectorCopy( xyz[i1][j1].p, v[2].p );
740                                                 VectorCopy( xyz[i1][j ].p, v[3].p );
741                                         }
742
743                                         VectorCopy( v[0].p,v[4].p );
744                                         VectorCopy( v[1].p,v[5].p );
745                                         VectorCopy( v[2].p,v[6].p );
746                                         VectorCopy( v[3].p,v[7].p );
747
748                                         switch ( Plane )
749                                         {
750                                         case PLANE_XY1:
751                                                 front  = LessThan( zmin,32. );
752                                                 v[4].p[2] = backface;
753                                                 v[5].p[2] = backface;
754                                                 v[6].p[2] = backface;
755                                                 v[7].p[2] = backface;
756                                                 break;
757                                         case PLANE_XZ0:
758                                                 front  = MoreThan( ymax,32. );
759                                                 v[0].p[1] = backface;
760                                                 v[1].p[1] = backface;
761                                                 v[2].p[1] = backface;
762                                                 v[3].p[1] = backface;
763                                                 break;
764                                         case PLANE_XZ1:
765                                                 front  = LessThan( ymin,32. );
766                                                 v[0].p[1] = backface;
767                                                 v[1].p[1] = backface;
768                                                 v[2].p[1] = backface;
769                                                 v[3].p[1] = backface;
770                                                 break;
771                                         case PLANE_YZ0:
772                                                 front  = MoreThan( xmax,32. );
773                                                 v[4].p[0] = backface;
774                                                 v[5].p[0] = backface;
775                                                 v[6].p[0] = backface;
776                                                 v[7].p[0] = backface;
777                                                 break;
778                                         case PLANE_YZ1:
779                                                 front  = LessThan( xmin,32. );
780                                                 v[4].p[0] = backface;
781                                                 v[5].p[0] = backface;
782                                                 v[6].p[0] = backface;
783                                                 v[7].p[0] = backface;
784                                                 break;
785                                         default:
786                                                 front  = MoreThan( zmax,32. );
787                                                 v[4].p[2] = backface;
788                                                 v[5].p[2] = backface;
789                                                 v[6].p[2] = backface;
790                                                 v[7].p[2] = backface;
791                                         }
792
793                                         switch ( Plane )
794                                         {
795                                         case PLANE_XZ0:
796                                         case PLANE_XZ1:
797                                                 v[4].p[1] = front;
798                                                 v[5].p[1] = v[4].p[1];
799                                                 v[6].p[1] = v[4].p[1];
800                                                 v[7].p[1] = v[4].p[1];
801                                                 break;
802                                         case PLANE_YZ0:
803                                         case PLANE_YZ1:
804                                                 v[0].p[0] = front;
805                                                 v[1].p[0] = v[0].p[0];
806                                                 v[2].p[0] = v[0].p[0];
807                                                 v[3].p[0] = v[0].p[0];
808                                                 break;
809                                         default:
810                                                 v[0].p[2] = front;
811                                                 v[1].p[2] = v[0].p[2];
812                                                 v[2].p[2] = v[0].p[2];
813                                                 v[3].p[2] = v[0].p[2];
814                                         }
815
816                                         brush.NumFaces = 6;
817                                         brush.Number   = N;
818                                         XYZtoV( &v[0],&brush.face[0].v[0] );
819                                         XYZtoV( &v[1],&brush.face[0].v[1] );
820                                         XYZtoV( &v[2],&brush.face[0].v[2] );
821                                         strcpy( brush.face[0].texture,skip );
822                                         brush.face[0].Shift[0] = 0.;
823                                         brush.face[0].Shift[1] = 0.;
824                                         brush.face[0].Rotate   = 0.;
825                                         brush.face[0].Scale[0] = 1.;
826                                         brush.face[0].Scale[1] = 1.;
827                                         brush.face[0].Contents = detail;
828                                         brush.face[0].Surface  = SURF_SKIP;
829                                         brush.face[0].Value    = 0;
830
831                                         XYZtoV( &v[4],&brush.face[1].v[0] );
832                                         XYZtoV( &v[7],&brush.face[1].v[1] );
833                                         XYZtoV( &v[6],&brush.face[1].v[2] );
834                                         strcpy( brush.face[1].texture,skip );
835                                         brush.face[1].Shift[0] = 0.;
836                                         brush.face[1].Shift[1] = 0.;
837                                         brush.face[1].Rotate   = 0.;
838                                         brush.face[1].Scale[0] = 1.;
839                                         brush.face[1].Scale[1] = 1.;
840                                         brush.face[1].Contents = detail;
841                                         brush.face[1].Surface  = SURF_SKIP;
842                                         brush.face[1].Value    = 0;
843
844                                         XYZtoV( &v[0],&brush.face[2].v[0] );
845                                         XYZtoV( &v[4],&brush.face[2].v[1] );
846                                         XYZtoV( &v[5],&brush.face[2].v[2] );
847                                         strcpy( brush.face[2].texture,hint );
848                                         brush.face[2].Shift[0] = 0.;
849                                         brush.face[2].Shift[1] = 0.;
850                                         brush.face[2].Rotate   = 0.;
851                                         brush.face[2].Scale[0] = 1.;
852                                         brush.face[2].Scale[1] = 1.;
853                                         brush.face[2].Contents = detail;
854                                         brush.face[2].Surface  = SURF_HINT;
855                                         brush.face[2].Value    = 0;
856
857                                         XYZtoV( &v[1],&brush.face[3].v[0] );
858                                         XYZtoV( &v[5],&brush.face[3].v[1] );
859                                         XYZtoV( &v[6],&brush.face[3].v[2] );
860                                         strcpy( brush.face[3].texture,hint );
861                                         brush.face[3].Shift[0] = 0.;
862                                         brush.face[3].Shift[1] = 0.;
863                                         brush.face[3].Rotate   = 0.;
864                                         brush.face[3].Scale[0] = 1.;
865                                         brush.face[3].Scale[1] = 1.;
866                                         brush.face[3].Contents = detail;
867                                         brush.face[3].Surface  = SURF_HINT;
868                                         brush.face[3].Value    = 0;
869
870                                         XYZtoV( &v[2],&brush.face[4].v[0] );
871                                         XYZtoV( &v[6],&brush.face[4].v[1] );
872                                         XYZtoV( &v[7],&brush.face[4].v[2] );
873                                         strcpy( brush.face[4].texture,hint );
874                                         brush.face[4].Shift[0] = 0.;
875                                         brush.face[4].Shift[1] = 0.;
876                                         brush.face[4].Rotate   = 0.;
877                                         brush.face[4].Scale[0] = 1.;
878                                         brush.face[4].Scale[1] = 1.;
879                                         brush.face[4].Contents = detail;
880                                         brush.face[4].Surface  = SURF_HINT;
881                                         brush.face[4].Value    = 0;
882
883                                         XYZtoV( &v[3],&brush.face[5].v[0] );
884                                         XYZtoV( &v[7],&brush.face[5].v[1] );
885                                         XYZtoV( &v[4],&brush.face[5].v[2] );
886                                         strcpy( brush.face[5].texture,hint );
887                                         brush.face[5].Shift[0] = 0.;
888                                         brush.face[5].Shift[1] = 0.;
889                                         brush.face[5].Rotate   = 0.;
890                                         brush.face[5].Scale[0] = 1.;
891                                         brush.face[5].Scale[1] = 1.;
892                                         brush.face[5].Contents = detail;
893                                         brush.face[5].Surface  = SURF_HINT;
894                                         brush.face[5].Value    = 0;
895
896                                         MakeBrush( &brush );
897                                         N++;
898                                 }
899                         }
900                 }
901                 if ( GimpHints ) {
902                         N = 0;
903                         // these brush parameters never change
904                         brush.NumFaces = 5;
905                         for ( i = 0; i < 6; i++ )
906                         {
907                                 strcpy( brush.face[i].texture,hint );
908                                 brush.face[i].Shift[0] = 0.;
909                                 brush.face[i].Shift[1] = 0.;
910                                 brush.face[i].Rotate   = 0.;
911                                 brush.face[i].Scale[0] = 1.;
912                                 brush.face[i].Scale[1] = 1.;
913                                 brush.face[i].Contents = 0;
914                                 brush.face[i].Surface  = SURF_HINT;
915                                 brush.face[i].Value    = 0;
916                         }
917                         for ( i = 0; i < NH; i++ )
918                         {
919                                 for ( j = 0; j < NV; j++ )
920                                 {
921                                         for ( k = 0; k < 2; k++ )
922                                         {
923                                                 if ( k == 0 ) {
924                                                         if ( ( i + j ) % 2 ) {
925                                                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
926                                                                 switch ( Plane )
927                                                                 {
928                                                                 case PLANE_XY1:
929                                                                 case PLANE_XZ1:
930                                                                 case PLANE_YZ1:
931                                                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
932                                                                         VectorCopy( xyz[i + 1][j + 1].p, v[2].p );
933                                                                         break;
934                                                                 default:
935                                                                         VectorCopy( xyz[i + 1][j + 1].p, v[1].p );
936                                                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
937                                                                 }
938                                                         }
939                                                         else
940                                                         {
941                                                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
942                                                                 switch ( Plane )
943                                                                 {
944                                                                 case PLANE_XY1:
945                                                                 case PLANE_XZ1:
946                                                                 case PLANE_YZ1:
947                                                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
948                                                                         VectorCopy( xyz[i  ][j + 1].p, v[2].p );
949                                                                         break;
950                                                                 default:
951                                                                         VectorCopy( xyz[i  ][j + 1].p, v[1].p );
952                                                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
953                                                                 }
954                                                         }
955                                                 }
956                                                 else
957                                                 {
958                                                         if ( ( i + j ) % 2 ) {
959                                                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
960                                                                 switch ( Plane )
961                                                                 {
962                                                                 case PLANE_XY1:
963                                                                 case PLANE_XZ1:
964                                                                 case PLANE_YZ1:
965                                                                         VectorCopy( xyz[i  ][j  ].p,v[1].p );
966                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
967                                                                         break;
968                                                                 default:
969                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
970                                                                         VectorCopy( xyz[i  ][j  ].p,v[2].p );
971                                                                 }
972                                                         }
973                                                         else
974                                                         {
975                                                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
976                                                                 switch ( Plane )
977                                                                 {
978                                                                 case PLANE_XY1:
979                                                                 case PLANE_XZ1:
980                                                                 case PLANE_YZ1:
981                                                                         VectorCopy( xyz[i + 1][j  ].p,v[1].p );
982                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
983                                                                         break;
984                                                                 default:
985                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
986                                                                         VectorCopy( xyz[i + 1][j  ].p,v[2].p );
987                                                                 }
988                                                         }
989                                                 }
990                                                 VectorCopy( v[0].p,v[3].p );
991                                                 VectorCopy( v[1].p,v[4].p );
992                                                 VectorCopy( v[2].p,v[5].p );
993                                                 switch ( Plane )
994                                                 {
995                                                 case PLANE_XY0:
996                                                         v[0].p[2] += HINT_OFFSET;
997                                                         v[1].p[2] += HINT_OFFSET;
998                                                         v[2].p[2] += HINT_OFFSET;
999 //              v[3].p[2] = backface;
1000 //              v[4].p[2] = backface;
1001 //              v[5].p[2] = backface;
1002                                                         break;
1003                                                 case PLANE_XY1:
1004                                                         v[0].p[2] -= HINT_OFFSET;
1005                                                         v[1].p[2] -= HINT_OFFSET;
1006                                                         v[2].p[2] -= HINT_OFFSET;
1007 //              v[3].p[2] = backface;
1008 //              v[4].p[2] = backface;
1009 //              v[5].p[2] = backface;
1010                                                         break;
1011                                                 case PLANE_XZ0:
1012 //              v[0].p[1] = backface;
1013 //              v[1].p[1] = backface;
1014 //              v[2].p[1] = backface;
1015                                                         v[3].p[1] += HINT_OFFSET;
1016                                                         v[4].p[1] += HINT_OFFSET;
1017                                                         v[5].p[1] += HINT_OFFSET;
1018                                                         break;
1019                                                 case PLANE_XZ1:
1020 //              v[0].p[1] = backface;
1021 //              v[1].p[1] = backface;
1022 //              v[2].p[1] = backface;
1023                                                         v[3].p[1] -= HINT_OFFSET;
1024                                                         v[4].p[1] -= HINT_OFFSET;
1025                                                         v[5].p[1] -= HINT_OFFSET;
1026                                                         break;
1027                                                 case PLANE_YZ0:
1028                                                         v[0].p[0] += HINT_OFFSET;
1029                                                         v[1].p[0] += HINT_OFFSET;
1030                                                         v[2].p[0] += HINT_OFFSET;
1031 //              v[3].p[0] = backface;
1032 //              v[4].p[0] = backface;
1033 //              v[5].p[0] = backface;
1034                                                         break;
1035                                                 case PLANE_YZ1:
1036                                                         v[0].p[0] -= HINT_OFFSET;
1037                                                         v[1].p[0] -= HINT_OFFSET;
1038                                                         v[2].p[0] -= HINT_OFFSET;
1039 //              v[3].p[0] = backface;
1040 //              v[4].p[0] = backface;
1041 //              v[5].p[0] = backface;
1042                                                         break;
1043                                                 }
1044                                                 brush.Number   = N;
1045                                                 XYZtoV( &v[0],&brush.face[0].v[0] );
1046                                                 XYZtoV( &v[3],&brush.face[0].v[1] );
1047                                                 XYZtoV( &v[4],&brush.face[0].v[2] );
1048
1049                                                 XYZtoV( &v[1],&brush.face[1].v[0] );
1050                                                 XYZtoV( &v[4],&brush.face[1].v[1] );
1051                                                 XYZtoV( &v[5],&brush.face[1].v[2] );
1052
1053                                                 XYZtoV( &v[2],&brush.face[2].v[0] );
1054                                                 XYZtoV( &v[5],&brush.face[2].v[1] );
1055                                                 XYZtoV( &v[3],&brush.face[2].v[2] );
1056
1057                                                 XYZtoV( &v[3],&brush.face[3].v[0] );
1058                                                 XYZtoV( &v[5],&brush.face[3].v[1] );
1059                                                 XYZtoV( &v[4],&brush.face[3].v[2] );
1060
1061                                                 XYZtoV( &v[0],&brush.face[4].v[0] );
1062                                                 XYZtoV( &v[1],&brush.face[4].v[1] );
1063                                                 XYZtoV( &v[2],&brush.face[4].v[2] );
1064
1065                                                 MakeBrush( &brush );
1066                                                 N++;
1067                                         }
1068                                 }
1069                         }
1070                 } // endif AddHints==1
1071                 CloseFuncGroup();
1072         }
1073
1074 } // end MapBrushes
1075
1076 //=============================================================
1077 void GenerateMap(){
1078         extern void MapOut( int,int,NODE *,TRI * );
1079         extern bool SingleBrushSelected;
1080         int ntri;
1081
1082         if ( !ValidSurface() ) {
1083                 return;
1084         }
1085         /*
1086            ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
1087            SetCursor(ghCursorCurrent);
1088          */
1089 #if 0
1090         if ( SingleBrushSelected ) {
1091                 g_FuncTable.m_pfnDeleteSelection();
1092         }
1093 #endif
1094
1095         GenerateXYZ();
1096         ntri = NH * NV * 2;
1097
1098         if ( Game == QUAKE3 && UsePatches != 0 ) {
1099                 MapPatches();
1100         }
1101
1102         if ( Decimate > 0 && ( Game != QUAKE3 || UsePatches == 0 ) ) {
1103                 MapOut( gNumNodes,gNumTris,gNode,gTri );
1104                 /*
1105                    ghCursorCurrent = ghCursorDefault;
1106                    SetCursor(ghCursorCurrent);
1107                  */
1108                 return;
1109         }
1110
1111         contents = 0;
1112         // HL doesn't have detail property
1113         if ( ( Game != HALFLIFE ) && UseDetail ) {
1114                 contents += CONTENTS_DETAIL;
1115         }
1116         // HL and Q3 don't have ladder property
1117         if ( ( Game != HALFLIFE && Game != QUAKE3 ) && UseLadder ) {
1118                 contents += CONTENTS_LADDER;
1119         }
1120         // Genesis requires solid property to be set explicitly
1121         if ( Game == GENESIS3D ) {
1122                 contents |= CONTENTS_SOLID;
1123         }
1124         // Heretic 2 uses different sounds (in surface props) for different texture types
1125         if ( Game == HERETIC2 ) {
1126                 surface[0] = GetDefSurfaceProps( Texture[Game][0] );
1127                 surface[1] = GetDefSurfaceProps( Texture[Game][1] );
1128                 surface[2] = GetDefSurfaceProps( Texture[Game][2] );
1129         }
1130         else
1131         {
1132                 surface[0] = 0;
1133                 surface[1] = 0;
1134                 surface[2] = 0;
1135         }
1136         if ( Game != QUAKE3 || UsePatches == 0 ) {
1137                 MapBrushes();
1138         }
1139
1140         /*
1141            ghCursorCurrent = ghCursorDefault;
1142            SetCursor(ghCursorCurrent);
1143          */
1144 }
1145
1146 //=============================================================
1147 void GenerateXYZ(){
1148         extern void MakeDecimatedMap( int *, int *, NODE * *, TRI * * );
1149         double zl, zu;
1150         double wh, wv;
1151         int NHalfcycles;
1152         double a,v,h,ha,va;
1153         double delta, dr, rate;
1154         double range, maxrange;
1155         double r;
1156         int i, j, k, N;
1157         int i0, i1, j0, j1;
1158         int ii, jj;
1159
1160 //  FILE *f;
1161 //  char CSV[64];
1162
1163         if ( !ValidSurface() ) {
1164                 return;
1165         }
1166
1167         srand( 1 );
1168         srand( RandomSeed );
1169
1170         dh = ( Hur - Hll ) / NH;
1171         dv = ( Vur - Vll ) / NV;
1172
1173         // H & V
1174         for ( i = 0; i <= NH; i++ )
1175         {
1176                 for ( j = 0; j <= NV; j++ )
1177                 {
1178                         switch ( Plane )
1179                         {
1180                         case PLANE_XZ0:
1181                         case PLANE_XZ1:
1182                                 xyz[i][j].p[0] = Hll + i * dh;
1183                                 xyz[i][j].p[2] = Vll + j * dv;
1184                                 break;
1185                         case PLANE_YZ0:
1186                         case PLANE_YZ1:
1187                                 xyz[i][j].p[1] = Hll + i * dh;
1188                                 xyz[i][j].p[2] = Vll + j * dv;
1189                                 break;
1190                         default:
1191                                 xyz[i][j].p[0] = Hll + i * dh;
1192                                 xyz[i][j].p[1] = Vll + j * dv;
1193                         }
1194                 }
1195         }
1196
1197         if ( WaveType == WAVE_BITMAP ) {
1198                 GenerateBitmapMapping();
1199         }
1200         /*
1201            else if(WaveType == WAVE_FORMULA)
1202            DoFormula();
1203          */
1204         else
1205         {
1206                 // Initialize Z values using bilinear interpolation
1207                 for ( i = 0; i <= NH; i++ )
1208                 {
1209                         zl = Z00 + i * ( Z10 - Z00 ) / NH;
1210                         zu = Z01 + i * ( Z11 - Z01 ) / NH;
1211                         switch ( Plane )
1212                         {
1213                         case PLANE_XZ0:
1214                         case PLANE_XZ1:
1215                                 for ( j = 0; j <= NV; j++ )
1216                                         xyz[i][j].p[1] = zl + j * ( zu - zl ) / NV;
1217                                 break;
1218                         case PLANE_YZ0:
1219                         case PLANE_YZ1:
1220                                 for ( j = 0; j <= NV; j++ )
1221                                         xyz[i][j].p[0] = zl + j * ( zu - zl ) / NV;
1222                                 break;
1223                         default:
1224                                 for ( j = 0; j <= NV; j++ )
1225                                         xyz[i][j].p[2] = zl + j * ( zu - zl ) / NV;
1226                         }
1227                 }
1228         }
1229
1230         switch ( WaveType )
1231         {
1232         case WAVE_COS_SIN:
1233                 if ( FixBorders ) {
1234                         NHalfcycles = (int)( ( Hur - Hll ) / ( WaveLength / 2. ) );
1235                         NHalfcycles = max( NHalfcycles,1 );
1236                         wh = 2. * ( Hur - Hll ) / NHalfcycles;
1237                         NHalfcycles = (int)( ( Vur - Vll ) / ( WaveLength / 2. ) );
1238                         wv = 2. * ( Vur - Vll ) / NHalfcycles;
1239                         NHalfcycles = max( NHalfcycles,1 );
1240                         i0 = 1;
1241                         i1 = NH - 1;
1242                         j0 = 1;
1243                         j1 = NV - 1;
1244                 }
1245                 else
1246                 {
1247                         wh = WaveLength;
1248                         wv = WaveLength;
1249                         i0 = 0;
1250                         i1 = NH;
1251                         j0 = 0;
1252                         j1 = NV;
1253                 }
1254
1255                 for ( i = i0; i <= i1; i++ )
1256                 {
1257                         h  = Hll + i * dh;
1258                         ha = ( ( h - Hll ) / wh ) * 2. * PI - PI / 2.;
1259                         for ( j = j0; j <= j1; j++ )
1260                         {
1261                                 v  = Vll + j * dv;
1262                                 va = ( ( v - Vll ) / wv ) * 2. * PI;
1263                                 a = Amplitude * cos( ha ) * sin( va );
1264                                 switch ( Plane )
1265                                 {
1266                                 case PLANE_XY1:
1267                                         xyz[i][j].p[2] -= a;
1268                                         break;
1269                                 case PLANE_XZ0:
1270                                         xyz[i][j].p[1] += a;
1271                                         break;
1272                                 case PLANE_XZ1:
1273                                         xyz[i][j].p[1] -= a;
1274                                         break;
1275                                 case PLANE_YZ0:
1276                                         xyz[i][j].p[0] += a;
1277                                         break;
1278                                 case PLANE_YZ1:
1279                                         xyz[i][j].p[0] -= a;
1280                                         break;
1281                                 default:
1282                                         xyz[i][j].p[2] += a;
1283                                 }
1284                         }
1285                 }
1286                 break;
1287         case WAVE_HCYLINDER:
1288                 for ( i = 0; i <= NH; i++ )
1289                 {
1290                         h  = Hll + i * dh;
1291                         ha = ( ( h - Hll ) / WaveLength ) * 2. * PI - PI / 2.;
1292                         for ( j = 0; j <= NV; j++ )
1293                         {
1294                                 a = Amplitude * cos( ha );
1295                                 switch ( Plane )
1296                                 {
1297                                 case PLANE_XY1:
1298                                         xyz[i][j].p[2] -= a;
1299                                         break;
1300                                 case PLANE_XZ0:
1301                                         xyz[i][j].p[1] += a;
1302                                         break;
1303                                 case PLANE_XZ1:
1304                                         xyz[i][j].p[1] -= a;
1305                                         break;
1306                                 case PLANE_YZ0:
1307                                         xyz[i][j].p[0] += a;
1308                                         break;
1309                                 case PLANE_YZ1:
1310                                         xyz[i][j].p[0] -= a;
1311                                         break;
1312                                 default:
1313                                         xyz[i][j].p[2] += a;
1314                                 }
1315                         }
1316                 }
1317                 break;
1318         case WAVE_VCYLINDER:
1319                 for ( i = 0; i <= NH; i++ )
1320                 {
1321                         h  = Hll + i * dh;
1322                         for ( j = 0; j <= NV; j++ )
1323                         {
1324                                 v  = Vll + j * dv;
1325                                 va = ( ( v - Vll ) / WaveLength ) * 2. * PI;
1326                                 a = Amplitude * sin( va );
1327                                 switch ( Plane )
1328                                 {
1329                                 case PLANE_XY1:
1330                                         xyz[i][j].p[2] -= a;
1331                                         break;
1332                                 case PLANE_XZ0:
1333                                         xyz[i][j].p[1] += a;
1334                                         break;
1335                                 case PLANE_XZ1:
1336                                         xyz[i][j].p[1] -= a;
1337                                         break;
1338                                 case PLANE_YZ0:
1339                                         xyz[i][j].p[0] += a;
1340                                         break;
1341                                 case PLANE_YZ1:
1342                                         xyz[i][j].p[0] -= a;
1343                                         break;
1344                                 default:
1345                                         xyz[i][j].p[2] += a;
1346                                 }
1347                         }
1348                 }
1349                 break;
1350         case WAVE_ROUGH_ONLY:
1351                 PlasmaCloud();
1352                 break;
1353         }
1354
1355         if ( WaveType != WAVE_ROUGH_ONLY ) {
1356                 // Fixed values
1357                 for ( i = 0; i <= NH; i++ )
1358                 {
1359                         for ( j = 0; j <= NV; j++ )
1360                         {
1361                                 if ( xyz[i][j].fixed ) {
1362                                         switch ( Plane )
1363                                         {
1364                                         case PLANE_XZ0:
1365                                         case PLANE_XZ1:
1366                                                 xyz[i][j].p[1] = xyz[i][j].fixed_value;
1367                                                 break;
1368                                         case PLANE_YZ0:
1369                                         case PLANE_YZ1:
1370                                                 xyz[i][j].p[0] = xyz[i][j].fixed_value;
1371                                                 break;
1372                                         default:
1373                                                 xyz[i][j].p[2] = xyz[i][j].fixed_value;
1374                                         }
1375
1376                                         if ( xyz[i][j].range > 0 ) {
1377                                                 maxrange = pow( xyz[i][j].range,2 ); // so we don't have to do sqrt's
1378                                                 i0 = i - (int)( floor( xyz[i][j].range / dh - 0.5 ) + 1 );
1379                                                 i1 = i + i - i0;
1380                                                 j0 = j - (int)( floor( xyz[i][j].range / dv - 0.5 ) + 1 );
1381                                                 j1 = j + j - j0;
1382                                                 if ( FixBorders ) {
1383                                                         i0 = max( i0,1 );
1384                                                         i1 = min( i1,NH - 1 );
1385                                                         j0 = max( j0,1 );
1386                                                         j1 = min( j1,NV - 1 );
1387                                                 }
1388                                                 else
1389                                                 {
1390                                                         i0 = max( i0,0 );
1391                                                         i1 = min( i1,NH );
1392                                                         j0 = max( j0,0 );
1393                                                         j1 = min( j1,NV );
1394                                                 }
1395                                                 for ( ii = i0; ii <= i1; ii++ )
1396                                                 {
1397                                                         for ( jj = j0; jj <= j1; jj++ )
1398                                                         {
1399                                                                 if ( ii == i && jj == j ) {
1400                                                                         continue;
1401                                                                 }
1402                                                                 range = pow( dh * ( i - ii ), 2 ) + pow( dv * ( j - jj ), 2 );
1403                                                                 if ( range > maxrange ) {
1404                                                                         continue;
1405                                                                 }
1406                                                                 dr = sqrt( range / maxrange );
1407                                                                 rate = max( -30.,min( xyz[i][j].rate,30. ) );
1408                                                                 if ( rate < -1. ) {
1409                                                                         delta = pow( ( 1. - dr ),-rate + 1. );
1410                                                                 }
1411                                                                 else if ( rate < 0. ) {
1412                                                                         delta = ( 1 + rate ) * 0.5 * ( cos( dr * PI ) + 1.0 ) -
1413                                                                                         rate*pow( ( 1. - dr ),2 );
1414                                                                 }
1415                                                                 else if ( rate == 0. ) {
1416                                                                         delta = 0.5 * ( cos( dr * PI ) + 1.0 );
1417                                                                 }
1418                                                                 else if ( rate <= 1. ) {
1419                                                                         delta = ( 1. - rate ) * 0.5 * ( cos( dr * PI ) + 1.0 ) +
1420                                                                                         rate * ( 1. - pow( dr,2 ) );
1421                                                                 }
1422                                                                 else
1423                                                                 {
1424                                                                         delta = 1. - pow( dr,rate + 1 );
1425                                                                 }
1426                                                                 switch ( Plane )
1427                                                                 {
1428                                                                 case PLANE_XZ0:
1429                                                                 case PLANE_XZ1:
1430                                                                         xyz[ii][jj].p[1] += ( xyz[i][j].p[1] - xyz[ii][jj].p[1] ) * delta;
1431                                                                         break;
1432                                                                 case PLANE_YZ0:
1433                                                                 case PLANE_YZ1:
1434                                                                         xyz[ii][jj].p[0] += ( xyz[i][j].p[0] - xyz[ii][jj].p[0] ) * delta;
1435                                                                         break;
1436                                                                 default:
1437                                                                         xyz[ii][jj].p[2] += ( xyz[i][j].p[2] - xyz[ii][jj].p[2] ) * delta;
1438                                                                 }
1439                                                         }
1440                                                 }
1441                                         }
1442                                 }
1443                         }
1444                 }
1445         }
1446
1447         if ( ( Roughness > 0. ) && ( WaveType != WAVE_ROUGH_ONLY ) ) {
1448                 for ( i = 0; i <= NH; i++ )
1449                 {
1450                         for ( j = 0; j <= NV; j++ )
1451                         {
1452                                 if ( CanEdit( i,j ) && !xyz[i][j].fixed ) {
1453                                         switch ( Plane )
1454                                         {
1455                                         case PLANE_XZ0:
1456                                         case PLANE_XZ1:
1457                                                 xyz[i][j].p[1] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1458                                                 break;
1459                                         case PLANE_YZ0:
1460                                         case PLANE_YZ1:
1461                                                 xyz[i][j].p[0] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1462                                                 break;
1463                                         default:
1464                                                 xyz[i][j].p[2] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1465                                         }
1466                                 }
1467                                 else{
1468                                         r = rand(); // We still get a random number, so that fixing points
1469                                 }
1470                                 // doesn't change the sequence.
1471
1472                         }
1473                 }
1474         }
1475
1476         for ( i = 0; i <= NH; i++ )
1477         {
1478                 for ( j = 0; j <= NV; j++ )
1479                 {
1480                         for ( k = 0; k < 3; k++ )
1481                         {
1482                                 xyz[i][j].p[k] = Nearest( xyz[i][j].p[k],2.0 );
1483                         }
1484                 }
1485         }
1486
1487         // Find minima and maxima
1488         switch ( Plane )
1489         {
1490         case PLANE_XZ0:
1491         case PLANE_XZ1:
1492                 xmin = Hll;
1493                 xmax = Hur;
1494                 zmin = Vll;
1495                 zmax = Vur;
1496                 ymin = xyz[0][0].p[1];
1497                 ymax = ymin;
1498                 for ( i = 0; i <= NH; i++ )
1499                 {
1500                         for ( j = 0; j <= NV; j++ )
1501                         {
1502                                 ymin = min( ymin,xyz[i][j].p[1] );
1503                                 ymax = max( ymax,xyz[i][j].p[1] );
1504                         }
1505                 }
1506                 break;
1507         case PLANE_YZ0:
1508         case PLANE_YZ1:
1509                 ymin = Hll;
1510                 ymax = Hur;
1511                 zmin = Vll;
1512                 zmax = Vur;
1513                 xmin = xyz[0][0].p[0];
1514                 xmax = ymin;
1515                 for ( i = 0; i <= NH; i++ )
1516                 {
1517                         for ( j = 0; j <= NV; j++ )
1518                         {
1519                                 xmin = min( xmin,xyz[i][j].p[0] );
1520                                 xmax = max( xmax,xyz[i][j].p[0] );
1521                         }
1522                 }
1523                 break;
1524                 break;
1525         default:
1526                 xmin = Hll;
1527                 xmax = Hur;
1528                 ymin = Vll;
1529                 ymax = Vur;
1530                 zmin = xyz[0][0].p[2];
1531                 zmax = zmin;
1532                 for ( i = 0; i <= NH; i++ )
1533                 {
1534                         for ( j = 0; j <= NV; j++ )
1535                         {
1536                                 zmin = min( zmin,xyz[i][j].p[2] );
1537                                 zmax = max( zmax,xyz[i][j].p[2] );
1538                         }
1539                 }
1540         }
1541
1542         xmin = Nearest( xmin,2. );
1543         xmax = Nearest( xmax,2. );
1544         ymin = Nearest( ymin,2. );
1545         ymax = Nearest( ymax,2. );
1546         zmin = Nearest( zmin,2. );
1547         zmax = Nearest( zmax,2. );
1548
1549         switch ( Plane )
1550         {
1551         case PLANE_XY1:
1552                 backface = AtLeast( zmax + 32.,32. );
1553                 break;
1554         case PLANE_XZ0:
1555                 backface = NoMoreThan( ymin - 32.,32. );
1556                 break;
1557         case PLANE_XZ1:
1558                 backface = AtLeast( ymax + 32.,32. );
1559                 break;
1560         case PLANE_YZ0:
1561                 backface = NoMoreThan( xmin - 32.,32. );
1562                 break;
1563         case PLANE_YZ1:
1564                 backface = AtLeast( xmax + 32.,32. );
1565                 break;
1566         default:
1567                 backface = NoMoreThan( zmin - 32.,32. );
1568         }
1569
1570         if ( gNode ) {
1571                 free( gNode );
1572                 free( gTri );
1573                 gNode = (NODE *)NULL;
1574                 gTri  = (TRI *)NULL;
1575         }
1576         if ( Decimate > 0 && ( Game != QUAKE3 || UsePatches == 0 ) ) {
1577                 MakeDecimatedMap( &gNumNodes,&gNumTris,&gNode,&gTri );
1578         }
1579         else
1580         {
1581                 gNumNodes = ( NH + 1 ) * ( NV + 1 );
1582                 gNumTris  = NH * NV * 2;
1583                 gNode = (NODE *) malloc( gNumNodes * sizeof( NODE ) );
1584                 gTri = (TRI *) malloc( gNumTris * sizeof( TRI ) );
1585
1586                 for ( i = 0,N = 0; i <= NH; i++ )
1587                 {
1588                         for ( j = 0; j <= NV; j++, N++ )
1589                         {
1590                                 gNode[N].used = 1;
1591                                 gNode[N].p[0] = (float)xyz[i][j].p[0];
1592                                 gNode[N].p[1] = (float)xyz[i][j].p[1];
1593                                 gNode[N].p[2] = (float)xyz[i][j].p[2];
1594                         }
1595                 }
1596
1597                 for ( i = 0; i < NH; i++ )
1598                 {
1599                         for ( j = 0; j < NV; j++ )
1600                         {
1601                                 k = i * NV * 2 + j * 2;
1602                                 if ( ( i + j ) % 2 ) {
1603                                         switch ( Plane )
1604                                         {
1605                                         case PLANE_XY1:
1606                                         case PLANE_XZ1:
1607                                         case PLANE_YZ1:
1608                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1609                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1610                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j;
1611                                                 gTri[k + 1].v[0] = i * ( NV + 1 ) + j;
1612                                                 gTri[k + 1].v[1] = i * ( NV + 1 ) + j + 1;
1613                                                 gTri[k + 1].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1614                                                 break;
1615                                         default:
1616                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1617                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j;
1618                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1619                                                 gTri[k + 1].v[0] = i * ( NV + 1 ) + j;
1620                                                 gTri[k + 1].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1621                                                 gTri[k + 1].v[2] = i * ( NV + 1 ) + j + 1;
1622                                         }
1623                                 }
1624                                 else
1625                                 {
1626                                         switch ( Plane )
1627                                         {
1628                                         case PLANE_XY1:
1629                                         case PLANE_XZ1:
1630                                         case PLANE_YZ1:
1631                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1632                                                 gTri[k  ].v[1] = i * ( NV + 1 ) + j + 1;
1633                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j;
1634                                                 gTri[k + 1].v[0] = ( i + 1 ) * ( NV + 1 ) + j;
1635                                                 gTri[k + 1].v[1] = i * ( NV + 1 ) + j + 1;
1636                                                 gTri[k + 1].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1637                                                 break;
1638                                         default:
1639                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1640                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j;
1641                                                 gTri[k  ].v[2] = i * ( NV + 1 ) + j + 1;
1642                                                 gTri[k + 1].v[0] = ( i + 1 ) * ( NV + 1 ) + j;
1643                                                 gTri[k + 1].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1644                                                 gTri[k + 1].v[2] = i * ( NV + 1 ) + j + 1;
1645                                         }
1646                                 }
1647                         }
1648                 }
1649         }
1650 /*
1651    sprintf(CSV,"csv%03d.csv",Decimate);
1652    f = fopen(CSV,"w");
1653    for(i=0; i<gNumNodes; i++)
1654    {
1655     if(gNode[i].used)
1656       fprintf(f,"%g,%g,%g\n",gNode[i].p[0],gNode[i].p[1],gNode[i].p[2]);
1657    }
1658    fclose(f);
1659  */
1660         for ( i = 0; i < gNumTris; i++ )
1661                 PlaneFromPoints( gNode[gTri[i].v[0]].p,
1662                                                  gNode[gTri[i].v[1]].p,
1663                                                  gNode[gTri[i].v[2]].p,
1664                                                  &gTri[i].plane );
1665
1666         // Hydra: snap-to-grid begin
1667         if ( SnapToGrid > 0 ) {
1668                 for ( i = 0; i < NH; i++ )
1669                 {
1670                         for ( j = 0; j < NV; j++ )
1671                         {
1672                                 switch ( Plane )
1673                                 {
1674                                 case PLANE_XZ0:
1675                                 case PLANE_XZ1:
1676                                         xyz[i][j].p[1] = CalculateSnapValue( xyz[i][j].p[1] );
1677                                         break;
1678                                 case PLANE_YZ0:
1679                                 case PLANE_YZ1:
1680                                         xyz[i][j].p[0] = CalculateSnapValue( xyz[i][j].p[0] );
1681                                         break;
1682                                 default:
1683                                         xyz[i][j].p[2] = CalculateSnapValue( xyz[i][j].p[2] );
1684                                 }
1685                         }
1686                 }
1687         }
1688         // Hydra: snap-to-grid end
1689 }
1690 //=============================================================
1691 double Nearest( double x, double dx ){
1692         double xx;
1693
1694         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1695         if ( fabs( xx ) < dx / 2 ) {
1696                 xx = 0.;
1697         }
1698         return xx;
1699 }
1700 //=============================================================
1701 double NoMoreThan( double x, double dx ){
1702         double xx;
1703
1704         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1705         if ( xx > x ) {
1706                 xx -= dx;
1707         }
1708         return xx;
1709 }
1710 //=============================================================
1711 double AtLeast( double x, double dx ){
1712         double xx;
1713
1714         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1715         if ( xx < x ) {
1716                 xx += dx;
1717         }
1718         return xx;
1719 }
1720 //=============================================================
1721 double LessThan( double x,double dx ){
1722         double xx;
1723
1724         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1725         if ( xx >= x ) {
1726                 xx -= dx;
1727         }
1728         return xx;
1729 }
1730 //=============================================================
1731 double MoreThan( double x,double dx ){
1732         double xx;
1733
1734         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1735         while ( xx <= x )
1736                 xx += dx;
1737         return xx;
1738 }
1739 //=============================================================
1740 void SubdividePlasma( int i0,int j0,int i1,int j1 ){
1741         int i, j;
1742         double z1, z2;
1743         double r;    // NOTE: This is used to keep the random number sequence the same
1744                      //       when we fix a point. If we did NOT do this, then simply
1745                      //       fixing a point at its current value would change the entire
1746                      //       surface.
1747
1748         i = ( i0 + i1 ) / 2;
1749         j = ( j0 + j1 ) / 2;
1750         if ( i1 > i0 + 1 ) {
1751                 if ( !xyz[i][j0].done ) {
1752                         xyz[i][j0].pp[2] = xyz[i0][j0].pp[2] +
1753                                                            ( xyz[i1][j0].pp[2] - xyz[i0][j0].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 ) +
1754                                                            ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1755                         xyz[i][j0].done = 1;
1756                 }
1757                 else{
1758                         r = rand();
1759                 }
1760                 if ( ( j1 > j0 ) && ( !xyz[i][j1].done ) ) {
1761                         xyz[i][j1].pp[2] = xyz[i0][j1].pp[2] +
1762                                                            ( xyz[i1][j1].pp[2] - xyz[i0][j1].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 ) +
1763                                                            ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1764                         xyz[i][j1].done = 1;
1765                 }
1766                 else{
1767                         r = rand();
1768                 }
1769         }
1770         if ( j1 > j0 + 1 ) {
1771                 if ( !xyz[i0][j].done ) {
1772                         xyz[i0][j].pp[2] = xyz[i0][j0].pp[2] +
1773                                                            ( xyz[i0][j1].pp[2] - xyz[i0][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 ) +
1774                                                            ( (double)( j - j0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1775                         xyz[i0][j].done = 1;
1776                 }
1777                 else{
1778                         r = rand();
1779                 }
1780                 if ( ( i1 > i0 ) && ( !xyz[i1][j].done ) ) {
1781                         xyz[i1][j].pp[2] = xyz[i1][j0].pp[2] +
1782                                                            ( xyz[i1][j1].pp[2] - xyz[i1][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 ) +
1783                                                            ( (double)( j - j0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1784                         xyz[i1][j].done = 1;
1785                 }
1786                 else{
1787                         r = rand();
1788                 }
1789         }
1790         if ( ( i1 > i0 + 1 ) && ( j1 > j0 + 1 ) ) {
1791                 if ( !xyz[i][j].done ) {
1792                         z1 = xyz[i0][j].pp[2] +
1793                                  ( xyz[i1][j].pp[2] - xyz[i0][j].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 );
1794                         z2 = xyz[i][j0].pp[2] +
1795                                  ( xyz[i][j1].pp[2] - xyz[i][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 );
1796                         xyz[i][j].pp[2] = ( z1 + z2 ) / 2. +
1797                                                           ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1798                         xyz[i][j].done = 1;
1799                 }
1800                 else{
1801                         r = rand();
1802                 }
1803         }
1804         if ( i > i0 + 1 || j > j0 + 1 ) {
1805                 SubdividePlasma( i0,j0,i,j );
1806         }
1807         if ( i1 > i + 1 || j > j0 + 1 ) {
1808                 SubdividePlasma( i,j0,i1,j );
1809         }
1810         if ( i > i0 + 1 || j1 > j0 + 1 ) {
1811                 SubdividePlasma( i0,j,i,j1 );
1812         }
1813         if ( i1 > i + 1 || j1 > j0 + 1 ) {
1814                 SubdividePlasma( i,j,i1,j1 );
1815         }
1816 }
1817 //==================================================================================
1818 void PlasmaCloud(){
1819         int i, j;
1820         /* use pp[2] values until done to avoid messing with a bunch of
1821            switch statements */
1822
1823         for ( i = 0; i <= NH; i++ )
1824         {
1825                 for ( j = 0; j <= NV; j++ )
1826                 {
1827                         if ( FixedPoint( i,j ) ) {
1828                                 xyz[i][j].done = 1;
1829                         }
1830                         else{
1831                                 xyz[i][j].done = 0;
1832                         }
1833                 }
1834         }
1835
1836         switch ( Plane )
1837         {
1838         case PLANE_XZ0:
1839         case PLANE_XZ1:
1840                 for ( i = 0; i <= NH; i++ )
1841                 {
1842                         for ( j = 0; j <= NV; j++ )
1843                         {
1844                                 if ( xyz[i][j].fixed ) {
1845                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1846                                 }
1847                                 else{
1848                                         xyz[i][j].pp[2] = xyz[i][j].p[1];
1849                                 }
1850                         }
1851                 }
1852                 break;
1853         case PLANE_YZ0:
1854         case PLANE_YZ1:
1855                 for ( i = 0; i <= NH; i++ )
1856                 {
1857                         for ( j = 0; j <= NV; j++ )
1858                         {
1859                                 if ( xyz[i][j].fixed ) {
1860                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1861                                 }
1862                                 else{
1863                                         xyz[i][j].pp[2] = xyz[i][j].p[0];
1864                                 }
1865                         }
1866                 }
1867                 break;
1868         default:
1869                 for ( i = 0; i <= NH; i++ )
1870                 {
1871                         for ( j = 0; j <= NV; j++ )
1872                         {
1873                                 if ( xyz[i][j].fixed ) {
1874                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1875                                 }
1876                                 else{
1877                                         xyz[i][j].pp[2] = xyz[i][j].p[2];
1878                                 }
1879                         }
1880                 }
1881                 break;
1882         }
1883         SubdividePlasma( 0,0,NH,NV );
1884         switch ( Plane )
1885         {
1886         case PLANE_XZ0:
1887         case PLANE_XZ1:
1888                 for ( i = 0; i <= NH; i++ )
1889                 {
1890                         for ( j = 0; j <= NV; j++ )
1891                         {
1892                                 xyz[i][j].p[1] = xyz[i][j].pp[2];
1893                         }
1894                 }
1895                 break;
1896         case PLANE_YZ0:
1897         case PLANE_YZ1:
1898                 for ( i = 0; i <= NH; i++ )
1899                 {
1900                         for ( j = 0; j <= NV; j++ )
1901                         {
1902                                 xyz[i][j].p[0] = xyz[i][j].pp[2];
1903                         }
1904                 }
1905                 break;
1906         default:
1907                 for ( i = 0; i <= NH; i++ )
1908                 {
1909                         for ( j = 0; j <= NV; j++ )
1910                         {
1911                                 xyz[i][j].p[2] = xyz[i][j].pp[2];
1912                         }
1913                 }
1914                 break;
1915         }
1916 }
1917 //===========================================================================
1918 bool FixedPoint( int i, int j ){
1919         if ( xyz[i][j].fixed ) {
1920                 return TRUE;
1921         }
1922         return !CanEdit( i,j );
1923 }
1924 //===========================================================================
1925 bool CanEdit( int i, int j ){
1926         if ( FixBorders && ( ( WaveType == WAVE_COS_SIN ) || ( WaveType == WAVE_ROUGH_ONLY ) ) ) {
1927                 if ( i == 0 ) {
1928                         return FALSE;
1929                 }
1930                 if ( i == NH ) {
1931                         return FALSE;
1932                 }
1933                 if ( j == 0 ) {
1934                         return FALSE;
1935                 }
1936                 if ( j == NV ) {
1937                         return FALSE;
1938                 }
1939         }
1940         if ( i == 0 && j == 0 ) {
1941                 return FALSE;
1942         }
1943         if ( i == NH && j == 0 ) {
1944                 return FALSE;
1945         }
1946         if ( i == 0 && j == NV ) {
1947                 return FALSE;
1948         }
1949         if ( i == NH && j == NV ) {
1950                 return FALSE;
1951         }
1952         return TRUE;
1953 }
1954 /*============================================================================
1955    TriangleFromPoint
1956    Determines which triangle in the gTri array bounds the input point. Doesn't
1957    do anything special with border points.
1958  */
1959 int TriangleFromPoint( double x, double y ){
1960         int j, tri;
1961
1962         if ( !gTri ) {
1963                 return -1;
1964         }
1965
1966         for ( j = 0, tri = -1; j < gNumTris && tri == -1; j++ )
1967         {
1968                 if ( side( x,y,
1969                                    gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1],
1970                                    gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1] ) < 0. ) {
1971                         continue;
1972                 }
1973                 if ( side( x,y,
1974                                    gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1],
1975                                    gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1] ) < 0. ) {
1976                         continue;
1977                 }
1978                 if ( side( x,y,
1979                                    gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1],
1980                                    gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1] ) < 0. ) {
1981                         continue;
1982                 }
1983                 tri = j;
1984         }
1985
1986         return tri;
1987 }
1988 /*============================================================================
1989    PlayerStartZ
1990    Determines minimum height to place the player start such that he doesn't
1991    intersect any surface brushes.
1992  */
1993 int PlayerStartZ( double x, double y ){
1994         int k,t[5];
1995         double z, zt;
1996
1997         if ( !gTri ) {
1998                 return (int)zmax;
1999         }
2000
2001         t[0] = TriangleFromPoint( x,y );
2002         t[1] = TriangleFromPoint( x + PlayerBox[Game].x[0],y + PlayerBox[Game].y[0] );
2003         t[2] = TriangleFromPoint( x + PlayerBox[Game].x[0],y + PlayerBox[Game].y[1] );
2004         t[3] = TriangleFromPoint( x + PlayerBox[Game].x[1],y + PlayerBox[Game].y[0] );
2005         t[4] = TriangleFromPoint( x + PlayerBox[Game].x[1],y + PlayerBox[Game].y[1] );
2006         z = zmin;
2007         for ( k = 0; k < 5; k++ )
2008         {
2009                 zt = ( gTri[t[k]].plane.dist -
2010                            gTri[t[k]].plane.normal[0] * x -
2011                            gTri[t[k]].plane.normal[1] * y   ) /
2012                          gTri[t[k]].plane.normal[2];
2013                 z = max( z,zt );
2014         }
2015         return (int)( AtLeast( z,2. ) - PlayerBox[Game].z[0] );
2016 }
2017 //=============================================================
2018 void XYZtoV( XYZ *xyz, vec3 *v ){
2019         v[0][0] = (vec)Nearest( xyz->p[0],2. );
2020         v[0][1] = (vec)Nearest( xyz->p[1],2. );
2021         v[0][2] = (vec)Nearest( xyz->p[2],2. );
2022 }
2023
2024 //=============================================================
2025 scene::Node* MakePatch( void ){
2026         scene::Node* patch = Patch_AllocNode();
2027 #if 0
2028         patch->m_patch->SetShader( Texture[Game][0] );
2029 #endif
2030         Node_getTraversable( h_worldspawn )->insert( patch );
2031         return patch;
2032 }
2033
2034 //=============================================================
2035 void MakeBrush( BRUSH *brush ){
2036         NodePtr node( Brush_AllocNode() );
2037
2038 #if 0
2039         for ( int i = 0; i < brush->NumFaces; i++ )
2040         {
2041                 _QERFaceData QERFaceData;
2042                 if ( !strncmp( brush->face[i].texture, "textures/", 9 ) ) {
2043                         strcpy( QERFaceData.m_TextureName,brush->face[i].texture );
2044                 }
2045                 else
2046                 {
2047                         strcpy( QERFaceData.m_TextureName,"textures/" );
2048                         strcpy( QERFaceData.m_TextureName + 9,brush->face[i].texture );
2049                 }
2050                 QERFaceData.m_nContents = brush->face[i].Contents;
2051                 QERFaceData.m_nFlags    = brush->face[i].Surface;
2052                 QERFaceData.m_nValue    = brush->face[i].Value;
2053                 QERFaceData.m_fShift[0] = brush->face[i].Shift[0];
2054                 QERFaceData.m_fShift[1] = brush->face[i].Shift[1];
2055                 QERFaceData.m_fRotate   = brush->face[i].Rotate;
2056                 QERFaceData.m_fScale[0] = brush->face[i].Scale[0];
2057                 QERFaceData.m_fScale[1] = brush->face[i].Scale[1];
2058                 QERFaceData.m_v1[0]     = brush->face[i].v[0][0];
2059                 QERFaceData.m_v1[1]     = brush->face[i].v[0][1];
2060                 QERFaceData.m_v1[2]     = brush->face[i].v[0][2];
2061                 QERFaceData.m_v2[0]     = brush->face[i].v[1][0];
2062                 QERFaceData.m_v2[1]     = brush->face[i].v[1][1];
2063                 QERFaceData.m_v2[2]     = brush->face[i].v[1][2];
2064                 QERFaceData.m_v3[0]     = brush->face[i].v[2][0];
2065                 QERFaceData.m_v3[1]     = brush->face[i].v[2][1];
2066                 QERFaceData.m_v3[2]     = brush->face[i].v[2][2];
2067                 QERFaceData.m_bBPrimit  = false;
2068                 ( g_FuncTable.m_pfnAddFaceData )( vp,&QERFaceData );
2069         }
2070 #endif
2071
2072         Node_getTraversable( h_func_group )->insert( node );
2073 }
2074 //=============================================================
2075 void OpenFuncGroup(){
2076         h_func_group = GlobalEntityCreator().createEntity( "func_group" );
2077         h_func_group->IncRef();
2078         if ( AddTerrainKey ) {
2079                 h_func_group->m_entity->setkeyvalue( "terrain", "1" );
2080         }
2081 }
2082 //=============================================================
2083 void CloseFuncGroup(){
2084         h_func_group->DecRef();
2085         if ( g_FuncTable.m_pfnSysUpdateWindows != NULL ) {
2086                 g_FuncTable.m_pfnSysUpdateWindows( W_ALL );
2087         }
2088 }