home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / ksegsize.c < prev    next >
Text File  |  1998-06-08  |  13KB  |  479 lines

  1. /*
  2.  * $Source: f:/miner/source/main/editor/rcs/ksegsize.c $
  3.  * $Revision: 2.1 $
  4.  * $Author: yuan $
  5.  * $Date: 1995/03/08 16:07:21 $
  6.  *
  7.  * Functions for sizing segments
  8.  *
  9.  * $Log: ksegsize.c $
  10.  * Revision 2.1  1995/03/08  16:07:21  yuan
  11.  * Added segment sizing default functions.
  12.  * 
  13.  * Revision 2.0  1995/02/27  11:35:46  john
  14.  * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  15.  * for bitmaps.tbl.
  16.  * 
  17.  * Revision 1.15  1994/11/17  14:47:42  mike
  18.  * validation functions moved from editor to game.
  19.  * 
  20.  * Revision 1.14  1994/08/25  21:57:45  mike
  21.  * IS_CHILD stuff.
  22.  * 
  23.  * Revision 1.13  1994/07/18  10:44:43  mike
  24.  * Fix uv propagation after segment sizing.
  25.  * 
  26.  * Revision 1.12  1994/05/04  19:16:34  mike
  27.  * *** empty log message ***
  28.  * 
  29.  * Revision 1.11  1994/05/03  18:31:00  mike
  30.  * Add PerturbCurside.
  31.  * 
  32.  * Revision 1.10  1994/05/03  11:05:14  mike
  33.  * Overhaul segment sizing system to allow sizing of non-free vertices,
  34.  * and also sizing of vertices on a side, edge or a single vertex.
  35.  * 
  36.  * Revision 1.9  1993/12/12  17:16:00  mike
  37.  * Kill some mprintf code.
  38.  * 
  39.  * 
  40.  * Revision 1.8  1993/12/10  11:10:53  mike
  41.  * Fix bugs in tmap propagation in segment sizing.
  42.  * 
  43.  * Revision 1.7  1993/12/06  13:25:30  mike
  44.  * Fix bug in setting size of New_segment after segment scale.
  45.  * 
  46.  * Revision 1.6  1993/11/17  18:57:52  mike
  47.  * Change scaling to be additive.
  48.  * 
  49.  * Revision 1.5  1993/11/12  16:52:57  mike
  50.  * *** empty log message ***
  51.  * 
  52.  * Revision 1.4  1993/11/05  17:32:47  john
  53.  * added funcs
  54.  * .,
  55.  * 
  56.  * Revision 1.3  1993/10/19  11:22:11  matt
  57.  * Removed extra includes
  58.  * 
  59.  * Revision 1.2  1993/10/17  14:17:52  mike
  60.  * Add big scale changes for segment.
  61.  * 
  62.  * Revision 1.1  1993/10/13  18:53:01  john
  63.  * Initial revision
  64.  * 
  65.  *
  66.  */
  67.  
  68. #pragma off (unreferenced)
  69. static char rcsid[] = "$Id: ksegsize.c 2.1 1995/03/08 16:07:21 yuan Exp $";
  70. #pragma on (unreferenced)
  71.  
  72. #include <stdlib.h>
  73.  
  74. #include "inferno.h"
  75. #include "editor.h"
  76. #include "mono.h"
  77. #include "error.h"
  78. #include "segment.h"
  79. #include "gameseg.h"
  80.  
  81. #define XDIM    0
  82. #define YDIM    1
  83. #define ZDIM    2
  84.  
  85. #define    MAX_MODIFIED_VERTICES    32
  86. int        Modified_vertices[MAX_MODIFIED_VERTICES];
  87. int        Modified_vertex_index = 0;
  88.  
  89. // ------------------------------------------------------------------------------------------
  90. void validate_modified_segments(void)
  91. {
  92.     int    v,w,v0,seg;
  93.     char    modified_segments[MAX_SEGMENTS];
  94.  
  95.     for (v=0; v<=Highest_segment_index; v++)
  96.         modified_segments[v] = 0;
  97.  
  98.     for (v=0; v<Modified_vertex_index; v++) {
  99.         v0 = Modified_vertices[v];
  100.  
  101.         for (seg = 0; seg <= Highest_segment_index; seg++) {
  102.             short *vp = Segments[seg].verts;
  103.             if (Segments[seg].segnum != -1)
  104.                 for (w=0; w<MAX_VERTICES_PER_SEGMENT; w++)
  105.                     if (*vp++ == v0)
  106.                         modified_segments[seg] = 1;
  107.         }
  108.     }
  109.  
  110.     for (v=0; v<=Highest_segment_index; v++)
  111.         if (modified_segments[v]) {
  112.             int    s;
  113.  
  114.             // mprintf(0, "Validating segment #%04i\n", v);
  115.             validate_segment(&Segments[v]);
  116.             for (s=0; s<MAX_SIDES_PER_SEGMENT; s++) {
  117.                 Num_tilings = 1;
  118.                 assign_default_uvs_to_side(&Segments[v], s);
  119.             }
  120.         }
  121. }
  122.  
  123. // ------------------------------------------------------------------------------------------
  124. //    Scale vertex *vertp by vector *vp, scaled by scale factor scale_factor
  125. void scale_vert_aux(int vertex_ind, vms_vector *vp, fix scale_factor)
  126. {
  127.     vms_vector    *vertp = &Vertices[vertex_ind];
  128.  
  129.     vertp->x += fixmul(vp->x,scale_factor)/2;
  130.     vertp->y += fixmul(vp->y,scale_factor)/2;
  131.     vertp->z += fixmul(vp->z,scale_factor)/2;
  132.  
  133.     Assert(Modified_vertex_index < MAX_MODIFIED_VERTICES);
  134.     Modified_vertices[Modified_vertex_index++] = vertex_ind;
  135. }
  136.  
  137. // ------------------------------------------------------------------------------------------
  138. void scale_vert(segment *sp, int vertex_ind, vms_vector *vp, fix scale_factor)
  139. {
  140.     switch (SegSizeMode) {
  141.         case SEGSIZEMODE_FREE:
  142.             if (is_free_vertex(vertex_ind))
  143.                 scale_vert_aux(vertex_ind, vp, scale_factor);
  144.             break;
  145.         case SEGSIZEMODE_ALL:
  146.             scale_vert_aux(vertex_ind, vp, scale_factor);
  147.             break;
  148.         case SEGSIZEMODE_CURSIDE: {
  149.             int    v;
  150.             for (v=0; v<4; v++)
  151.                 if (sp->verts[Side_to_verts[Curside][v]] == vertex_ind)
  152.                     scale_vert_aux(vertex_ind, vp, scale_factor);
  153.             break;
  154.         }
  155.         case SEGSIZEMODE_EDGE: {
  156.             int    v;
  157.  
  158.             for (v=0; v<2; v++)
  159.                 if (sp->verts[Side_to_verts[Curside][(Curedge+v)%4]] == vertex_ind)
  160.                     scale_vert_aux(vertex_ind, vp, scale_factor);
  161.             break;
  162.         }
  163.         case SEGSIZEMODE_VERTEX:
  164.             if (sp->verts[Side_to_verts[Curside][Curvert]] == vertex_ind)
  165.                 scale_vert_aux(vertex_ind, vp, scale_factor);
  166.             break;
  167.         default:
  168.             Error("Unsupported SegSizeMode in ksegsize.c/scale_vert = %i\n", SegSizeMode);
  169.     }
  170.  
  171. }
  172.  
  173. // ------------------------------------------------------------------------------------------
  174. void scale_free_verts(segment *sp, vms_vector *vp, int side, fix scale_factor)
  175. {
  176.     int        v;
  177.     char        *verts;
  178.     int        vertex_ind;
  179.  
  180.     verts = Side_to_verts[side];
  181.  
  182.     for (v=0; v<4; v++) {
  183.         vertex_ind = sp->verts[verts[v]];
  184.         if (SegSizeMode || is_free_vertex(vertex_ind))
  185.             scale_vert(sp, vertex_ind, vp, scale_factor);
  186.     }
  187.  
  188. }
  189.  
  190.  
  191. // -----------------------------------------------------------------------------
  192. //    Make segment *sp bigger in dimension dimension by amount amount.
  193. void med_scale_segment_new(segment *sp, int dimension, fix amount)
  194. {
  195.     vms_matrix    mat;
  196.  
  197.     Modified_vertex_index = 0;
  198.  
  199.     med_extract_matrix_from_segment(sp, &mat);
  200.  
  201.     switch (dimension) {
  202.         case XDIM:
  203.             scale_free_verts(sp, &mat.rvec, WLEFT,   -amount);
  204.             scale_free_verts(sp, &mat.rvec, WRIGHT,  +amount);
  205.             break;
  206.         case YDIM:
  207.             scale_free_verts(sp, &mat.uvec, WBOTTOM, -amount);
  208.             scale_free_verts(sp, &mat.uvec, WTOP,    +amount);
  209.             break;
  210.         case ZDIM:
  211.             scale_free_verts(sp, &mat.fvec, WFRONT,  -amount);
  212.             scale_free_verts(sp, &mat.fvec, WBACK,   +amount);
  213.             break;
  214.     }
  215.  
  216.     validate_modified_segments();
  217. }
  218.  
  219. // ------------------------------------------------------------------------------------------
  220. //    Extract a vector from a segment.  The vector goes from the start face to the end face.
  221. //    The point on each face is the average of the four points forming the face.
  222. void extract_vector_from_segment_side(segment *sp, int side, vms_vector *vp, int vla, int vlb, int vra, int vrb)
  223. {
  224.     vms_vector    v1, v2;
  225.  
  226.     vm_vec_sub(&v1,&Vertices[sp->verts[Side_to_verts[side][vra]]],&Vertices[sp->verts[Side_to_verts[side][vla]]]);
  227.     vm_vec_sub(&v2,&Vertices[sp->verts[Side_to_verts[side][vrb]]],&Vertices[sp->verts[Side_to_verts[side][vlb]]]);
  228.     vm_vec_add(vp, &v1, &v2);
  229.  
  230.     vm_vec_scale(vp, F1_0/2);
  231. }
  232.  
  233. // ------------------------------------------------------------------------------------------
  234. //    Extract the right vector from segment *sp, return in *vp.
  235. //    The forward vector is defined to be the vector from the the center of the left face of the segment
  236. // to the center of the right face of the segment.
  237. void med_extract_right_vector_from_segment_side(segment *sp, int sidenum, vms_vector *vp)
  238. {
  239.     extract_vector_from_segment_side(sp, sidenum, vp, 3, 2, 0, 1);
  240. }
  241.  
  242. // ------------------------------------------------------------------------------------------
  243. //    Extract the up vector from segment *sp, return in *vp.
  244. //    The forward vector is defined to be the vector from the the center of the bottom face of the segment
  245. // to the center of the top face of the segment.
  246. void med_extract_up_vector_from_segment_side(segment *sp, int sidenum, vms_vector *vp)
  247. {
  248.     extract_vector_from_segment_side(sp, sidenum, vp, 1, 2, 0, 3);
  249. }
  250.  
  251.  
  252. // -----------------------------------------------------------------------------
  253. //    Increase the size of Cursegp in dimension dimension by amount
  254. int segsize_common(int dimension, fix amount)
  255. {
  256.     int    i;
  257.     int    propagated[MAX_SIDES_PER_SEGMENT];
  258.     vms_vector    uvec, rvec, fvec, scalevec;
  259.  
  260.     Degenerate_segment_found = 0;
  261.  
  262.     med_scale_segment_new(Cursegp, dimension, amount);
  263.  
  264.     med_extract_up_vector_from_segment_side(Cursegp, Curside, &uvec);
  265.     med_extract_right_vector_from_segment_side(Cursegp, Curside, &rvec);
  266.     extract_forward_vector_from_segment(Cursegp, &fvec);
  267.  
  268.     scalevec.x = vm_vec_mag(&rvec);
  269.     scalevec.y = vm_vec_mag(&uvec);
  270.     scalevec.z = vm_vec_mag(&fvec);
  271.  
  272.     if (Degenerate_segment_found) {
  273.         Degenerate_segment_found = 0;
  274.         // mprintf(0, "Applying scale would create degenerate segments.  Aborting scale.\n");
  275.         editor_status("Applying scale would create degenerate segments.  Aborting scale.");
  276.         med_scale_segment_new(Cursegp, dimension, -amount);
  277.         return 1;
  278.     }
  279.  
  280.     med_create_new_segment(&scalevec);
  281.  
  282.     //    For all segments to which Cursegp is connected, propagate tmap (uv coordinates) from the connected
  283.     //    segment back to Cursegp.  This will meaningfully propagate uv coordinates to all sides which havve
  284.     //    an incident edge.  It will also do some sides more than once.  And it is probably just not what you want.
  285.     for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
  286.         propagated[i] = 0;
  287.  
  288.     for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
  289.         if (IS_CHILD(Cursegp->children[i])) {
  290.             int    s;
  291.             for (s=0; s<MAX_SIDES_PER_SEGMENT; s++)
  292.                 propagated[s]++;
  293.             propagated[Side_opposite[i]]--;
  294.             med_propagate_tmaps_to_segments(&Segments[Cursegp->children[i]],Cursegp,1);
  295.         }
  296.  
  297.     //    Now, for all sides that were not adjacent to another side, and therefore did not get tmaps
  298.     //    propagated to them, treat as a back side.
  299.     for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
  300.         if (!propagated[i]) {
  301.             med_propagate_tmaps_to_back_side(Cursegp, i, 1);
  302.         }
  303.  
  304.     //    New stuff, assign default texture to all affected sides.
  305.  
  306.     Update_flags |= UF_WORLD_CHANGED;
  307.     mine_changed = 1;
  308.     return 1;
  309. }
  310.  
  311. // -----------------------------------------------------------------------------
  312. // ---------- segment size control ----------
  313.  
  314. int IncreaseSegLength()
  315. {
  316.     return segsize_common(ZDIM,+F1_0);
  317. }
  318.  
  319. int DecreaseSegLength()
  320. {
  321.     return segsize_common(ZDIM,-F1_0);
  322. }
  323.  
  324. int DecreaseSegWidth()
  325. {
  326.     return segsize_common(XDIM,-F1_0);
  327. }
  328.  
  329. int IncreaseSegWidth()
  330. {
  331.     return segsize_common(XDIM,+F1_0);
  332. }
  333.  
  334. int IncreaseSegHeight()
  335. {
  336.     return segsize_common(YDIM,+F1_0);
  337. }
  338.  
  339. int DecreaseSegHeight()
  340. {
  341.     return segsize_common(YDIM,-F1_0);
  342. }
  343.  
  344.  
  345. int IncreaseSegLengthBig()
  346. {
  347.     return segsize_common(ZDIM,+5 * F1_0);
  348. }
  349.  
  350. int DecreaseSegLengthBig()
  351. {
  352.     return segsize_common(ZDIM,-5 * F1_0);
  353. }
  354.  
  355. int DecreaseSegWidthBig()
  356. {
  357.     return segsize_common(XDIM,-5 * F1_0);
  358. }
  359.  
  360. int IncreaseSegWidthBig()
  361. {
  362.     return segsize_common(XDIM,+5 * F1_0);
  363. }
  364.  
  365. int IncreaseSegHeightBig()
  366. {
  367.     return segsize_common(YDIM,+5 * F1_0);
  368. }
  369.  
  370. int DecreaseSegHeightBig()
  371. {
  372.     return segsize_common(YDIM,-5 * F1_0);
  373. }
  374.  
  375.  
  376. int IncreaseSegLengthDefault()
  377. {
  378.     return segsize_common(ZDIM,+40 *F1_0);
  379. }
  380.  
  381. int DecreaseSegLengthDefault()
  382. {
  383.     return segsize_common(ZDIM,-40*F1_0);
  384. }
  385.  
  386. int IncreaseSegWidthDefault()
  387. {
  388.     return segsize_common(XDIM,+40*F1_0);
  389. }
  390.  
  391. int DecreaseSegWidthDefault()
  392. {
  393.     return segsize_common(XDIM,-40*F1_0);
  394. }
  395.  
  396. int IncreaseSegHeightDefault()
  397. {
  398.     return segsize_common(YDIM,+40 * F1_0);
  399. }
  400.  
  401. int DecreaseSegHeightDefault()
  402. {
  403.     return segsize_common(YDIM,-40 * F1_0);
  404. }
  405.  
  406.  
  407.  
  408. //    ---------------------------------------------------------------------------
  409. int ToggleSegSizeMode(void)
  410. {
  411.     SegSizeMode++;
  412.     if (SegSizeMode > SEGSIZEMODE_MAX)
  413.         SegSizeMode = SEGSIZEMODE_MIN;
  414.  
  415.     return 1;
  416. }
  417.  
  418. //    ---------------------------------------------------------------------------
  419. int    PerturbCursideCommon(fix amount)
  420. {
  421.     int            saveSegSizeMode = SegSizeMode;
  422.     vms_vector    fvec, rvec, uvec;
  423.     fix            fmag, rmag, umag;
  424.     int            v;
  425.  
  426.     SegSizeMode = SEGSIZEMODE_CURSIDE;
  427.  
  428.     Modified_vertex_index = 0;
  429.  
  430.     extract_forward_vector_from_segment(Cursegp, &fvec);
  431.     extract_right_vector_from_segment(Cursegp, &rvec);
  432.     extract_up_vector_from_segment(Cursegp, &uvec);
  433.  
  434.     fmag = vm_vec_mag(&fvec);
  435.     rmag = vm_vec_mag(&rvec);
  436.     umag = vm_vec_mag(&uvec);
  437.  
  438.     for (v=0; v<4; v++) {
  439.         vms_vector perturb_vec;
  440.  
  441.         perturb_vec.x = fixmul(rmag, rand()*2 - 32767);
  442.         perturb_vec.y = fixmul(umag, rand()*2 - 32767);
  443.         perturb_vec.z = fixmul(fmag, rand()*2 - 32767);
  444.  
  445.         scale_vert(Cursegp, Cursegp->verts[Side_to_verts[Curside][v]], &perturb_vec, amount);
  446.     }
  447.  
  448. //    validate_segment(Cursegp);
  449. //    if (SegSizeMode) {
  450. //        for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
  451. //            if (Cursegp->children[i] != -1)
  452. //                validate_segment(&Segments[Cursegp->children[i]]);
  453. //    }
  454.  
  455.     validate_modified_segments();
  456.     SegSizeMode = saveSegSizeMode;
  457.  
  458.     Update_flags |= UF_WORLD_CHANGED;
  459.     mine_changed = 1;
  460.  
  461.     return 1;
  462. }
  463.  
  464. //    ---------------------------------------------------------------------------
  465. int    PerturbCurside(void)
  466. {
  467.     PerturbCursideCommon(F1_0/10);
  468.  
  469.     return 1;
  470. }
  471.  
  472. //    ---------------------------------------------------------------------------
  473. int    PerturbCursideBig(void)
  474. {
  475.     PerturbCursideCommon(F1_0/2);
  476.  
  477.     return 1;
  478. }
  479.