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
57 snapvalue = (int) value / SnapToGrid;
58 if ((long) value % SnapToGrid < (SnapToGrid / 2)) { // Snap Downwards if less than halfway between to grid units
59 value = snapvalue * SnapToGrid;
60 } else { // Snap Upwards if more than halfway between to grid units
61 value = (snapvalue + 1) * SnapToGrid;
66 // Hydra : snap-to-grid end
68 //=============================================================
71 if (WaveType == WAVE_BITMAP && !gbmp.colors) {
95 //=============================================================
103 int i, j, k1, k2, k3;
107 dh = (Hur - Hll) / NH;
108 dv = (Vur - Vll) / NV;
110 // Generate control points in pp array to give desired values currently
132 for (i = 0; i <= NH; i++) {
133 for (j = 0; j <= NV; j++) {
134 xyz[i][j].pp[k1] = xyz[i][j].p[k1];
135 xyz[i][j].pp[k2] = xyz[i][j].p[k2];
138 for (i = 0; i <= NH; i += 2) {
139 for (j = 0; j <= NV; j += 2) {
140 xyz[i][j].pp[k3] = xyz[i][j].p[k3];
143 for (i = 1; i < NH; i += 2) {
144 for (j = 0; j <= NV; j += 2) {
145 xyz[i][j].pp[k3] = (4 * xyz[i][j].p[k3] - xyz[i - 1][j].p[k3] - xyz[i + 1][j].p[k3]) / 2;
148 for (j = 1; j < NV; j += 2) {
149 for (i = 0; i <= NH; i += 2) {
150 xyz[i][j].pp[k3] = (4 * xyz[i][j].p[k3] - xyz[i][j - 1].p[k3] - xyz[i][j + 1].p[k3]) / 2;
153 for (i = 1; i < NH; i += 2) {
154 for (j = 1; j < NV; j += 2) {
155 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]
156 - xyz[i + 1][j - 1].p[k3] - 2 * xyz[i - 1][j].p[k3] - 2 * xyz[i + 1][j].p[k3]
157 - xyz[i - 1][j + 1].p[k3] - 2 * xyz[i][j + 1].p[k3] - xyz[i + 1][j + 1].p[k3]) / 4;
163 while (NH_remain > 1) {
164 if (((NH_remain - 1) % 14) == 0) {
166 } else if (((NH_remain - 1) % 12) == 0) {
168 } else if (((NH_remain - 1) % 10) == 0) {
170 } else if (((NH_remain - 1) % 8) == 0) {
172 } else if (((NH_remain - 1) % 6) == 0) {
174 } else if (((NH_remain - 1) % 4) == 0) {
176 } else if (((NH_remain - 1) % 2) == 0) {
178 } else if (NH_remain > 16) {
180 } else if (NH_remain > 4) {
185 while (NH_patch > 3 && (NH_patch - 1) * dh > 512) {
188 NH_remain -= (NH_patch - 1);
190 sprintf(szOops, "Oops... screwed up with NH=%d", NH);
191 g_FuncTable.m_pfnMessageBox(NULL, szOops, "Uh oh");
195 while (NV_remain > 1) {
196 if (((NV_remain - 1) % 14) == 0) {
198 } else if (((NV_remain - 1) % 12) == 0) {
200 } else if (((NV_remain - 1) % 10) == 0) {
202 } else if (((NV_remain - 1) % 8) == 0) {
204 } else if (((NV_remain - 1) % 6) == 0) {
206 } else if (((NV_remain - 1) % 4) == 0) {
208 } else if (((NV_remain - 1) % 2) == 0) {
210 } else if (NV_remain > 16) {
212 } else if (NV_remain > 4) {
217 while (NV_patch > 3 && (NV_patch - 1) * dh > 512) {
220 NV_remain -= (NV_patch - 1);
222 sprintf(szOops, "Oops... screwed up with NV=%d", NV);
223 g_FuncTable.m_pfnMessageBox(NULL, szOops, "Uh oh");
226 scene::Node *patch = MakePatch();
228 b->pPatch->setDims( NH_patch, NV_patch );
229 for ( i = 0; i < NH_patch; i++ )
236 ii = i0 + NH_patch - 1 - i;
241 for ( j = 0; j < NV_patch; j++ )
243 b->pPatch->ctrlAt( COL,i,j )[0] = (float)xyz[ii][j0 + j].pp[0];
244 b->pPatch->ctrlAt( COL,i,j )[1] = (float)xyz[ii][j0 + j].pp[1];
245 b->pPatch->ctrlAt( COL,i,j )[2] = (float)xyz[ii][j0 + j].pp[2];
246 b->pPatch->ctrlAt( COL,i,j )[3] = (float)i;
247 b->pPatch->ctrlAt( COL,i,j )[4] = (float)j;
250 b->pPatch->UpdateCachedData();
260 //=============================================================
270 vec3_t PlaneNormal, SurfNormal;
278 strcpy(surftext, Texture[Game][0]);
279 strcpy(sidetext, (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
280 strcpy(surftext2, (strlen(Texture[Game][2]) ? Texture[Game][2] : Texture[Game][0]));
282 // if surftext2 is identical to surftext, there's no need to
283 // check surface angle
284 if (!g_strcasecmp(surftext, surftext2)) {
288 Steep = (float) cos((double) SlantAngle / 57.2957795);
298 PlaneNormal[2] = -1.;
307 PlaneNormal[1] = -1.;
316 PlaneNormal[0] = -1.;
325 for (i = 0; i < NH; i++) {
326 for (j = 0; j < NV; j++) {
328 VectorCopy(xyz[i][j].p, v[0].p);
333 VectorCopy(xyz[i + 1][j].p, v[1].p);
334 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
337 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
338 VectorCopy(xyz[i + 1][j].p, v[2].p);
341 VectorCopy(xyz[i][j].p, v[0].p);
346 VectorCopy(xyz[i + 1][j].p, v[1].p);
347 VectorCopy(xyz[i][j + 1].p, v[2].p);
350 VectorCopy(xyz[i][j + 1].p, v[1].p);
351 VectorCopy(xyz[i + 1][j].p, v[2].p);
354 VectorCopy(v[0].p, v[3].p);
355 VectorCopy(v[1].p, v[4].p);
356 VectorCopy(v[2].p, v[5].p);
360 v[0].p[1] = backface;
361 v[1].p[1] = backface;
362 v[2].p[1] = backface;
366 v[3].p[0] = backface;
367 v[4].p[0] = backface;
368 v[5].p[0] = backface;
371 v[3].p[2] = backface;
372 v[4].p[2] = backface;
373 v[5].p[2] = backface;
376 brush.Number = i * NV * 2 + j * 2;
378 XYZtoV(&v[0], &brush.face[0].v[0]);
379 XYZtoV(&v[3], &brush.face[0].v[1]);
380 XYZtoV(&v[4], &brush.face[0].v[2]);
381 strcpy(brush.face[0].texture,
382 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
383 brush.face[0].Shift[0] = (float) TexOffset[0];
384 brush.face[0].Shift[1] = (float) TexOffset[1];
385 brush.face[0].Rotate = 0.;
386 brush.face[0].Scale[0] = (float) TexScale[0];
387 brush.face[0].Scale[1] = (float) TexScale[1];
388 brush.face[0].Contents = contents;
389 brush.face[0].Surface = surface[1];
390 brush.face[0].Value = 0;
392 XYZtoV(&v[1], &brush.face[1].v[0]);
393 XYZtoV(&v[4], &brush.face[1].v[1]);
394 XYZtoV(&v[5], &brush.face[1].v[2]);
395 strcpy(brush.face[1].texture,
396 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
397 brush.face[1].Shift[0] = (float) TexOffset[0];
398 brush.face[1].Shift[1] = (float) TexOffset[1];
399 brush.face[1].Rotate = 0.;
400 brush.face[1].Scale[0] = (float) TexScale[0];
401 brush.face[1].Scale[1] = (float) TexScale[1];
402 brush.face[1].Contents = contents;
403 brush.face[1].Surface = surface[1];
404 brush.face[1].Value = 0;
406 XYZtoV(&v[2], &brush.face[2].v[0]);
407 XYZtoV(&v[5], &brush.face[2].v[1]);
408 XYZtoV(&v[3], &brush.face[2].v[2]);
409 strcpy(brush.face[2].texture,
410 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
411 brush.face[2].Shift[0] = (float) TexOffset[0];
412 brush.face[2].Shift[1] = (float) TexOffset[1];
413 brush.face[2].Rotate = 0.;
414 brush.face[2].Scale[0] = (float) TexScale[0];
415 brush.face[2].Scale[1] = (float) TexScale[1];
416 brush.face[2].Contents = contents;
417 brush.face[2].Surface = surface[1];
418 brush.face[2].Value = 0;
420 if (CheckAngle && (Plane == PLANE_XZ0 || Plane == PLANE_XZ1)) {
421 XYZVectorSubtract(v[4].p, v[3].p, t[0]);
422 XYZVectorSubtract(v[5].p, v[4].p, t[1]);
423 CrossProduct(t[0], t[1], SurfNormal);
424 VectorNormalize(SurfNormal, SurfNormal);
425 if (DotProduct(SurfNormal, PlaneNormal) < Steep) {
426 strcpy(surft, surftext2);
429 strcpy(surft, surftext);
433 strcpy(surft, surftext);
437 XYZtoV(&v[3], &brush.face[3].v[0]);
438 XYZtoV(&v[5], &brush.face[3].v[1]);
439 XYZtoV(&v[4], &brush.face[3].v[2]);
440 strcpy(brush.face[3].texture,
441 (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext));
442 brush.face[3].Shift[0] = (float) TexOffset[0];
443 brush.face[3].Shift[1] = (float) TexOffset[1];
444 brush.face[3].Rotate = 0.;
445 brush.face[3].Scale[0] = (float) TexScale[0];
446 brush.face[3].Scale[1] = (float) TexScale[1];
447 brush.face[3].Contents = contents;
448 brush.face[3].Surface = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1]);
449 brush.face[3].Value = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0);
451 if (CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1) {
452 XYZVectorSubtract(v[2].p, v[0].p, t[0]);
453 XYZVectorSubtract(v[1].p, v[2].p, t[1]);
454 CrossProduct(t[0], t[1], SurfNormal);
455 VectorNormalize(SurfNormal, SurfNormal);
456 if (DotProduct(SurfNormal, PlaneNormal) < Steep) {
457 strcpy(surft, surftext2);
460 strcpy(surft, surftext);
464 strcpy(surft, surftext);
468 XYZtoV(&v[0], &brush.face[4].v[0]);
469 XYZtoV(&v[1], &brush.face[4].v[1]);
470 XYZtoV(&v[2], &brush.face[4].v[2]);
471 strcpy(brush.face[4].texture,
472 (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft));
473 brush.face[4].Shift[0] = (float) TexOffset[0];
474 brush.face[4].Shift[1] = (float) TexOffset[1];
475 brush.face[4].Rotate = 0.;
476 brush.face[4].Scale[0] = (float) TexScale[0];
477 brush.face[4].Scale[1] = (float) TexScale[1];
478 brush.face[4].Contents = contents;
479 brush.face[4].Surface = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf);
480 brush.face[4].Value = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2);
484 VectorCopy(xyz[i][j + 1].p, v[0].p);
489 VectorCopy(xyz[i][j].p, v[1].p);
490 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
493 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
494 VectorCopy(xyz[i][j].p, v[2].p);
497 VectorCopy(xyz[i][j + 1].p, v[0].p);
502 VectorCopy(xyz[i + 1][j].p, v[1].p);
503 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
506 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
507 VectorCopy(xyz[i + 1][j].p, v[2].p);
510 VectorCopy(v[0].p, v[3].p);
511 VectorCopy(v[1].p, v[4].p);
512 VectorCopy(v[2].p, v[5].p);
516 v[0].p[1] = backface;
517 v[1].p[1] = backface;
518 v[2].p[1] = backface;
522 v[3].p[0] = backface;
523 v[4].p[0] = backface;
524 v[5].p[0] = backface;
527 v[3].p[2] = backface;
528 v[4].p[2] = backface;
529 v[5].p[2] = backface;
531 brush.Number = i * NV * 2 + j * 2 + 1;
533 XYZtoV(&v[0], &brush.face[0].v[0]);
534 XYZtoV(&v[3], &brush.face[0].v[1]);
535 XYZtoV(&v[4], &brush.face[0].v[2]);
536 strcpy(brush.face[0].texture,
537 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
538 brush.face[0].Shift[0] = (float) TexOffset[0];
539 brush.face[0].Shift[1] = (float) TexOffset[1];
540 brush.face[0].Rotate = 0.;
541 brush.face[0].Scale[0] = (float) TexScale[0];
542 brush.face[0].Scale[1] = (float) TexScale[1];
543 brush.face[0].Contents = contents;
544 brush.face[0].Surface = surface[1];
545 brush.face[0].Value = 0;
547 XYZtoV(&v[1], &brush.face[1].v[0]);
548 XYZtoV(&v[4], &brush.face[1].v[1]);
549 XYZtoV(&v[5], &brush.face[1].v[2]);
550 strcpy(brush.face[1].texture,
551 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
552 brush.face[1].Shift[0] = (float) TexOffset[0];
553 brush.face[1].Shift[1] = (float) TexOffset[1];
554 brush.face[1].Rotate = 0.;
555 brush.face[1].Scale[0] = (float) TexScale[0];
556 brush.face[1].Scale[1] = (float) TexScale[1];
557 brush.face[1].Contents = contents;
558 brush.face[1].Surface = surface[1];
559 brush.face[1].Value = 0;
561 XYZtoV(&v[2], &brush.face[2].v[0]);
562 XYZtoV(&v[5], &brush.face[2].v[1]);
563 XYZtoV(&v[3], &brush.face[2].v[2]);
564 strcpy(brush.face[2].texture,
565 (strlen(Texture[Game][1]) ? Texture[Game][1] : Texture[Game][0]));
566 brush.face[2].Shift[0] = (float) TexOffset[0];
567 brush.face[2].Shift[1] = (float) TexOffset[1];
568 brush.face[2].Rotate = 0.;
569 brush.face[2].Scale[0] = (float) TexScale[0];
570 brush.face[2].Scale[1] = (float) TexScale[1];
571 brush.face[2].Contents = contents;
572 brush.face[2].Surface = surface[1];
573 brush.face[2].Value = 0;
575 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) {
581 strcpy(surft, surftext2);
584 strcpy(surft, surftext);
588 strcpy(surft, surftext);
591 XYZtoV(&v[3], &brush.face[3].v[0]);
592 XYZtoV(&v[5], &brush.face[3].v[1]);
593 XYZtoV(&v[4], &brush.face[3].v[2]);
594 strcpy(brush.face[3].texture,
595 (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext));
596 brush.face[3].Shift[0] = (float) TexOffset[0];
597 brush.face[3].Shift[1] = (float) TexOffset[1];
598 brush.face[3].Rotate = 0.;
599 brush.face[3].Scale[0] = (float) TexScale[0];
600 brush.face[3].Scale[1] = (float) TexScale[1];
601 brush.face[3].Contents = contents;
602 brush.face[3].Surface = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1]);
603 brush.face[3].Value = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0);
605 if (CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1) {
606 XYZVectorSubtract(v[2].p, v[0].p, t[0]);
607 XYZVectorSubtract(v[1].p, v[2].p, t[1]);
608 CrossProduct(t[0], t[1], SurfNormal);
609 VectorNormalize(SurfNormal, SurfNormal);
610 if (DotProduct(SurfNormal, PlaneNormal) < Steep) {
611 strcpy(surft, surftext2);
614 strcpy(surft, surftext);
618 strcpy(surft, surftext);
621 XYZtoV(&v[0], &brush.face[4].v[0]);
622 XYZtoV(&v[1], &brush.face[4].v[1]);
623 XYZtoV(&v[2], &brush.face[4].v[2]);
624 strcpy(brush.face[4].texture,
625 (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft));
626 brush.face[4].Shift[0] = (float) TexOffset[0];
627 brush.face[4].Shift[1] = (float) TexOffset[1];
628 brush.face[4].Rotate = 0.;
629 brush.face[4].Scale[0] = (float) TexScale[0];
630 brush.face[4].Scale[1] = (float) TexScale[1];
631 brush.face[4].Contents = contents;
632 brush.face[4].Surface = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf);
633 brush.face[4].Value = (Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2);
640 if (AddHints || GimpHints) {
641 int detail, i1, j1, N;
646 strcpy(hint, "HINT");
647 strcpy(skip, "HINT");
650 strcpy(hint, "generic/misc/hint");
651 strcpy(skip, "generic/misc/skip");
654 strcpy(hint, "general/hint");
655 strcpy(skip, "general/hint"); // Heretic2 doesn't have a skip texture
658 strcpy(hint, "common/0_hint");
659 strcpy(skip, "common/0_skip");
662 strcpy(hint, "hint");
663 strcpy(skip, "hint");
666 strcpy(hint, "textures/common/hint");
667 strcpy(skip, "textures/common/skip");
670 strcpy(hint, "e1u1/hint");
671 strcpy(skip, "e1u1/skip");
677 detail = CONTENTS_DETAIL;
679 for (i = 0; i < NH; i++) {
682 for (j = 0; j < NV; j++) {
684 // For detail hint brushes, no need to use a hint brush over
685 // EVERY grid square... it would be redundant. Instead use
686 // a checkerboard pattern
693 VectorCopy(xyz[i][j].p, v[0].p);
698 VectorCopy(xyz[i1][j].p, v[1].p);
699 VectorCopy(xyz[i1][j1].p, v[2].p);
700 VectorCopy(xyz[i][j1].p, v[3].p);
703 VectorCopy(xyz[i][j1].p, v[1].p);
704 VectorCopy(xyz[i1][j1].p, v[2].p);
705 VectorCopy(xyz[i1][j].p, v[3].p);
708 VectorCopy(v[0].p, v[4].p);
709 VectorCopy(v[1].p, v[5].p);
710 VectorCopy(v[2].p, v[6].p);
711 VectorCopy(v[3].p, v[7].p);
715 front = LessThan(zmin, 32.);
716 v[4].p[2] = backface;
717 v[5].p[2] = backface;
718 v[6].p[2] = backface;
719 v[7].p[2] = backface;
722 front = MoreThan(ymax, 32.);
723 v[0].p[1] = backface;
724 v[1].p[1] = backface;
725 v[2].p[1] = backface;
726 v[3].p[1] = backface;
729 front = LessThan(ymin, 32.);
730 v[0].p[1] = backface;
731 v[1].p[1] = backface;
732 v[2].p[1] = backface;
733 v[3].p[1] = backface;
736 front = MoreThan(xmax, 32.);
737 v[4].p[0] = backface;
738 v[5].p[0] = backface;
739 v[6].p[0] = backface;
740 v[7].p[0] = backface;
743 front = LessThan(xmin, 32.);
744 v[4].p[0] = backface;
745 v[5].p[0] = backface;
746 v[6].p[0] = backface;
747 v[7].p[0] = backface;
750 front = MoreThan(zmax, 32.);
751 v[4].p[2] = backface;
752 v[5].p[2] = backface;
753 v[6].p[2] = backface;
754 v[7].p[2] = backface;
761 v[5].p[1] = v[4].p[1];
762 v[6].p[1] = v[4].p[1];
763 v[7].p[1] = v[4].p[1];
768 v[1].p[0] = v[0].p[0];
769 v[2].p[0] = v[0].p[0];
770 v[3].p[0] = v[0].p[0];
774 v[1].p[2] = v[0].p[2];
775 v[2].p[2] = v[0].p[2];
776 v[3].p[2] = v[0].p[2];
781 XYZtoV(&v[0], &brush.face[0].v[0]);
782 XYZtoV(&v[1], &brush.face[0].v[1]);
783 XYZtoV(&v[2], &brush.face[0].v[2]);
784 strcpy(brush.face[0].texture, skip);
785 brush.face[0].Shift[0] = 0.;
786 brush.face[0].Shift[1] = 0.;
787 brush.face[0].Rotate = 0.;
788 brush.face[0].Scale[0] = 1.;
789 brush.face[0].Scale[1] = 1.;
790 brush.face[0].Contents = detail;
791 brush.face[0].Surface = SURF_SKIP;
792 brush.face[0].Value = 0;
794 XYZtoV(&v[4], &brush.face[1].v[0]);
795 XYZtoV(&v[7], &brush.face[1].v[1]);
796 XYZtoV(&v[6], &brush.face[1].v[2]);
797 strcpy(brush.face[1].texture, skip);
798 brush.face[1].Shift[0] = 0.;
799 brush.face[1].Shift[1] = 0.;
800 brush.face[1].Rotate = 0.;
801 brush.face[1].Scale[0] = 1.;
802 brush.face[1].Scale[1] = 1.;
803 brush.face[1].Contents = detail;
804 brush.face[1].Surface = SURF_SKIP;
805 brush.face[1].Value = 0;
807 XYZtoV(&v[0], &brush.face[2].v[0]);
808 XYZtoV(&v[4], &brush.face[2].v[1]);
809 XYZtoV(&v[5], &brush.face[2].v[2]);
810 strcpy(brush.face[2].texture, hint);
811 brush.face[2].Shift[0] = 0.;
812 brush.face[2].Shift[1] = 0.;
813 brush.face[2].Rotate = 0.;
814 brush.face[2].Scale[0] = 1.;
815 brush.face[2].Scale[1] = 1.;
816 brush.face[2].Contents = detail;
817 brush.face[2].Surface = SURF_HINT;
818 brush.face[2].Value = 0;
820 XYZtoV(&v[1], &brush.face[3].v[0]);
821 XYZtoV(&v[5], &brush.face[3].v[1]);
822 XYZtoV(&v[6], &brush.face[3].v[2]);
823 strcpy(brush.face[3].texture, hint);
824 brush.face[3].Shift[0] = 0.;
825 brush.face[3].Shift[1] = 0.;
826 brush.face[3].Rotate = 0.;
827 brush.face[3].Scale[0] = 1.;
828 brush.face[3].Scale[1] = 1.;
829 brush.face[3].Contents = detail;
830 brush.face[3].Surface = SURF_HINT;
831 brush.face[3].Value = 0;
833 XYZtoV(&v[2], &brush.face[4].v[0]);
834 XYZtoV(&v[6], &brush.face[4].v[1]);
835 XYZtoV(&v[7], &brush.face[4].v[2]);
836 strcpy(brush.face[4].texture, hint);
837 brush.face[4].Shift[0] = 0.;
838 brush.face[4].Shift[1] = 0.;
839 brush.face[4].Rotate = 0.;
840 brush.face[4].Scale[0] = 1.;
841 brush.face[4].Scale[1] = 1.;
842 brush.face[4].Contents = detail;
843 brush.face[4].Surface = SURF_HINT;
844 brush.face[4].Value = 0;
846 XYZtoV(&v[3], &brush.face[5].v[0]);
847 XYZtoV(&v[7], &brush.face[5].v[1]);
848 XYZtoV(&v[4], &brush.face[5].v[2]);
849 strcpy(brush.face[5].texture, hint);
850 brush.face[5].Shift[0] = 0.;
851 brush.face[5].Shift[1] = 0.;
852 brush.face[5].Rotate = 0.;
853 brush.face[5].Scale[0] = 1.;
854 brush.face[5].Scale[1] = 1.;
855 brush.face[5].Contents = detail;
856 brush.face[5].Surface = SURF_HINT;
857 brush.face[5].Value = 0;
866 // these brush parameters never change
868 for (i = 0; i < 6; i++) {
869 strcpy(brush.face[i].texture, hint);
870 brush.face[i].Shift[0] = 0.;
871 brush.face[i].Shift[1] = 0.;
872 brush.face[i].Rotate = 0.;
873 brush.face[i].Scale[0] = 1.;
874 brush.face[i].Scale[1] = 1.;
875 brush.face[i].Contents = 0;
876 brush.face[i].Surface = SURF_HINT;
877 brush.face[i].Value = 0;
879 for (i = 0; i < NH; i++) {
880 for (j = 0; j < NV; j++) {
881 for (k = 0; k < 2; k++) {
884 VectorCopy(xyz[i][j].p, v[0].p);
889 VectorCopy(xyz[i + 1][j].p, v[1].p);
890 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
893 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
894 VectorCopy(xyz[i + 1][j].p, v[2].p);
897 VectorCopy(xyz[i][j].p, v[0].p);
902 VectorCopy(xyz[i + 1][j].p, v[1].p);
903 VectorCopy(xyz[i][j + 1].p, v[2].p);
906 VectorCopy(xyz[i][j + 1].p, v[1].p);
907 VectorCopy(xyz[i + 1][j].p, v[2].p);
912 VectorCopy(xyz[i][j + 1].p, v[0].p);
917 VectorCopy(xyz[i][j].p, v[1].p);
918 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
921 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
922 VectorCopy(xyz[i][j].p, v[2].p);
925 VectorCopy(xyz[i][j + 1].p, v[0].p);
930 VectorCopy(xyz[i + 1][j].p, v[1].p);
931 VectorCopy(xyz[i + 1][j + 1].p, v[2].p);
934 VectorCopy(xyz[i + 1][j + 1].p, v[1].p);
935 VectorCopy(xyz[i + 1][j].p, v[2].p);
939 VectorCopy(v[0].p, v[3].p);
940 VectorCopy(v[1].p, v[4].p);
941 VectorCopy(v[2].p, v[5].p);
944 v[0].p[2] += HINT_OFFSET;
945 v[1].p[2] += HINT_OFFSET;
946 v[2].p[2] += HINT_OFFSET;
947 // v[3].p[2] = backface;
948 // v[4].p[2] = backface;
949 // v[5].p[2] = backface;
952 v[0].p[2] -= HINT_OFFSET;
953 v[1].p[2] -= HINT_OFFSET;
954 v[2].p[2] -= HINT_OFFSET;
955 // v[3].p[2] = backface;
956 // v[4].p[2] = backface;
957 // v[5].p[2] = backface;
960 // v[0].p[1] = backface;
961 // v[1].p[1] = backface;
962 // v[2].p[1] = backface;
963 v[3].p[1] += HINT_OFFSET;
964 v[4].p[1] += HINT_OFFSET;
965 v[5].p[1] += HINT_OFFSET;
968 // v[0].p[1] = backface;
969 // v[1].p[1] = backface;
970 // v[2].p[1] = backface;
971 v[3].p[1] -= HINT_OFFSET;
972 v[4].p[1] -= HINT_OFFSET;
973 v[5].p[1] -= HINT_OFFSET;
976 v[0].p[0] += HINT_OFFSET;
977 v[1].p[0] += HINT_OFFSET;
978 v[2].p[0] += HINT_OFFSET;
979 // v[3].p[0] = backface;
980 // v[4].p[0] = backface;
981 // v[5].p[0] = backface;
984 v[0].p[0] -= HINT_OFFSET;
985 v[1].p[0] -= HINT_OFFSET;
986 v[2].p[0] -= HINT_OFFSET;
987 // v[3].p[0] = backface;
988 // v[4].p[0] = backface;
989 // v[5].p[0] = backface;
993 XYZtoV(&v[0], &brush.face[0].v[0]);
994 XYZtoV(&v[3], &brush.face[0].v[1]);
995 XYZtoV(&v[4], &brush.face[0].v[2]);
997 XYZtoV(&v[1], &brush.face[1].v[0]);
998 XYZtoV(&v[4], &brush.face[1].v[1]);
999 XYZtoV(&v[5], &brush.face[1].v[2]);
1001 XYZtoV(&v[2], &brush.face[2].v[0]);
1002 XYZtoV(&v[5], &brush.face[2].v[1]);
1003 XYZtoV(&v[3], &brush.face[2].v[2]);
1005 XYZtoV(&v[3], &brush.face[3].v[0]);
1006 XYZtoV(&v[5], &brush.face[3].v[1]);
1007 XYZtoV(&v[4], &brush.face[3].v[2]);
1009 XYZtoV(&v[0], &brush.face[4].v[0]);
1010 XYZtoV(&v[1], &brush.face[4].v[1]);
1011 XYZtoV(&v[2], &brush.face[4].v[2]);
1018 } // endif AddHints==1
1024 //=============================================================
1027 extern void MapOut(int, int, NODE *, TRI *);
1028 extern bool SingleBrushSelected;
1031 if (!ValidSurface()) {
1035 ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
1036 SetCursor(ghCursorCurrent);
1039 if ( SingleBrushSelected ) {
1040 g_FuncTable.m_pfnDeleteSelection();
1047 if (Game == QUAKE3 && UsePatches != 0) {
1051 if (Decimate > 0 && (Game != QUAKE3 || UsePatches == 0)) {
1052 MapOut(gNumNodes, gNumTris, gNode, gTri);
1054 ghCursorCurrent = ghCursorDefault;
1055 SetCursor(ghCursorCurrent);
1061 // HL doesn't have detail property
1062 if ((Game != HALFLIFE) && UseDetail) {
1063 contents += CONTENTS_DETAIL;
1065 // HL and Q3 don't have ladder property
1066 if ((Game != HALFLIFE && Game != QUAKE3) && UseLadder) {
1067 contents += CONTENTS_LADDER;
1069 // Genesis requires solid property to be set explicitly
1070 if (Game == GENESIS3D) {
1071 contents |= CONTENTS_SOLID;
1073 // Heretic 2 uses different sounds (in surface props) for different texture types
1074 if (Game == HERETIC2) {
1075 surface[0] = GetDefSurfaceProps(Texture[Game][0]);
1076 surface[1] = GetDefSurfaceProps(Texture[Game][1]);
1077 surface[2] = GetDefSurfaceProps(Texture[Game][2]);
1083 if (Game != QUAKE3 || UsePatches == 0) {
1088 ghCursorCurrent = ghCursorDefault;
1089 SetCursor(ghCursorCurrent);
1093 //=============================================================
1096 extern void MakeDecimatedMap(int *, int *, NODE **, TRI **);
1100 double a, v, h, ha, va;
1101 double delta, dr, rate;
1102 double range, maxrange;
1111 if (!ValidSurface()) {
1118 dh = (Hur - Hll) / NH;
1119 dv = (Vur - Vll) / NV;
1122 for (i = 0; i <= NH; i++) {
1123 for (j = 0; j <= NV; j++) {
1127 xyz[i][j].p[0] = Hll + i * dh;
1128 xyz[i][j].p[2] = Vll + j * dv;
1132 xyz[i][j].p[1] = Hll + i * dh;
1133 xyz[i][j].p[2] = Vll + j * dv;
1136 xyz[i][j].p[0] = Hll + i * dh;
1137 xyz[i][j].p[1] = Vll + j * dv;
1142 if (WaveType == WAVE_BITMAP) {
1143 GenerateBitmapMapping();
1146 else if(WaveType == WAVE_FORMULA)
1150 // Initialize Z values using bilinear interpolation
1151 for (i = 0; i <= NH; i++) {
1152 zl = Z00 + i * (Z10 - Z00) / NH;
1153 zu = Z01 + i * (Z11 - Z01) / NH;
1157 for (j = 0; j <= NV; j++) {
1158 xyz[i][j].p[1] = zl + j * (zu - zl) / NV;
1163 for (j = 0; j <= NV; j++) {
1164 xyz[i][j].p[0] = zl + j * (zu - zl) / NV;
1168 for (j = 0; j <= NV; j++) {
1169 xyz[i][j].p[2] = zl + j * (zu - zl) / NV;
1178 NHalfcycles = (int) ((Hur - Hll) / (WaveLength / 2.));
1179 NHalfcycles = max(NHalfcycles, 1);
1180 wh = 2. * (Hur - Hll) / NHalfcycles;
1181 NHalfcycles = (int) ((Vur - Vll) / (WaveLength / 2.));
1182 wv = 2. * (Vur - Vll) / NHalfcycles;
1183 NHalfcycles = max(NHalfcycles, 1);
1197 for (i = i0; i <= i1; i++) {
1199 ha = ((h - Hll) / wh) * 2. * PI - PI / 2.;
1200 for (j = j0; j <= j1; j++) {
1202 va = ((v - Vll) / wv) * 2. * PI;
1203 a = Amplitude * cos(ha) * sin(va);
1206 xyz[i][j].p[2] -= a;
1209 xyz[i][j].p[1] += a;
1212 xyz[i][j].p[1] -= a;
1215 xyz[i][j].p[0] += a;
1218 xyz[i][j].p[0] -= a;
1221 xyz[i][j].p[2] += a;
1226 case WAVE_HCYLINDER:
1227 for (i = 0; i <= NH; i++) {
1229 ha = ((h - Hll) / WaveLength) * 2. * PI - PI / 2.;
1230 for (j = 0; j <= NV; j++) {
1231 a = Amplitude * cos(ha);
1234 xyz[i][j].p[2] -= a;
1237 xyz[i][j].p[1] += a;
1240 xyz[i][j].p[1] -= a;
1243 xyz[i][j].p[0] += a;
1246 xyz[i][j].p[0] -= a;
1249 xyz[i][j].p[2] += a;
1254 case WAVE_VCYLINDER:
1255 for (i = 0; i <= NH; i++) {
1257 for (j = 0; j <= NV; j++) {
1259 va = ((v - Vll) / WaveLength) * 2. * PI;
1260 a = Amplitude * sin(va);
1263 xyz[i][j].p[2] -= a;
1266 xyz[i][j].p[1] += a;
1269 xyz[i][j].p[1] -= a;
1272 xyz[i][j].p[0] += a;
1275 xyz[i][j].p[0] -= a;
1278 xyz[i][j].p[2] += a;
1283 case WAVE_ROUGH_ONLY:
1288 if (WaveType != WAVE_ROUGH_ONLY) {
1290 for (i = 0; i <= NH; i++) {
1291 for (j = 0; j <= NV; j++) {
1292 if (xyz[i][j].fixed) {
1296 xyz[i][j].p[1] = xyz[i][j].fixed_value;
1300 xyz[i][j].p[0] = xyz[i][j].fixed_value;
1303 xyz[i][j].p[2] = xyz[i][j].fixed_value;
1306 if (xyz[i][j].range > 0) {
1307 maxrange = pow(xyz[i][j].range, 2); // so we don't have to do sqrt's
1308 i0 = i - (int) (floor(xyz[i][j].range / dh - 0.5) + 1);
1310 j0 = j - (int) (floor(xyz[i][j].range / dv - 0.5) + 1);
1314 i1 = min(i1, NH - 1);
1316 j1 = min(j1, NV - 1);
1323 for (ii = i0; ii <= i1; ii++) {
1324 for (jj = j0; jj <= j1; jj++) {
1325 if (ii == i && jj == j) {
1328 range = pow(dh * (i - ii), 2) + pow(dv * (j - jj), 2);
1329 if (range > maxrange) {
1332 dr = sqrt(range / maxrange);
1333 rate = max(-30., min(xyz[i][j].rate, 30.));
1335 delta = pow((1. - dr), -rate + 1.);
1336 } else if (rate < 0.) {
1337 delta = (1 + rate) * 0.5 * (cos(dr * PI) + 1.0) -
1338 rate * pow((1. - dr), 2);
1339 } else if (rate == 0.) {
1340 delta = 0.5 * (cos(dr * PI) + 1.0);
1341 } else if (rate <= 1.) {
1342 delta = (1. - rate) * 0.5 * (cos(dr * PI) + 1.0) +
1343 rate * (1. - pow(dr, 2));
1345 delta = 1. - pow(dr, rate + 1);
1350 xyz[ii][jj].p[1] += (xyz[i][j].p[1] - xyz[ii][jj].p[1]) * delta;
1354 xyz[ii][jj].p[0] += (xyz[i][j].p[0] - xyz[ii][jj].p[0]) * delta;
1357 xyz[ii][jj].p[2] += (xyz[i][j].p[2] - xyz[ii][jj].p[2]) * delta;
1367 if ((Roughness > 0.) && (WaveType != WAVE_ROUGH_ONLY)) {
1368 for (i = 0; i <= NH; i++) {
1369 for (j = 0; j <= NV; j++) {
1370 if (CanEdit(i, j) && !xyz[i][j].fixed) {
1374 xyz[i][j].p[1] += -Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX);
1378 xyz[i][j].p[0] += -Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX);
1381 xyz[i][j].p[2] += -Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX);
1384 r = rand(); // We still get a random number, so that fixing points
1386 // doesn't change the sequence.
1392 for (i = 0; i <= NH; i++) {
1393 for (j = 0; j <= NV; j++) {
1394 for (k = 0; k < 3; k++) {
1395 xyz[i][j].p[k] = Nearest(xyz[i][j].p[k], 2.0);
1400 // Find minima and maxima
1408 ymin = xyz[0][0].p[1];
1410 for (i = 0; i <= NH; i++) {
1411 for (j = 0; j <= NV; j++) {
1412 ymin = min(ymin, xyz[i][j].p[1]);
1413 ymax = max(ymax, xyz[i][j].p[1]);
1423 xmin = xyz[0][0].p[0];
1425 for (i = 0; i <= NH; i++) {
1426 for (j = 0; j <= NV; j++) {
1427 xmin = min(xmin, xyz[i][j].p[0]);
1428 xmax = max(xmax, xyz[i][j].p[0]);
1438 zmin = xyz[0][0].p[2];
1440 for (i = 0; i <= NH; i++) {
1441 for (j = 0; j <= NV; j++) {
1442 zmin = min(zmin, xyz[i][j].p[2]);
1443 zmax = max(zmax, xyz[i][j].p[2]);
1448 xmin = Nearest(xmin, 2.);
1449 xmax = Nearest(xmax, 2.);
1450 ymin = Nearest(ymin, 2.);
1451 ymax = Nearest(ymax, 2.);
1452 zmin = Nearest(zmin, 2.);
1453 zmax = Nearest(zmax, 2.);
1457 backface = AtLeast(zmax + 32., 32.);
1460 backface = NoMoreThan(ymin - 32., 32.);
1463 backface = AtLeast(ymax + 32., 32.);
1466 backface = NoMoreThan(xmin - 32., 32.);
1469 backface = AtLeast(xmax + 32., 32.);
1472 backface = NoMoreThan(zmin - 32., 32.);
1478 gNode = (NODE *) NULL;
1479 gTri = (TRI *) NULL;
1481 if (Decimate > 0 && (Game != QUAKE3 || UsePatches == 0)) {
1482 MakeDecimatedMap(&gNumNodes, &gNumTris, &gNode, &gTri);
1484 gNumNodes = (NH + 1) * (NV + 1);
1485 gNumTris = NH * NV * 2;
1486 gNode = (NODE *) malloc(gNumNodes * sizeof(NODE));
1487 gTri = (TRI *) malloc(gNumTris * sizeof(TRI));
1489 for (i = 0, N = 0; i <= NH; i++) {
1490 for (j = 0; j <= NV; j++, N++) {
1492 gNode[N].p[0] = (float) xyz[i][j].p[0];
1493 gNode[N].p[1] = (float) xyz[i][j].p[1];
1494 gNode[N].p[2] = (float) xyz[i][j].p[2];
1498 for (i = 0; i < NH; i++) {
1499 for (j = 0; j < NV; j++) {
1500 k = i * NV * 2 + j * 2;
1506 gTri[k].v[0] = i * (NV + 1) + j;
1507 gTri[k].v[1] = (i + 1) * (NV + 1) + j + 1;
1508 gTri[k].v[2] = (i + 1) * (NV + 1) + j;
1509 gTri[k + 1].v[0] = i * (NV + 1) + j;
1510 gTri[k + 1].v[1] = i * (NV + 1) + j + 1;
1511 gTri[k + 1].v[2] = (i + 1) * (NV + 1) + j + 1;
1514 gTri[k].v[0] = i * (NV + 1) + j;
1515 gTri[k].v[1] = (i + 1) * (NV + 1) + j;
1516 gTri[k].v[2] = (i + 1) * (NV + 1) + j + 1;
1517 gTri[k + 1].v[0] = i * (NV + 1) + j;
1518 gTri[k + 1].v[1] = (i + 1) * (NV + 1) + j + 1;
1519 gTri[k + 1].v[2] = i * (NV + 1) + j + 1;
1526 gTri[k].v[0] = i * (NV + 1) + j;
1527 gTri[k].v[1] = i * (NV + 1) + j + 1;
1528 gTri[k].v[2] = (i + 1) * (NV + 1) + j;
1529 gTri[k + 1].v[0] = (i + 1) * (NV + 1) + j;
1530 gTri[k + 1].v[1] = i * (NV + 1) + j + 1;
1531 gTri[k + 1].v[2] = (i + 1) * (NV + 1) + j + 1;
1534 gTri[k].v[0] = i * (NV + 1) + j;
1535 gTri[k].v[1] = (i + 1) * (NV + 1) + j;
1536 gTri[k].v[2] = i * (NV + 1) + j + 1;
1537 gTri[k + 1].v[0] = (i + 1) * (NV + 1) + j;
1538 gTri[k + 1].v[1] = (i + 1) * (NV + 1) + j + 1;
1539 gTri[k + 1].v[2] = i * (NV + 1) + j + 1;
1546 sprintf(CSV,"csv%03d.csv",Decimate);
1548 for(i=0; i<gNumNodes; i++)
1551 fprintf(f,"%g,%g,%g\n",gNode[i].p[0],gNode[i].p[1],gNode[i].p[2]);
1555 for (i = 0; i < gNumTris; i++) {
1556 PlaneFromPoints(gNode[gTri[i].v[0]].p,
1557 gNode[gTri[i].v[1]].p,
1558 gNode[gTri[i].v[2]].p,
1562 // Hydra: snap-to-grid begin
1563 if (SnapToGrid > 0) {
1564 for (i = 0; i < NH; i++) {
1565 for (j = 0; j < NV; j++) {
1569 xyz[i][j].p[1] = CalculateSnapValue(xyz[i][j].p[1]);
1573 xyz[i][j].p[0] = CalculateSnapValue(xyz[i][j].p[0]);
1576 xyz[i][j].p[2] = CalculateSnapValue(xyz[i][j].p[2]);
1581 // Hydra: snap-to-grid end
1584 //=============================================================
1585 double Nearest(double x, double dx)
1589 xx = (double) (floor(x / dx - 0.5) + 1.) * dx;
1590 if (fabs(xx) < dx / 2) {
1596 //=============================================================
1597 double NoMoreThan(double x, double dx)
1601 xx = (double) (floor(x / dx - 0.5) + 1.) * dx;
1608 //=============================================================
1609 double AtLeast(double x, double dx)
1613 xx = (double) (floor(x / dx - 0.5) + 1.) * dx;
1620 //=============================================================
1621 double LessThan(double x, double dx)
1625 xx = (double) (floor(x / dx - 0.5) + 1.) * dx;
1632 //=============================================================
1633 double MoreThan(double x, double dx)
1637 xx = (double) (floor(x / dx - 0.5) + 1.) * dx;
1644 //=============================================================
1645 void SubdividePlasma(int i0, int j0, int i1, int j1)
1649 double r; // NOTE: This is used to keep the random number sequence the same
1650 // when we fix a point. If we did NOT do this, then simply
1651 // fixing a point at its current value would change the entire
1657 if (!xyz[i][j0].done) {
1658 xyz[i][j0].pp[2] = xyz[i0][j0].pp[2] +
1659 (xyz[i1][j0].pp[2] - xyz[i0][j0].pp[2]) * (double) (i - i0) / (double) (i1 - i0) +
1660 ((double) (i - i0)) *
1661 (-Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX));
1662 xyz[i][j0].done = 1;
1666 if ((j1 > j0) && (!xyz[i][j1].done)) {
1667 xyz[i][j1].pp[2] = xyz[i0][j1].pp[2] +
1668 (xyz[i1][j1].pp[2] - xyz[i0][j1].pp[2]) * (double) (i - i0) / (double) (i1 - i0) +
1669 ((double) (i - i0)) *
1670 (-Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX));
1671 xyz[i][j1].done = 1;
1677 if (!xyz[i0][j].done) {
1678 xyz[i0][j].pp[2] = xyz[i0][j0].pp[2] +
1679 (xyz[i0][j1].pp[2] - xyz[i0][j0].pp[2]) * (double) (j - j0) / (double) (j1 - j0) +
1680 ((double) (j - j0)) *
1681 (-Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX));
1682 xyz[i0][j].done = 1;
1686 if ((i1 > i0) && (!xyz[i1][j].done)) {
1687 xyz[i1][j].pp[2] = xyz[i1][j0].pp[2] +
1688 (xyz[i1][j1].pp[2] - xyz[i1][j0].pp[2]) * (double) (j - j0) / (double) (j1 - j0) +
1689 ((double) (j - j0)) *
1690 (-Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX));
1691 xyz[i1][j].done = 1;
1696 if ((i1 > i0 + 1) && (j1 > j0 + 1)) {
1697 if (!xyz[i][j].done) {
1698 z1 = xyz[i0][j].pp[2] +
1699 (xyz[i1][j].pp[2] - xyz[i0][j].pp[2]) * (double) (i - i0) / (double) (i1 - i0);
1700 z2 = xyz[i][j0].pp[2] +
1701 (xyz[i][j1].pp[2] - xyz[i][j0].pp[2]) * (double) (j - j0) / (double) (j1 - j0);
1702 xyz[i][j].pp[2] = (z1 + z2) / 2. +
1703 ((double) (i - i0)) *
1704 (-Roughness / 2. + Roughness * ((double) rand() / (double) RAND_MAX));
1710 if (i > i0 + 1 || j > j0 + 1) {
1711 SubdividePlasma(i0, j0, i, j);
1713 if (i1 > i + 1 || j > j0 + 1) {
1714 SubdividePlasma(i, j0, i1, j);
1716 if (i > i0 + 1 || j1 > j0 + 1) {
1717 SubdividePlasma(i0, j, i, j1);
1719 if (i1 > i + 1 || j1 > j0 + 1) {
1720 SubdividePlasma(i, j, i1, j1);
1724 //==================================================================================
1728 /* use pp[2] values until done to avoid messing with a bunch of
1729 switch statements */
1731 for (i = 0; i <= NH; i++) {
1732 for (j = 0; j <= NV; j++) {
1733 if (FixedPoint(i, j)) {
1744 for (i = 0; i <= NH; i++) {
1745 for (j = 0; j <= NV; j++) {
1746 if (xyz[i][j].fixed) {
1747 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1749 xyz[i][j].pp[2] = xyz[i][j].p[1];
1756 for (i = 0; i <= NH; i++) {
1757 for (j = 0; j <= NV; j++) {
1758 if (xyz[i][j].fixed) {
1759 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1761 xyz[i][j].pp[2] = xyz[i][j].p[0];
1767 for (i = 0; i <= NH; i++) {
1768 for (j = 0; j <= NV; j++) {
1769 if (xyz[i][j].fixed) {
1770 xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1772 xyz[i][j].pp[2] = xyz[i][j].p[2];
1778 SubdividePlasma(0, 0, NH, NV);
1782 for (i = 0; i <= NH; i++) {
1783 for (j = 0; j <= NV; j++) {
1784 xyz[i][j].p[1] = xyz[i][j].pp[2];
1790 for (i = 0; i <= NH; i++) {
1791 for (j = 0; j <= NV; j++) {
1792 xyz[i][j].p[0] = xyz[i][j].pp[2];
1797 for (i = 0; i <= NH; i++) {
1798 for (j = 0; j <= NV; j++) {
1799 xyz[i][j].p[2] = xyz[i][j].pp[2];
1806 //===========================================================================
1807 bool FixedPoint(int i, int j)
1809 if (xyz[i][j].fixed) {
1812 return !CanEdit(i, j);
1815 //===========================================================================
1816 bool CanEdit(int i, int j)
1818 if (FixBorders && ((WaveType == WAVE_COS_SIN) || (WaveType == WAVE_ROUGH_ONLY))) {
1832 if (i == 0 && j == 0) {
1835 if (i == NH && j == 0) {
1838 if (i == 0 && j == NV) {
1841 if (i == NH && j == NV) {
1847 /*============================================================================
1849 Determines which triangle in the gTri array bounds the input point. Doesn't
1850 do anything special with border points.
1852 int TriangleFromPoint(double x, double y)
1860 for (j = 0, tri = -1; j < gNumTris && tri == -1; j++) {
1862 gNode[gTri[j].v[0]].p[0], gNode[gTri[j].v[0]].p[1],
1863 gNode[gTri[j].v[1]].p[0], gNode[gTri[j].v[1]].p[1]) < 0.) {
1867 gNode[gTri[j].v[1]].p[0], gNode[gTri[j].v[1]].p[1],
1868 gNode[gTri[j].v[2]].p[0], gNode[gTri[j].v[2]].p[1]) < 0.) {
1872 gNode[gTri[j].v[2]].p[0], gNode[gTri[j].v[2]].p[1],
1873 gNode[gTri[j].v[0]].p[0], gNode[gTri[j].v[0]].p[1]) < 0.) {
1882 /*============================================================================
1884 Determines minimum height to place the player start such that he doesn't
1885 intersect any surface brushes.
1887 int PlayerStartZ(double x, double y)
1896 t[0] = TriangleFromPoint(x, y);
1897 t[1] = TriangleFromPoint(x + PlayerBox[Game].x[0], y + PlayerBox[Game].y[0]);
1898 t[2] = TriangleFromPoint(x + PlayerBox[Game].x[0], y + PlayerBox[Game].y[1]);
1899 t[3] = TriangleFromPoint(x + PlayerBox[Game].x[1], y + PlayerBox[Game].y[0]);
1900 t[4] = TriangleFromPoint(x + PlayerBox[Game].x[1], y + PlayerBox[Game].y[1]);
1902 for (k = 0; k < 5; k++) {
1903 zt = (gTri[t[k]].plane.dist -
1904 gTri[t[k]].plane.normal[0] * x -
1905 gTri[t[k]].plane.normal[1] * y) /
1906 gTri[t[k]].plane.normal[2];
1909 return (int) (AtLeast(z, 2.) - PlayerBox[Game].z[0]);
1912 //=============================================================
1913 void XYZtoV(XYZ *xyz, vec3 *v)
1915 v[0][0] = (vec) Nearest(xyz->p[0], 2.);
1916 v[0][1] = (vec) Nearest(xyz->p[1], 2.);
1917 v[0][2] = (vec) Nearest(xyz->p[2], 2.);
1920 //=============================================================
1921 scene::Node *MakePatch(void)
1923 scene::Node *patch = Patch_AllocNode();
1925 patch->m_patch->SetShader( Texture[Game][0] );
1927 Node_getTraversable(h_worldspawn)->insert(patch);
1931 //=============================================================
1932 void MakeBrush(BRUSH *brush)
1934 NodePtr node(Brush_AllocNode());
1937 for ( int i = 0; i < brush->NumFaces; i++ )
1939 _QERFaceData QERFaceData;
1940 if ( !strncmp( brush->face[i].texture, "textures/", 9 ) ) {
1941 strcpy( QERFaceData.m_TextureName,brush->face[i].texture );
1945 strcpy( QERFaceData.m_TextureName,"textures/" );
1946 strcpy( QERFaceData.m_TextureName + 9,brush->face[i].texture );
1948 QERFaceData.m_nContents = brush->face[i].Contents;
1949 QERFaceData.m_nFlags = brush->face[i].Surface;
1950 QERFaceData.m_nValue = brush->face[i].Value;
1951 QERFaceData.m_fShift[0] = brush->face[i].Shift[0];
1952 QERFaceData.m_fShift[1] = brush->face[i].Shift[1];
1953 QERFaceData.m_fRotate = brush->face[i].Rotate;
1954 QERFaceData.m_fScale[0] = brush->face[i].Scale[0];
1955 QERFaceData.m_fScale[1] = brush->face[i].Scale[1];
1956 QERFaceData.m_v1[0] = brush->face[i].v[0][0];
1957 QERFaceData.m_v1[1] = brush->face[i].v[0][1];
1958 QERFaceData.m_v1[2] = brush->face[i].v[0][2];
1959 QERFaceData.m_v2[0] = brush->face[i].v[1][0];
1960 QERFaceData.m_v2[1] = brush->face[i].v[1][1];
1961 QERFaceData.m_v2[2] = brush->face[i].v[1][2];
1962 QERFaceData.m_v3[0] = brush->face[i].v[2][0];
1963 QERFaceData.m_v3[1] = brush->face[i].v[2][1];
1964 QERFaceData.m_v3[2] = brush->face[i].v[2][2];
1965 QERFaceData.m_bBPrimit = false;
1966 ( g_FuncTable.m_pfnAddFaceData )( vp,&QERFaceData );
1970 Node_getTraversable(h_func_group)->insert(node);
1973 //=============================================================
1974 void OpenFuncGroup()
1976 h_func_group = GlobalEntityCreator().createEntity("func_group");
1977 h_func_group->IncRef();
1978 if (AddTerrainKey) {
1979 h_func_group->m_entity->setkeyvalue("terrain", "1");
1983 //=============================================================
1984 void CloseFuncGroup()
1986 h_func_group->DecRef();
1987 if (g_FuncTable.m_pfnSysUpdateWindows != NULL) {
1988 g_FuncTable.m_pfnSysUpdateWindows(W_ALL);