2 GenSurf plugin for GtkRadiant
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
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.
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.
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
25 double xmin,xmax,ymin,ymax,zmin,zmax;
29 XYZ xyz[MAX_ROWS+1][MAX_ROWS+1];
35 #include "refcounted_ptr.h"
44 scene::Node* h_func_group;
45 scene::Node* h_worldspawn;
48 //=============================================================
49 // Hydra : snap-to-grid begin
50 double CalculateSnapValue(double value)
54 // simple uncomplicated snapping, rounding both UP and DOWN to the nearest
58 snapvalue = (int)value / SnapToGrid;
59 if ((long)value % SnapToGrid < (SnapToGrid / 2)) // Snap Downwards if less than halfway between to grid units
60 value = snapvalue * SnapToGrid;
61 else // Snap Upwards if more than halfway between to grid units
62 value = (snapvalue+1) * SnapToGrid;
66 // Hydra : snap-to-grid end
68 //=============================================================
71 if(WaveType == WAVE_BITMAP && !gbmp.colors) return FALSE;
72 if(NH < 1) return FALSE;
73 if(NH > MAX_ROWS) return FALSE;
74 if(NV < 1) return FALSE;
75 if(NV > MAX_ROWS) return FALSE;
76 if(Hll >= Hur) return FALSE;
77 if(Vll >= Vur) return FALSE;
81 //=============================================================
96 // Generate control points in pp array to give desired values currently
123 xyz[i][j].pp[k1] = xyz[i][j].p[k1];
124 xyz[i][j].pp[k2] = xyz[i][j].p[k2];
127 for(i=0; i<=NH; i+=2)
129 for(j=0; j<=NV; j+=2)
130 xyz[i][j].pp[k3] = xyz[i][j].p[k3];
134 for(j=0; j<=NV; j+=2)
136 xyz[i][j].pp[k3] = (4*xyz[i][j].p[k3] - xyz[i-1][j].p[k3] - xyz[i+1][j].p[k3])/2;
141 for(i=0; i<=NH; i+=2)
143 xyz[i][j].pp[k3] = (4*xyz[i][j].p[k3] - xyz[i][j-1].p[k3] - xyz[i][j+1].p[k3])/2;
150 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]
151 - xyz[i+1][j-1].p[k3] - 2*xyz[i-1][j].p[k3] - 2*xyz[i+1][j].p[k3]
152 - xyz[i-1][j+1].p[k3] - 2*xyz[i][j+1].p[k3] - xyz[i+1][j+1].p[k3])/4;
160 if(( (NH_remain-1) % 14) == 0)
162 else if(( (NH_remain-1) % 12) == 0)
164 else if(( (NH_remain-1) % 10) == 0)
166 else if(( (NH_remain-1) % 8) == 0)
168 else if(( (NH_remain-1) % 6) == 0)
170 else if(( (NH_remain-1) % 4) == 0)
172 else if(( (NH_remain-1) % 2) == 0)
174 else if(NH_remain > 16)
176 else if(NH_remain > 4)
180 while( NH_patch > 3 && (NH_patch-1)*dh > 512 )
182 NH_remain -= (NH_patch-1);
185 sprintf(szOops,"Oops... screwed up with NH=%d",NH);
186 g_FuncTable.m_pfnMessageBox(NULL,szOops,"Uh oh");
192 if(( (NV_remain-1) % 14) == 0)
194 else if(( (NV_remain-1) % 12) == 0)
196 else if(( (NV_remain-1) % 10) == 0)
198 else if(( (NV_remain-1) % 8) == 0)
200 else if(( (NV_remain-1) % 6) == 0)
202 else if(( (NV_remain-1) % 4) == 0)
204 else if(( (NV_remain-1) % 2) == 0)
206 else if(NV_remain > 16)
208 else if(NV_remain > 4)
212 while( NV_patch > 3 && (NV_patch-1)*dh > 512 )
214 NV_remain -= (NV_patch-1);
217 sprintf(szOops,"Oops... screwed up with NV=%d",NV);
218 g_FuncTable.m_pfnMessageBox(NULL,szOops,"Uh oh");
221 scene::Node* patch = MakePatch();
223 b->pPatch->setDims(NH_patch, NV_patch);
224 for(i=0; i<NH_patch; i++)
231 ii = i0 + NH_patch - 1 - i;
236 for(j=0; j<NV_patch; j++)
238 b->pPatch->ctrlAt(COL,i,j)[0] = (float)xyz[ii][j0+j].pp[0];
239 b->pPatch->ctrlAt(COL,i,j)[1] = (float)xyz[ii][j0+j].pp[1];
240 b->pPatch->ctrlAt(COL,i,j)[2] = (float)xyz[ii][j0+j].pp[2];
241 b->pPatch->ctrlAt(COL,i,j)[3] = (float)i;
242 b->pPatch->ctrlAt(COL,i,j)[4] = (float)j;
245 b->pPatch->UpdateCachedData();
255 //=============================================================
265 vec3_t PlaneNormal,SurfNormal;
273 strcpy(surftext,Texture[Game][0]);
274 strcpy(sidetext,(strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
275 strcpy(surftext2,(strlen(Texture[Game][2]) ? Texture[Game][2] : Texture[Game][0]));
277 // if surftext2 is identical to surftext, there's no need to
278 // check surface angle
279 if(!g_strcasecmp(surftext,surftext2))
284 Steep = (float)cos((double)SlantAngle/57.2957795);
287 case PLANE_XY0: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
288 case PLANE_XY1: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]=-1.;break;
289 case PLANE_XZ0: PlaneNormal[0]= 0.;PlaneNormal[1]= 1.;PlaneNormal[2]= 1.;break;
290 case PLANE_XZ1: PlaneNormal[0]= 0.;PlaneNormal[1]=-1.;PlaneNormal[2]= 1.;break;
291 case PLANE_YZ0: PlaneNormal[0]= 1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
292 case PLANE_YZ1: PlaneNormal[0]=-1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
304 VectorCopy(xyz[i ][j ].p, v[0].p);
310 VectorCopy(xyz[i+1][j ].p, v[1].p);
311 VectorCopy(xyz[i+1][j+1].p, v[2].p);
314 VectorCopy(xyz[i+1][j+1].p, v[1].p);
315 VectorCopy(xyz[i+1][j ].p, v[2].p);
320 VectorCopy(xyz[i ][j ].p, v[0].p);
326 VectorCopy(xyz[i+1][j ].p, v[1].p);
327 VectorCopy(xyz[i ][j+1].p, v[2].p);
330 VectorCopy(xyz[i ][j+1].p, v[1].p);
331 VectorCopy(xyz[i+1][j ].p, v[2].p);
334 VectorCopy(v[0].p,v[3].p);
335 VectorCopy(v[1].p,v[4].p);
336 VectorCopy(v[2].p,v[5].p);
341 v[0].p[1] = backface;
342 v[1].p[1] = backface;
343 v[2].p[1] = backface;
347 v[3].p[0] = backface;
348 v[4].p[0] = backface;
349 v[5].p[0] = backface;
352 v[3].p[2] = backface;
353 v[4].p[2] = backface;
354 v[5].p[2] = backface;
357 brush.Number = i*NV*2+j*2;
359 XYZtoV(&v[0],&brush.face[0].v[0]);
360 XYZtoV(&v[3],&brush.face[0].v[1]);
361 XYZtoV(&v[4],&brush.face[0].v[2]);
362 strcpy(brush.face[0].texture,
363 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
364 brush.face[0].Shift[0] = (float)TexOffset[0];
365 brush.face[0].Shift[1] = (float)TexOffset[1];
366 brush.face[0].Rotate = 0.;
367 brush.face[0].Scale[0] = (float)TexScale[0];
368 brush.face[0].Scale[1] = (float)TexScale[1];
369 brush.face[0].Contents = contents;
370 brush.face[0].Surface = surface[1];
371 brush.face[0].Value = 0;
373 XYZtoV(&v[1],&brush.face[1].v[0]);
374 XYZtoV(&v[4],&brush.face[1].v[1]);
375 XYZtoV(&v[5],&brush.face[1].v[2]);
376 strcpy(brush.face[1].texture,
377 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
378 brush.face[1].Shift[0] = (float)TexOffset[0];
379 brush.face[1].Shift[1] = (float)TexOffset[1];
380 brush.face[1].Rotate = 0.;
381 brush.face[1].Scale[0] = (float)TexScale[0];
382 brush.face[1].Scale[1] = (float)TexScale[1];
383 brush.face[1].Contents = contents;
384 brush.face[1].Surface = surface[1];
385 brush.face[1].Value = 0;
387 XYZtoV(&v[2],&brush.face[2].v[0]);
388 XYZtoV(&v[5],&brush.face[2].v[1]);
389 XYZtoV(&v[3],&brush.face[2].v[2]);
390 strcpy(brush.face[2].texture,
391 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
392 brush.face[2].Shift[0] = (float)TexOffset[0];
393 brush.face[2].Shift[1] = (float)TexOffset[1];
394 brush.face[2].Rotate = 0.;
395 brush.face[2].Scale[0] = (float)TexScale[0];
396 brush.face[2].Scale[1] = (float)TexScale[1];
397 brush.face[2].Contents = contents;
398 brush.face[2].Surface = surface[1];
399 brush.face[2].Value = 0;
401 if(CheckAngle && (Plane==PLANE_XZ0 || Plane==PLANE_XZ1))
403 XYZVectorSubtract(v[4].p,v[3].p,t[0]);
404 XYZVectorSubtract(v[5].p,v[4].p,t[1]);
405 CrossProduct(t[0],t[1],SurfNormal);
406 VectorNormalize(SurfNormal,SurfNormal);
407 if(DotProduct(SurfNormal,PlaneNormal) < Steep)
409 strcpy(surft,surftext2);
414 strcpy(surft,surftext);
420 strcpy(surft,surftext);
424 XYZtoV(&v[3],&brush.face[3].v[0]);
425 XYZtoV(&v[5],&brush.face[3].v[1]);
426 XYZtoV(&v[4],&brush.face[3].v[2]);
427 strcpy(brush.face[3].texture,
428 (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? surft : sidetext));
429 brush.face[3].Shift[0] = (float)TexOffset[0];
430 brush.face[3].Shift[1] = (float)TexOffset[1];
431 brush.face[3].Rotate = 0.;
432 brush.face[3].Scale[0] = (float)TexScale[0];
433 brush.face[3].Scale[1] = (float)TexScale[1];
434 brush.face[3].Contents = contents;
435 brush.face[3].Surface = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? surf : surface[1]);
436 brush.face[3].Value = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? ArghRad2 : 0);
438 if(CheckAngle && Plane!=PLANE_XZ0 && Plane!=PLANE_XZ1)
440 XYZVectorSubtract(v[2].p,v[0].p,t[0]);
441 XYZVectorSubtract(v[1].p,v[2].p,t[1]);
442 CrossProduct(t[0],t[1],SurfNormal);
443 VectorNormalize(SurfNormal,SurfNormal);
444 if(DotProduct(SurfNormal,PlaneNormal) < Steep)
446 strcpy(surft,surftext2);
451 strcpy(surft,surftext);
457 strcpy(surft,surftext);
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);
478 VectorCopy(xyz[i ][j+1].p,v[0].p);
484 VectorCopy(xyz[i ][j ].p,v[1].p);
485 VectorCopy(xyz[i+1][j+1].p,v[2].p);
488 VectorCopy(xyz[i+1][j+1].p,v[1].p);
489 VectorCopy(xyz[i ][j ].p,v[2].p);
494 VectorCopy(xyz[i ][j+1].p,v[0].p);
500 VectorCopy(xyz[i+1][j ].p,v[1].p);
501 VectorCopy(xyz[i+1][j+1].p,v[2].p);
504 VectorCopy(xyz[i+1][j+1].p,v[1].p);
505 VectorCopy(xyz[i+1][j ].p,v[2].p);
508 VectorCopy(v[0].p,v[3].p);
509 VectorCopy(v[1].p,v[4].p);
510 VectorCopy(v[2].p,v[5].p);
515 v[0].p[1] = backface;
516 v[1].p[1] = backface;
517 v[2].p[1] = backface;
521 v[3].p[0] = backface;
522 v[4].p[0] = backface;
523 v[5].p[0] = backface;
526 v[3].p[2] = backface;
527 v[4].p[2] = backface;
528 v[5].p[2] = backface;
530 brush.Number = i*NV*2+j*2+1;
532 XYZtoV(&v[0],&brush.face[0].v[0]);
533 XYZtoV(&v[3],&brush.face[0].v[1]);
534 XYZtoV(&v[4],&brush.face[0].v[2]);
535 strcpy(brush.face[0].texture,
536 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
537 brush.face[0].Shift[0] = (float)TexOffset[0];
538 brush.face[0].Shift[1] = (float)TexOffset[1];
539 brush.face[0].Rotate = 0.;
540 brush.face[0].Scale[0] = (float)TexScale[0];
541 brush.face[0].Scale[1] = (float)TexScale[1];
542 brush.face[0].Contents = contents;
543 brush.face[0].Surface = surface[1];
544 brush.face[0].Value = 0;
546 XYZtoV(&v[1],&brush.face[1].v[0]);
547 XYZtoV(&v[4],&brush.face[1].v[1]);
548 XYZtoV(&v[5],&brush.face[1].v[2]);
549 strcpy(brush.face[1].texture,
550 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
551 brush.face[1].Shift[0] = (float)TexOffset[0];
552 brush.face[1].Shift[1] = (float)TexOffset[1];
553 brush.face[1].Rotate = 0.;
554 brush.face[1].Scale[0] = (float)TexScale[0];
555 brush.face[1].Scale[1] = (float)TexScale[1];
556 brush.face[1].Contents = contents;
557 brush.face[1].Surface = surface[1];
558 brush.face[1].Value = 0;
560 XYZtoV(&v[2],&brush.face[2].v[0]);
561 XYZtoV(&v[5],&brush.face[2].v[1]);
562 XYZtoV(&v[3],&brush.face[2].v[2]);
563 strcpy(brush.face[2].texture,
564 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
565 brush.face[2].Shift[0] = (float)TexOffset[0];
566 brush.face[2].Shift[1] = (float)TexOffset[1];
567 brush.face[2].Rotate = 0.;
568 brush.face[2].Scale[0] = (float)TexScale[0];
569 brush.face[2].Scale[1] = (float)TexScale[1];
570 brush.face[2].Contents = contents;
571 brush.face[2].Surface = surface[1];
572 brush.face[2].Value = 0;
574 if(CheckAngle && (Plane==PLANE_XZ0 || Plane==PLANE_XZ1))
576 XYZVectorSubtract(v[4].p,v[3].p,t[0]);
577 XYZVectorSubtract(v[5].p,v[4].p,t[1]);
578 CrossProduct(t[0],t[1],SurfNormal);
579 VectorNormalize(SurfNormal,SurfNormal);
580 if(DotProduct(SurfNormal,PlaneNormal) < Steep)
582 strcpy(surft,surftext2);
587 strcpy(surft,surftext);
593 strcpy(surft,surftext);
596 XYZtoV(&v[3],&brush.face[3].v[0]);
597 XYZtoV(&v[5],&brush.face[3].v[1]);
598 XYZtoV(&v[4],&brush.face[3].v[2]);
599 strcpy(brush.face[3].texture,
600 (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? surft : sidetext));
601 brush.face[3].Shift[0] = (float)TexOffset[0];
602 brush.face[3].Shift[1] = (float)TexOffset[1];
603 brush.face[3].Rotate = 0.;
604 brush.face[3].Scale[0] = (float)TexScale[0];
605 brush.face[3].Scale[1] = (float)TexScale[1];
606 brush.face[3].Contents = contents;
607 brush.face[3].Surface = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? surf : surface[1]);
608 brush.face[3].Value = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? ArghRad2 : 0);
610 if(CheckAngle && Plane!=PLANE_XZ0 && Plane!=PLANE_XZ1)
612 XYZVectorSubtract(v[2].p,v[0].p,t[0]);
613 XYZVectorSubtract(v[1].p,v[2].p,t[1]);
614 CrossProduct(t[0],t[1],SurfNormal);
615 VectorNormalize(SurfNormal,SurfNormal);
616 if(DotProduct(SurfNormal,PlaneNormal) < Steep)
618 strcpy(surft,surftext2);
623 strcpy(surft,surftext);
629 strcpy(surft,surftext);
632 XYZtoV(&v[0],&brush.face[4].v[0]);
633 XYZtoV(&v[1],&brush.face[4].v[1]);
634 XYZtoV(&v[2],&brush.face[4].v[2]);
635 strcpy(brush.face[4].texture,
636 (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? sidetext : surft));
637 brush.face[4].Shift[0] = (float)TexOffset[0];
638 brush.face[4].Shift[1] = (float)TexOffset[1];
639 brush.face[4].Rotate = 0.;
640 brush.face[4].Scale[0] = (float)TexScale[0];
641 brush.face[4].Scale[1] = (float)TexScale[1];
642 brush.face[4].Contents = contents;
643 brush.face[4].Surface = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? surface[1] : surf);
644 brush.face[4].Value = (Plane==PLANE_XZ0 || Plane==PLANE_XZ1 ? 0 : ArghRad2);
651 if( AddHints || GimpHints )
653 int detail, i1, j1, N;
663 strcpy(hint,"generic/misc/hint");
664 strcpy(skip,"generic/misc/skip");
667 strcpy(hint,"general/hint");
668 strcpy(skip,"general/hint"); // Heretic2 doesn't have a skip texture
671 strcpy(hint,"common/0_hint");
672 strcpy(skip,"common/0_skip");
679 strcpy(hint,"textures/common/hint");
680 strcpy(skip,"textures/common/skip");
683 strcpy(hint,"e1u1/hint");
684 strcpy(skip,"e1u1/skip");
691 detail = CONTENTS_DETAIL;
700 // For detail hint brushes, no need to use a hint brush over
701 // EVERY grid square... it would be redundant. Instead use
702 // a checkerboard pattern
703 if((i+j)%2) continue;
707 VectorCopy(xyz[i ][j ].p, v[0].p);
713 VectorCopy(xyz[i1][j ].p, v[1].p);
714 VectorCopy(xyz[i1][j1].p, v[2].p);
715 VectorCopy(xyz[i ][j1].p, v[3].p);
718 VectorCopy(xyz[i ][j1].p, v[1].p);
719 VectorCopy(xyz[i1][j1].p, v[2].p);
720 VectorCopy(xyz[i1][j ].p, v[3].p);
723 VectorCopy(v[0].p,v[4].p);
724 VectorCopy(v[1].p,v[5].p);
725 VectorCopy(v[2].p,v[6].p);
726 VectorCopy(v[3].p,v[7].p);
731 front = LessThan(zmin,32.);
732 v[4].p[2] = backface;
733 v[5].p[2] = backface;
734 v[6].p[2] = backface;
735 v[7].p[2] = backface;
738 front = MoreThan(ymax,32.);
739 v[0].p[1] = backface;
740 v[1].p[1] = backface;
741 v[2].p[1] = backface;
742 v[3].p[1] = backface;
745 front = LessThan(ymin,32.);
746 v[0].p[1] = backface;
747 v[1].p[1] = backface;
748 v[2].p[1] = backface;
749 v[3].p[1] = backface;
752 front = MoreThan(xmax,32.);
753 v[4].p[0] = backface;
754 v[5].p[0] = backface;
755 v[6].p[0] = backface;
756 v[7].p[0] = backface;
759 front = LessThan(xmin,32.);
760 v[4].p[0] = backface;
761 v[5].p[0] = backface;
762 v[6].p[0] = backface;
763 v[7].p[0] = backface;
766 front = MoreThan(zmax,32.);
767 v[4].p[2] = backface;
768 v[5].p[2] = backface;
769 v[6].p[2] = backface;
770 v[7].p[2] = backface;
778 v[5].p[1] = v[4].p[1];
779 v[6].p[1] = v[4].p[1];
780 v[7].p[1] = v[4].p[1];
785 v[1].p[0] = v[0].p[0];
786 v[2].p[0] = v[0].p[0];
787 v[3].p[0] = v[0].p[0];
791 v[1].p[2] = v[0].p[2];
792 v[2].p[2] = v[0].p[2];
793 v[3].p[2] = v[0].p[2];
798 XYZtoV(&v[0],&brush.face[0].v[0]);
799 XYZtoV(&v[1],&brush.face[0].v[1]);
800 XYZtoV(&v[2],&brush.face[0].v[2]);
801 strcpy(brush.face[0].texture,skip);
802 brush.face[0].Shift[0] = 0.;
803 brush.face[0].Shift[1] = 0.;
804 brush.face[0].Rotate = 0.;
805 brush.face[0].Scale[0] = 1.;
806 brush.face[0].Scale[1] = 1.;
807 brush.face[0].Contents = detail;
808 brush.face[0].Surface = SURF_SKIP;
809 brush.face[0].Value = 0;
811 XYZtoV(&v[4],&brush.face[1].v[0]);
812 XYZtoV(&v[7],&brush.face[1].v[1]);
813 XYZtoV(&v[6],&brush.face[1].v[2]);
814 strcpy(brush.face[1].texture,skip);
815 brush.face[1].Shift[0] = 0.;
816 brush.face[1].Shift[1] = 0.;
817 brush.face[1].Rotate = 0.;
818 brush.face[1].Scale[0] = 1.;
819 brush.face[1].Scale[1] = 1.;
820 brush.face[1].Contents = detail;
821 brush.face[1].Surface = SURF_SKIP;
822 brush.face[1].Value = 0;
824 XYZtoV(&v[0],&brush.face[2].v[0]);
825 XYZtoV(&v[4],&brush.face[2].v[1]);
826 XYZtoV(&v[5],&brush.face[2].v[2]);
827 strcpy(brush.face[2].texture,hint);
828 brush.face[2].Shift[0] = 0.;
829 brush.face[2].Shift[1] = 0.;
830 brush.face[2].Rotate = 0.;
831 brush.face[2].Scale[0] = 1.;
832 brush.face[2].Scale[1] = 1.;
833 brush.face[2].Contents = detail;
834 brush.face[2].Surface = SURF_HINT;
835 brush.face[2].Value = 0;
837 XYZtoV(&v[1],&brush.face[3].v[0]);
838 XYZtoV(&v[5],&brush.face[3].v[1]);
839 XYZtoV(&v[6],&brush.face[3].v[2]);
840 strcpy(brush.face[3].texture,hint);
841 brush.face[3].Shift[0] = 0.;
842 brush.face[3].Shift[1] = 0.;
843 brush.face[3].Rotate = 0.;
844 brush.face[3].Scale[0] = 1.;
845 brush.face[3].Scale[1] = 1.;
846 brush.face[3].Contents = detail;
847 brush.face[3].Surface = SURF_HINT;
848 brush.face[3].Value = 0;
850 XYZtoV(&v[2],&brush.face[4].v[0]);
851 XYZtoV(&v[6],&brush.face[4].v[1]);
852 XYZtoV(&v[7],&brush.face[4].v[2]);
853 strcpy(brush.face[4].texture,hint);
854 brush.face[4].Shift[0] = 0.;
855 brush.face[4].Shift[1] = 0.;
856 brush.face[4].Rotate = 0.;
857 brush.face[4].Scale[0] = 1.;
858 brush.face[4].Scale[1] = 1.;
859 brush.face[4].Contents = detail;
860 brush.face[4].Surface = SURF_HINT;
861 brush.face[4].Value = 0;
863 XYZtoV(&v[3],&brush.face[5].v[0]);
864 XYZtoV(&v[7],&brush.face[5].v[1]);
865 XYZtoV(&v[4],&brush.face[5].v[2]);
866 strcpy(brush.face[5].texture,hint);
867 brush.face[5].Shift[0] = 0.;
868 brush.face[5].Shift[1] = 0.;
869 brush.face[5].Rotate = 0.;
870 brush.face[5].Scale[0] = 1.;
871 brush.face[5].Scale[1] = 1.;
872 brush.face[5].Contents = detail;
873 brush.face[5].Surface = SURF_HINT;
874 brush.face[5].Value = 0;
884 // these brush parameters never change
888 strcpy(brush.face[i].texture,hint);
889 brush.face[i].Shift[0] = 0.;
890 brush.face[i].Shift[1] = 0.;
891 brush.face[i].Rotate = 0.;
892 brush.face[i].Scale[0] = 1.;
893 brush.face[i].Scale[1] = 1.;
894 brush.face[i].Contents = 0;
895 brush.face[i].Surface = SURF_HINT;
896 brush.face[i].Value = 0;
908 VectorCopy(xyz[i ][j ].p, v[0].p);
914 VectorCopy(xyz[i+1][j ].p, v[1].p);
915 VectorCopy(xyz[i+1][j+1].p, v[2].p);
918 VectorCopy(xyz[i+1][j+1].p, v[1].p);
919 VectorCopy(xyz[i+1][j ].p, v[2].p);
924 VectorCopy(xyz[i ][j ].p, v[0].p);
930 VectorCopy(xyz[i+1][j ].p, v[1].p);
931 VectorCopy(xyz[i ][j+1].p, v[2].p);
934 VectorCopy(xyz[i ][j+1].p, v[1].p);
935 VectorCopy(xyz[i+1][j ].p, v[2].p);
943 VectorCopy(xyz[i ][j+1].p,v[0].p);
949 VectorCopy(xyz[i ][j ].p,v[1].p);
950 VectorCopy(xyz[i+1][j+1].p,v[2].p);
953 VectorCopy(xyz[i+1][j+1].p,v[1].p);
954 VectorCopy(xyz[i ][j ].p,v[2].p);
959 VectorCopy(xyz[i ][j+1].p,v[0].p);
965 VectorCopy(xyz[i+1][j ].p,v[1].p);
966 VectorCopy(xyz[i+1][j+1].p,v[2].p);
969 VectorCopy(xyz[i+1][j+1].p,v[1].p);
970 VectorCopy(xyz[i+1][j ].p,v[2].p);
974 VectorCopy(v[0].p,v[3].p);
975 VectorCopy(v[1].p,v[4].p);
976 VectorCopy(v[2].p,v[5].p);
980 v[0].p[2] += HINT_OFFSET;
981 v[1].p[2] += HINT_OFFSET;
982 v[2].p[2] += HINT_OFFSET;
983 // v[3].p[2] = backface;
984 // v[4].p[2] = backface;
985 // v[5].p[2] = backface;
988 v[0].p[2] -= HINT_OFFSET;
989 v[1].p[2] -= HINT_OFFSET;
990 v[2].p[2] -= HINT_OFFSET;
991 // v[3].p[2] = backface;
992 // v[4].p[2] = backface;
993 // v[5].p[2] = backface;
996 // v[0].p[1] = backface;
997 // v[1].p[1] = backface;
998 // v[2].p[1] = backface;
999 v[3].p[1] += HINT_OFFSET;
1000 v[4].p[1] += HINT_OFFSET;
1001 v[5].p[1] += HINT_OFFSET;
1004 // v[0].p[1] = backface;
1005 // v[1].p[1] = backface;
1006 // v[2].p[1] = backface;
1007 v[3].p[1] -= HINT_OFFSET;
1008 v[4].p[1] -= HINT_OFFSET;
1009 v[5].p[1] -= HINT_OFFSET;
1012 v[0].p[0] += HINT_OFFSET;
1013 v[1].p[0] += HINT_OFFSET;
1014 v[2].p[0] += HINT_OFFSET;
1015 // v[3].p[0] = backface;
1016 // v[4].p[0] = backface;
1017 // v[5].p[0] = backface;
1020 v[0].p[0] -= HINT_OFFSET;
1021 v[1].p[0] -= HINT_OFFSET;
1022 v[2].p[0] -= HINT_OFFSET;
1023 // v[3].p[0] = backface;
1024 // v[4].p[0] = backface;
1025 // v[5].p[0] = backface;
1029 XYZtoV(&v[0],&brush.face[0].v[0]);
1030 XYZtoV(&v[3],&brush.face[0].v[1]);
1031 XYZtoV(&v[4],&brush.face[0].v[2]);
1033 XYZtoV(&v[1],&brush.face[1].v[0]);
1034 XYZtoV(&v[4],&brush.face[1].v[1]);
1035 XYZtoV(&v[5],&brush.face[1].v[2]);
1037 XYZtoV(&v[2],&brush.face[2].v[0]);
1038 XYZtoV(&v[5],&brush.face[2].v[1]);
1039 XYZtoV(&v[3],&brush.face[2].v[2]);
1041 XYZtoV(&v[3],&brush.face[3].v[0]);
1042 XYZtoV(&v[5],&brush.face[3].v[1]);
1043 XYZtoV(&v[4],&brush.face[3].v[2]);
1045 XYZtoV(&v[0],&brush.face[4].v[0]);
1046 XYZtoV(&v[1],&brush.face[4].v[1]);
1047 XYZtoV(&v[2],&brush.face[4].v[2]);
1054 } // endif AddHints==1
1060 //=============================================================
1063 extern void MapOut(int,int,NODE *,TRI *);
1064 extern bool SingleBrushSelected;
1067 if(!ValidSurface()) return;
1069 ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
1070 SetCursor(ghCursorCurrent);
1073 if(SingleBrushSelected) g_FuncTable.m_pfnDeleteSelection();
1079 if(Game==QUAKE3 && UsePatches != 0)
1082 if(Decimate > 0 && (Game != QUAKE3 || UsePatches==0) )
1084 MapOut(gNumNodes,gNumTris,gNode,gTri);
1086 ghCursorCurrent = ghCursorDefault;
1087 SetCursor(ghCursorCurrent);
1093 // HL doesn't have detail property
1094 if((Game != HALFLIFE) && UseDetail) contents += CONTENTS_DETAIL;
1095 // HL and Q3 don't have ladder property
1096 if((Game != HALFLIFE && Game != QUAKE3) && UseLadder) contents += CONTENTS_LADDER;
1097 // Genesis requires solid property to be set explicitly
1098 if(Game == GENESIS3D) contents |= CONTENTS_SOLID;
1099 // Heretic 2 uses different sounds (in surface props) for different texture types
1100 if(Game == HERETIC2)
1102 surface[0] = GetDefSurfaceProps(Texture[Game][0]);
1103 surface[1] = GetDefSurfaceProps(Texture[Game][1]);
1104 surface[2] = GetDefSurfaceProps(Texture[Game][2]);
1112 if(Game!=QUAKE3 || UsePatches == 0)
1116 ghCursorCurrent = ghCursorDefault;
1117 SetCursor(ghCursorCurrent);
1121 //=============================================================
1124 extern void MakeDecimatedMap(int *, int *, NODE **, TRI **);
1129 double delta, dr, rate;
1130 double range, maxrange;
1139 if(!ValidSurface()) return;
1148 for(i=0; i<=NH; i++)
1156 xyz[i][j].p[0] = Hll + i*dh;
1157 xyz[i][j].p[2] = Vll + j*dv;
1161 xyz[i][j].p[1] = Hll + i*dh;
1162 xyz[i][j].p[2] = Vll + j*dv;
1165 xyz[i][j].p[0] = Hll + i*dh;
1166 xyz[i][j].p[1] = Vll + j*dv;
1171 if(WaveType == WAVE_BITMAP)
1172 GenerateBitmapMapping();
1174 else if(WaveType == WAVE_FORMULA)
1179 // Initialize Z values using bilinear interpolation
1180 for(i=0; i<=NH; i++)
1182 zl = Z00 + i*(Z10 - Z00)/NH;
1183 zu = Z01 + i*(Z11 - Z01)/NH;
1188 for(j=0; j<=NV; j++)
1189 xyz[i][j].p[1] = zl + j*(zu-zl)/NV;
1193 for(j=0; j<=NV; j++)
1194 xyz[i][j].p[0] = zl + j*(zu-zl)/NV;
1197 for(j=0; j<=NV; j++)
1198 xyz[i][j].p[2] = zl + j*(zu-zl)/NV;
1208 NHalfcycles = (int)((Hur-Hll)/(WaveLength/2.));
1209 NHalfcycles = max(NHalfcycles,1);
1210 wh = 2.*(Hur-Hll)/NHalfcycles;
1211 NHalfcycles = (int)((Vur-Vll)/(WaveLength/2.));
1212 wv = 2.*(Vur-Vll)/NHalfcycles;
1213 NHalfcycles = max(NHalfcycles,1);
1229 for(i=i0; i<=i1; i++)
1232 ha = ((h-Hll)/wh)*2.*PI - PI/2.;
1233 for(j=j0; j<=j1; j++)
1236 va = ((v-Vll)/wv)*2.*PI;
1237 a = Amplitude * cos( ha ) * sin( va );
1241 xyz[i][j].p[2] -= a;
1244 xyz[i][j].p[1] += a;
1247 xyz[i][j].p[1] -= a;
1250 xyz[i][j].p[0] += a;
1253 xyz[i][j].p[0] -= a;
1256 xyz[i][j].p[2] += a;
1261 case WAVE_HCYLINDER:
1262 for(i=0; i<=NH; i++)
1265 ha = ((h-Hll)/WaveLength)*2.*PI - PI/2.;
1266 for(j=0; j<=NV; j++)
1268 a = Amplitude * cos( ha );
1272 xyz[i][j].p[2] -= a;
1275 xyz[i][j].p[1] += a;
1278 xyz[i][j].p[1] -= a;
1281 xyz[i][j].p[0] += a;
1284 xyz[i][j].p[0] -= a;
1287 xyz[i][j].p[2] += a;
1292 case WAVE_VCYLINDER:
1293 for(i=0; i<=NH; i++)
1296 for(j=0; j<=NV; j++)
1299 va = ((v-Vll)/WaveLength)*2.*PI;
1300 a = Amplitude * sin( va );
1304 xyz[i][j].p[2] -= a;
1307 xyz[i][j].p[1] += a;
1310 xyz[i][j].p[1] -= a;
1313 xyz[i][j].p[0] += a;
1316 xyz[i][j].p[0] -= a;
1319 xyz[i][j].p[2] += a;
1324 case WAVE_ROUGH_ONLY:
1329 if(WaveType != WAVE_ROUGH_ONLY)
1332 for(i=0; i<=NH; i++)
1334 for(j=0; j<=NV; j++)
1342 xyz[i][j].p[1] = xyz[i][j].fixed_value;
1346 xyz[i][j].p[0] = xyz[i][j].fixed_value;
1349 xyz[i][j].p[2] = xyz[i][j].fixed_value;
1352 if(xyz[i][j].range > 0)
1354 maxrange = pow(xyz[i][j].range,2); // so we don't have to do sqrt's
1355 i0 = i - (int)( floor(xyz[i][j].range/dh - 0.5) + 1 );
1357 j0 = j - (int)( floor(xyz[i][j].range/dv - 0.5) + 1 );
1373 for(ii=i0; ii<=i1; ii++)
1375 for(jj=j0; jj<=j1; jj++)
1377 if(ii==i && jj==j) continue;
1378 range = pow( dh*(i-ii), 2) + pow( dv*(j-jj), 2);
1379 if(range > maxrange) continue;
1380 dr = sqrt(range/maxrange);
1381 rate = max(-30.,min(xyz[i][j].rate,30.));
1384 delta = pow((1.-dr),-rate+1.);
1388 delta = (1+rate)*0.5*(cos(dr*PI)+1.0) -
1389 rate*pow((1.-dr),2);
1393 delta = 0.5*(cos(dr*PI)+1.0);
1397 delta = (1.-rate)*0.5*(cos(dr*PI)+1.0) +
1398 rate*(1.-pow(dr,2));
1402 delta = 1.-pow(dr,rate+1);
1408 xyz[ii][jj].p[1] += (xyz[i][j].p[1] - xyz[ii][jj].p[1])*delta;
1412 xyz[ii][jj].p[0] += (xyz[i][j].p[0] - xyz[ii][jj].p[0])*delta;
1415 xyz[ii][jj].p[2] += (xyz[i][j].p[2] - xyz[ii][jj].p[2])*delta;
1425 if((Roughness > 0.) && (WaveType != WAVE_ROUGH_ONLY) )
1427 for(i=0; i<=NH; i++)
1429 for(j=0; j<=NV; j++)
1431 if(CanEdit(i,j) && !xyz[i][j].fixed)
1437 xyz[i][j].p[1] += -Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX);
1441 xyz[i][j].p[0] += -Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX);
1444 xyz[i][j].p[2] += -Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX);
1448 r = rand(); // We still get a random number, so that fixing points
1449 // doesn't change the sequence.
1455 for(i=0; i<=NH; i++)
1457 for(j=0; j<=NV; j++)
1461 xyz[i][j].p[k] = Nearest(xyz[i][j].p[k],2.0);
1466 // Find minima and maxima
1475 ymin = xyz[0][0].p[1];
1477 for(i=0; i<=NH; i++)
1479 for(j=0; j<=NV; j++)
1481 ymin = min(ymin,xyz[i][j].p[1]);
1482 ymax = max(ymax,xyz[i][j].p[1]);
1492 xmin = xyz[0][0].p[0];
1494 for(i=0; i<=NH; i++)
1496 for(j=0; j<=NV; j++)
1498 xmin = min(xmin,xyz[i][j].p[0]);
1499 xmax = max(xmax,xyz[i][j].p[0]);
1509 zmin = xyz[0][0].p[2];
1511 for(i=0; i<=NH; i++)
1513 for(j=0; j<=NV; j++)
1515 zmin = min(zmin,xyz[i][j].p[2]);
1516 zmax = max(zmax,xyz[i][j].p[2]);
1521 xmin = Nearest(xmin,2.);
1522 xmax = Nearest(xmax,2.);
1523 ymin = Nearest(ymin,2.);
1524 ymax = Nearest(ymax,2.);
1525 zmin = Nearest(zmin,2.);
1526 zmax = Nearest(zmax,2.);
1531 backface = AtLeast(zmax+32.,32.);
1534 backface = NoMoreThan(ymin-32.,32.);
1537 backface = AtLeast(ymax+32.,32.);
1540 backface = NoMoreThan(xmin-32.,32.);
1543 backface = AtLeast(xmax+32.,32.);
1546 backface = NoMoreThan(zmin-32.,32.);
1553 gNode = (NODE *)NULL;
1556 if(Decimate > 0 && (Game != QUAKE3 || UsePatches==0) )
1558 MakeDecimatedMap(&gNumNodes,&gNumTris,&gNode,&gTri);
1562 gNumNodes = (NH+1)*(NV+1);
1564 gNode = (NODE *) malloc(gNumNodes * sizeof(NODE));
1565 gTri = (TRI *) malloc(gNumTris * sizeof(TRI));
1567 for(i=0,N=0; i<=NH; i++)
1569 for(j=0; j<=NV; j++, N++)
1572 gNode[N].p[0] = (float)xyz[i][j].p[0];
1573 gNode[N].p[1] = (float)xyz[i][j].p[1];
1574 gNode[N].p[2] = (float)xyz[i][j].p[2];
1590 gTri[k ].v[0] = i*(NV+1)+j;
1591 gTri[k ].v[1] = (i+1)*(NV+1)+j+1;
1592 gTri[k ].v[2] = (i+1)*(NV+1)+j;
1593 gTri[k+1].v[0] = i*(NV+1)+j;
1594 gTri[k+1].v[1] = i*(NV+1)+j+1;
1595 gTri[k+1].v[2] = (i+1)*(NV+1)+j+1;
1598 gTri[k ].v[0] = i*(NV+1)+j;
1599 gTri[k ].v[1] = (i+1)*(NV+1)+j;
1600 gTri[k ].v[2] = (i+1)*(NV+1)+j+1;
1601 gTri[k+1].v[0] = i*(NV+1)+j;
1602 gTri[k+1].v[1] = (i+1)*(NV+1)+j+1;
1603 gTri[k+1].v[2] = i*(NV+1)+j+1;
1613 gTri[k ].v[0] = i*(NV+1)+j;
1614 gTri[k ].v[1] = i*(NV+1)+j+1;
1615 gTri[k ].v[2] = (i+1)*(NV+1)+j;
1616 gTri[k+1].v[0] = (i+1)*(NV+1)+j;
1617 gTri[k+1].v[1] = i*(NV+1)+j+1;
1618 gTri[k+1].v[2] = (i+1)*(NV+1)+j+1;
1621 gTri[k ].v[0] = i*(NV+1)+j;
1622 gTri[k ].v[1] = (i+1)*(NV+1)+j;
1623 gTri[k ].v[2] = i*(NV+1)+j+1;
1624 gTri[k+1].v[0] = (i+1)*(NV+1)+j;
1625 gTri[k+1].v[1] = (i+1)*(NV+1)+j+1;
1626 gTri[k+1].v[2] = i*(NV+1)+j+1;
1633 sprintf(CSV,"csv%03d.csv",Decimate);
1635 for(i=0; i<gNumNodes; i++)
1638 fprintf(f,"%g,%g,%g\n",gNode[i].p[0],gNode[i].p[1],gNode[i].p[2]);
1642 for(i=0; i<gNumTris; i++)
1643 PlaneFromPoints(gNode[gTri[i].v[0]].p,
1644 gNode[gTri[i].v[1]].p,
1645 gNode[gTri[i].v[2]].p,
1648 // Hydra: snap-to-grid begin
1659 xyz[i][j].p[1] = CalculateSnapValue(xyz[i][j].p[1]);
1663 xyz[i][j].p[0] = CalculateSnapValue(xyz[i][j].p[0]);
1666 xyz[i][j].p[2] = CalculateSnapValue(xyz[i][j].p[2]);
1671 // Hydra: snap-to-grid end
1673 //=============================================================
1674 double Nearest(double x, double dx)
1678 xx = (double)(floor(x/dx - 0.5)+1.)*dx;
1679 if(fabs(xx) < dx/2) xx = 0.;
1682 //=============================================================
1683 double NoMoreThan(double x, double dx)
1687 xx = (double)(floor(x/dx - 0.5)+1.)*dx;
1688 if(xx > x) xx -= dx;
1691 //=============================================================
1692 double AtLeast(double x, double dx)
1696 xx = (double)(floor(x/dx - 0.5)+1.)*dx;
1697 if(xx < x) xx += dx;
1700 //=============================================================
1701 double LessThan(double x,double dx)
1705 xx = (double)(floor(x/dx - 0.5)+1.)*dx;
1706 if(xx >= x) xx -= dx;
1709 //=============================================================
1710 double MoreThan(double x,double dx)
1714 xx = (double)(floor(x/dx - 0.5)+1.)*dx;
1719 //=============================================================
1720 void SubdividePlasma(int i0,int j0,int i1,int j1)
1724 double r; // NOTE: This is used to keep the random number sequence the same
1725 // when we fix a point. If we did NOT do this, then simply
1726 // fixing a point at its current value would change the entire
1733 if(!xyz[i][j0].done)
1735 xyz[i][j0].pp[2] = xyz[i0][j0].pp[2] +
1736 (xyz[i1][j0].pp[2] - xyz[i0][j0].pp[2])*(double)(i-i0)/(double)(i1-i0) +
1737 ((double)(i-i0))*(-Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX));
1738 xyz[i][j0].done = 1;
1742 if((j1 > j0) && (!xyz[i][j1].done) )
1744 xyz[i][j1].pp[2] = xyz[i0][j1].pp[2] +
1745 (xyz[i1][j1].pp[2] - xyz[i0][j1].pp[2])*(double)(i-i0)/(double)(i1-i0) +
1746 ((double)(i-i0))*(-Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX));
1747 xyz[i][j1].done = 1;
1754 if(!xyz[i0][j].done)
1756 xyz[i0][j].pp[2] = xyz[i0][j0].pp[2] +
1757 (xyz[i0][j1].pp[2] - xyz[i0][j0].pp[2])*(double)(j-j0)/(double)(j1-j0) +
1758 ((double)(j-j0))*(-Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX));
1759 xyz[i0][j].done = 1;
1763 if((i1 > i0) && (!xyz[i1][j].done))
1765 xyz[i1][j].pp[2] = xyz[i1][j0].pp[2] +
1766 (xyz[i1][j1].pp[2] - xyz[i1][j0].pp[2])*(double)(j-j0)/(double)(j1-j0) +
1767 ((double)(j-j0))*(-Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX));
1768 xyz[i1][j].done = 1;
1773 if((i1 > i0+1) && (j1 > j0+1))
1777 z1 = xyz[i0][j].pp[2] +
1778 (xyz[i1][j].pp[2] - xyz[i0][j].pp[2])*(double)(i-i0)/(double)(i1-i0);
1779 z2 = xyz[i][j0].pp[2] +
1780 (xyz[i][j1].pp[2] - xyz[i][j0].pp[2])*(double)(j-j0)/(double)(j1-j0);
1781 xyz[i][j].pp[2] = (z1+z2)/2. +
1782 ((double)(i-i0))*(-Roughness/2. + Roughness*((double)rand()/(double)RAND_MAX));
1788 if(i > i0+1 || j > j0+1)
1789 SubdividePlasma(i0,j0,i,j);
1790 if(i1 > i+1 || j > j0+1)
1791 SubdividePlasma(i,j0,i1,j);
1792 if(i > i0+1 || j1 > j0+1)
1793 SubdividePlasma(i0,j,i,j1);
1794 if(i1 > i+1 || j1 > j0+1)
1795 SubdividePlasma(i,j,i1,j1);
1797 //==================================================================================
1801 /* use pp[2] values until done to avoid messing with a bunch of
1802 switch statements */
1804 for(i=0; i<=NH; i++)
1806 for(j=0; j<=NV; j++)
1819 for(i=0; i<=NH; i++)
1821 for(j=0; j<=NV; j++)
1824 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1826 xyz[i][j].pp[2] = xyz[i][j].p[1];
1832 for(i=0; i<=NH; i++)
1834 for(j=0; j<=NV; j++)
1837 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1839 xyz[i][j].pp[2] = xyz[i][j].p[0];
1844 for(i=0; i<=NH; i++)
1846 for(j=0; j<=NV; j++)
1849 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1851 xyz[i][j].pp[2] = xyz[i][j].p[2];
1856 SubdividePlasma(0,0,NH,NV);
1861 for(i=0; i<=NH; i++)
1863 for(j=0; j<=NV; j++)
1865 xyz[i][j].p[1] = xyz[i][j].pp[2];
1871 for(i=0; i<=NH; i++)
1873 for(j=0; j<=NV; j++)
1875 xyz[i][j].p[0] = xyz[i][j].pp[2];
1880 for(i=0; i<=NH; i++)
1882 for(j=0; j<=NV; j++)
1884 xyz[i][j].p[2] = xyz[i][j].pp[2];
1890 //===========================================================================
1891 bool FixedPoint(int i, int j)
1893 if(xyz[i][j].fixed) return TRUE;
1894 return !CanEdit(i,j);
1896 //===========================================================================
1897 bool CanEdit(int i, int j)
1899 if(FixBorders && ( (WaveType==WAVE_COS_SIN) || (WaveType==WAVE_ROUGH_ONLY) ) )
1901 if(i== 0) return FALSE;
1902 if(i==NH) return FALSE;
1903 if(j== 0) return FALSE;
1904 if(j==NV) return FALSE;
1906 if(i== 0 && j== 0) return FALSE;
1907 if(i==NH && j== 0) return FALSE;
1908 if(i== 0 && j==NV) return FALSE;
1909 if(i==NH && j==NV) return FALSE;
1912 /*============================================================================
1914 Determines which triangle in the gTri array bounds the input point. Doesn't
1915 do anything special with border points.
1917 int TriangleFromPoint(double x, double y)
1921 if(!gTri) return -1;
1923 for(j=0, tri=-1; j<gNumTris && tri==-1; j++)
1926 gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1],
1927 gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1]) < 0. ) continue;
1929 gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1],
1930 gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1]) < 0. ) continue;
1932 gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1],
1933 gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1]) < 0. ) continue;
1939 /*============================================================================
1941 Determines minimum height to place the player start such that he doesn't
1942 intersect any surface brushes.
1944 int PlayerStartZ(double x, double y)
1949 if(!gTri) return (int)zmax;
1951 t[0] = TriangleFromPoint(x,y);
1952 t[1] = TriangleFromPoint(x+PlayerBox[Game].x[0],y+PlayerBox[Game].y[0]);
1953 t[2] = TriangleFromPoint(x+PlayerBox[Game].x[0],y+PlayerBox[Game].y[1]);
1954 t[3] = TriangleFromPoint(x+PlayerBox[Game].x[1],y+PlayerBox[Game].y[0]);
1955 t[4] = TriangleFromPoint(x+PlayerBox[Game].x[1],y+PlayerBox[Game].y[1]);
1959 zt = (gTri[t[k]].plane.dist -
1960 gTri[t[k]].plane.normal[0]*x -
1961 gTri[t[k]].plane.normal[1]*y )/
1962 gTri[t[k]].plane.normal[2];
1965 return (int)(AtLeast(z,2.) - PlayerBox[Game].z[0]);
1967 //=============================================================
1968 void XYZtoV(XYZ *xyz, vec3 *v)
1970 v[0][0] = (vec)Nearest(xyz->p[0],2.);
1971 v[0][1] = (vec)Nearest(xyz->p[1],2.);
1972 v[0][2] = (vec)Nearest(xyz->p[2],2.);
1975 //=============================================================
1976 scene::Node* MakePatch(void)
1978 scene::Node* patch = Patch_AllocNode();
1980 patch->m_patch->SetShader(Texture[Game][0]);
1982 Node_getTraversable(h_worldspawn)->insert(patch);
1986 //=============================================================
1987 void MakeBrush(BRUSH *brush)
1989 NodePtr node(Brush_AllocNode());
1992 for(int i=0; i<brush->NumFaces; i++)
1994 _QERFaceData QERFaceData;
1995 if(!strncmp(brush->face[i].texture, "textures/", 9))
1996 strcpy(QERFaceData.m_TextureName,brush->face[i].texture);
1999 strcpy(QERFaceData.m_TextureName,"textures/");
2000 strcpy(QERFaceData.m_TextureName+9,brush->face[i].texture);
2002 QERFaceData.m_nContents = brush->face[i].Contents;
2003 QERFaceData.m_nFlags = brush->face[i].Surface;
2004 QERFaceData.m_nValue = brush->face[i].Value;
2005 QERFaceData.m_fShift[0] = brush->face[i].Shift[0];
2006 QERFaceData.m_fShift[1] = brush->face[i].Shift[1];
2007 QERFaceData.m_fRotate = brush->face[i].Rotate;
2008 QERFaceData.m_fScale[0] = brush->face[i].Scale[0];
2009 QERFaceData.m_fScale[1] = brush->face[i].Scale[1];
2010 QERFaceData.m_v1[0] = brush->face[i].v[0][0];
2011 QERFaceData.m_v1[1] = brush->face[i].v[0][1];
2012 QERFaceData.m_v1[2] = brush->face[i].v[0][2];
2013 QERFaceData.m_v2[0] = brush->face[i].v[1][0];
2014 QERFaceData.m_v2[1] = brush->face[i].v[1][1];
2015 QERFaceData.m_v2[2] = brush->face[i].v[1][2];
2016 QERFaceData.m_v3[0] = brush->face[i].v[2][0];
2017 QERFaceData.m_v3[1] = brush->face[i].v[2][1];
2018 QERFaceData.m_v3[2] = brush->face[i].v[2][2];
2019 QERFaceData.m_bBPrimit = false;
2020 (g_FuncTable.m_pfnAddFaceData)(vp,&QERFaceData);
2024 Node_getTraversable(h_func_group)->insert(node);
2026 //=============================================================
2027 void OpenFuncGroup()
2029 h_func_group = GlobalEntityCreator().createEntity("func_group");
2030 h_func_group->IncRef();
2032 h_func_group->m_entity->setkeyvalue("terrain", "1");
2034 //=============================================================
2035 void CloseFuncGroup()
2037 h_func_group->DecRef();
2038 if (g_FuncTable.m_pfnSysUpdateWindows != NULL)
2039 g_FuncTable.m_pfnSysUpdateWindows (W_ALL);