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