home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / texture.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  10KB  |  500 lines

  1. /*
  2.  * $Source: f:/miner/source/main/editor/rcs/texture.c $
  3.  * $Revision: 2.0 $
  4.  * $Author: john $
  5.  * $Date: 1995/02/27 11:34:50 $
  6.  * 
  7.  * Texture map assignment.
  8.  * 
  9.  * $Log: texture.c $
  10.  * Revision 2.0  1995/02/27  11:34:50  john
  11.  * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  12.  * for bitmaps.tbl.
  13.  * 
  14.  * Revision 1.13  1994/08/04  19:13:15  matt
  15.  * Changed a bunch of vecmat calls to use multiple-function routines, and to
  16.  * allow the use of C macros for some functions
  17.  * 
  18.  * Revision 1.12  1994/08/03  10:31:56  mike
  19.  * Texture map propagation without uv assignment.
  20.  * 
  21.  * Revision 1.11  1994/07/14  19:36:34  yuan
  22.  * Tuning texture slides.
  23.  * 
  24.  * Revision 1.10  1994/07/14  19:29:08  yuan
  25.  * Fixed sliding.
  26.  * 
  27.  * Revision 1.9  1994/07/14  14:43:06  yuan
  28.  * Added 3x rotation.
  29.  * 
  30.  * Revision 1.8  1994/07/14  11:12:42  yuan
  31.  * Made sliding 3x more sensitive
  32.  * 
  33.  * Revision 1.7  1994/07/14  10:49:56  yuan
  34.  * Made texture rotation 3x finer
  35.  * 
  36.  * Revision 1.6  1994/02/14  12:06:00  mike
  37.  * change segment data structure.
  38.  * 
  39.  * Revision 1.5  1993/12/06  13:26:52  mike
  40.  * Make rotation and sliding work for triangulated sides.
  41.  * 
  42.  * Revision 1.4  1993/12/04  17:18:46  mike
  43.  * Add tiling functions, set_default.
  44.  * 
  45.  * Revision 1.3  1993/12/03  18:39:12  unknown
  46.  * Add texture map sliding, allow to work on triangulated sides.
  47.  * 
  48.  * Revision 1.2  1993/11/30  17:06:09  mike
  49.  * Texture map functions.
  50.  * 
  51.  * Revision 1.1  1993/11/29  16:00:57  mike
  52.  * Initial revision
  53.  * 
  54.  * 
  55.  */
  56.  
  57.  
  58. #pragma off (unreferenced)
  59. static char rcsid[] = "$Id: texture.c 2.0 1995/02/27 11:34:50 john Exp $";
  60. #pragma on (unreferenced)
  61.  
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <stdarg.h>
  65. #include <math.h>
  66. #include <string.h>
  67.  
  68. #include "inferno.h"
  69. #include "segment.h"
  70. #include "seguvs.h"
  71. #include "editor.h"
  72.  
  73. #include "fix.h"
  74. #include "mono.h"
  75. #include "error.h"
  76. #include "kdefs.h"
  77.  
  78. //    -----------------------------------------------------------
  79. int    TexFlipX()
  80. {
  81.     uvl    uvcenter;
  82.     fix    rotmat[4];
  83.  
  84.     compute_uv_side_center(&uvcenter, Cursegp, Curside);
  85.  
  86.     //    Create a rotation matrix
  87.     rotmat[0] = -0xffff;
  88.     rotmat[1] = 0;
  89.     rotmat[2] = 0;
  90.     rotmat[3] = 0xffff;
  91.  
  92.     rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
  93.  
  94.      Update_flags |= UF_WORLD_CHANGED;
  95.  
  96.     return    1;
  97. }
  98.  
  99. //    -----------------------------------------------------------
  100. int    TexFlipY()
  101. {
  102.     uvl    uvcenter;
  103.     fix    rotmat[4];
  104.  
  105.     compute_uv_side_center(&uvcenter, Cursegp, Curside);
  106.  
  107.     //    Create a rotation matrix
  108.     rotmat[0] = 0xffff;
  109.     rotmat[1] = 0;
  110.     rotmat[2] = 0;
  111.     rotmat[3] = -0xffff;
  112.  
  113.     rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
  114.  
  115.      Update_flags |= UF_WORLD_CHANGED;
  116.  
  117.     return    1;
  118. }
  119.  
  120. //    -----------------------------------------------------------
  121. int DoTexSlideLeft(int value)
  122. {
  123.     side    *sidep;
  124.     uvl    duvl03;
  125.     fix    dist;
  126.     byte    *vp;
  127.     int    v;
  128.  
  129.     vp = Side_to_verts[Curside];
  130.     sidep = &Cursegp->sides[Curside];
  131.  
  132.     dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
  133.     dist *= value;
  134.     if (dist < F1_0/(64*value))
  135.         dist = F1_0/(64*value);
  136.  
  137.     duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
  138.     duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
  139.  
  140.     for (v=0; v<4; v++) {
  141.         sidep->uvls[v].u -= duvl03.u;
  142.         sidep->uvls[v].v -= duvl03.v;
  143.     }
  144.  
  145.     Update_flags |= UF_WORLD_CHANGED;
  146.  
  147.     return    1;
  148. }
  149.  
  150. int TexSlideLeft()
  151. {
  152.     return DoTexSlideLeft(3);
  153. }
  154.  
  155. int TexSlideLeftBig()
  156. {
  157.     return DoTexSlideLeft(1);
  158. }
  159.  
  160. //    -----------------------------------------------------------
  161. int DoTexSlideUp(int value)
  162. {
  163.     side    *sidep;
  164.     uvl    duvl03;
  165.     fix    dist;
  166.     byte    *vp;
  167.     int    v;
  168.  
  169.     vp = Side_to_verts[Curside];
  170.     sidep = &Cursegp->sides[Curside];
  171.  
  172.     dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
  173.     dist *= value;
  174.  
  175.     if (dist < F1_0/(64*value))
  176.         dist = F1_0/(64*value);
  177.  
  178.     duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
  179.     duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
  180.  
  181.     for (v=0; v<4; v++) {
  182.         sidep->uvls[v].u -= duvl03.u;
  183.         sidep->uvls[v].v -= duvl03.v;
  184.     }
  185.  
  186.     Update_flags |= UF_WORLD_CHANGED;
  187.  
  188.     return    1;
  189. }
  190.  
  191. int TexSlideUp()
  192. {
  193.     return DoTexSlideUp(3);
  194. }
  195.  
  196. int TexSlideUpBig()
  197. {
  198.     return DoTexSlideUp(1);
  199. }
  200.  
  201.  
  202. //    -----------------------------------------------------------
  203. int DoTexSlideDown(int value)
  204. {
  205.     side    *sidep;
  206.     uvl    duvl03;
  207.     fix    dist;
  208.     byte    *vp;
  209.     int    v;
  210.  
  211.     vp = Side_to_verts[Curside];
  212.     sidep = &Cursegp->sides[Curside];
  213.  
  214.     dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
  215.     dist *= value;
  216.     if (dist < F1_0/(64*value))
  217.         dist = F1_0/(64*value);
  218.  
  219.     duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
  220.     duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
  221.  
  222.     for (v=0; v<4; v++) {
  223.         sidep->uvls[v].u += duvl03.u;
  224.         sidep->uvls[v].v += duvl03.v;
  225.     }
  226.  
  227.     Update_flags |= UF_WORLD_CHANGED;
  228.  
  229.     return    1;
  230. }
  231.  
  232. int TexSlideDown()
  233. {
  234.     return DoTexSlideDown(3);
  235. }
  236.  
  237. int TexSlideDownBig()
  238. {
  239.     return DoTexSlideDown(1);
  240. }
  241.  
  242. //    -----------------------------------------------------------
  243. //    Compute the center of the side in u,v coordinates.
  244. void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum)
  245. {
  246.     int    v;
  247.     side    *sidep = &segp->sides[sidenum];
  248.  
  249.     uvcenter->u = 0;
  250.     uvcenter->v = 0;
  251.  
  252.     for (v=0; v<4; v++) {
  253.         uvcenter->u += sidep->uvls[v].u;
  254.         uvcenter->v += sidep->uvls[v].v;
  255.     }
  256.  
  257.     uvcenter->u /= 4;
  258.     uvcenter->v /= 4;
  259. }
  260.  
  261.  
  262. //    -----------------------------------------------------------
  263. //    rotate point *uv by matrix rotmat, return *uvrot
  264. void rotate_uv_point(uvl *uvrot, fix *rotmat, uvl *uv, uvl *uvcenter)
  265. {
  266.     uvrot->u = fixmul(uv->u - uvcenter->u,rotmat[0]) + fixmul(uv->v - uvcenter->v,rotmat[1]) + uvcenter->u;
  267.     uvrot->v = fixmul(uv->u - uvcenter->u,rotmat[2]) + fixmul(uv->v - uvcenter->v,rotmat[3]) + uvcenter->v;
  268. }
  269.  
  270. //    -----------------------------------------------------------
  271. //    Compute the center of the side in u,v coordinates.
  272. void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter)
  273. {
  274.     int    v;
  275.     side    *sidep = &segp->sides[sidenum];
  276.     uvl    tuv;
  277.  
  278.     for (v=0; v<4; v++) {
  279.         rotate_uv_point(&tuv, rotmat, &sidep->uvls[v], uvcenter);
  280.         sidep->uvls[v] = tuv;
  281.     }
  282. }
  283.  
  284. //    -----------------------------------------------------------
  285. //    ang is in 0..ffff = 0..359.999 degrees
  286. //    rotmat is filled in with 4 fixes
  287. void create_2d_rotation_matrix(fix *rotmat, fix ang)
  288. {
  289.     fix    sinang, cosang;
  290.  
  291.     fix_sincos(ang, &sinang, &cosang);
  292.  
  293.     rotmat[0] = cosang;
  294.     rotmat[1] = sinang;
  295.     rotmat[2] = -sinang;
  296.     rotmat[3] = cosang;
  297.     
  298. }
  299.  
  300.  
  301. //    -----------------------------------------------------------
  302. int DoTexRotateLeft(int value)
  303. {
  304.     uvl    uvcenter;
  305.     fix    rotmat[4];
  306.  
  307.     compute_uv_side_center(&uvcenter, Cursegp, Curside);
  308.  
  309.     //    Create a rotation matrix
  310.     create_2d_rotation_matrix(rotmat, -F1_0/value);
  311.  
  312.     rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
  313.  
  314.      Update_flags |= UF_WORLD_CHANGED;
  315.  
  316.     return    1;
  317. }
  318.  
  319. int TexRotateLeft()
  320. {
  321.     return DoTexRotateLeft(192);
  322. }
  323.  
  324. int TexRotateLeftBig()
  325. {
  326.     return DoTexRotateLeft(64);
  327. }
  328.  
  329.  
  330. //    -----------------------------------------------------------
  331. int DoTexSlideRight(int value)
  332. {
  333.     side    *sidep;
  334.     uvl    duvl03;
  335.     fix    dist;
  336.     byte    *vp;
  337.     int    v;
  338.  
  339.     vp = Side_to_verts[Curside];
  340.     sidep = &Cursegp->sides[Curside];
  341.  
  342.     dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
  343.     dist *= value;
  344.     if (dist < F1_0/(64*value))
  345.         dist = F1_0/(64*value);
  346.  
  347.     duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
  348.     duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
  349.  
  350.     for (v=0; v<4; v++) {
  351.         sidep->uvls[v].u += duvl03.u;
  352.         sidep->uvls[v].v += duvl03.v;
  353.     }
  354.  
  355.     Update_flags |= UF_WORLD_CHANGED;
  356.  
  357.     return    1;
  358. }
  359.  
  360. int TexSlideRight()
  361. {
  362.     return DoTexSlideRight(3);
  363. }
  364.  
  365. int TexSlideRightBig()
  366. {
  367.     return DoTexSlideRight(1);
  368. }
  369.  
  370. //    -----------------------------------------------------------
  371. int DoTexRotateRight(int value)
  372. {
  373.     uvl    uvcenter;
  374.     fix    rotmat[4];
  375.  
  376.     compute_uv_side_center(&uvcenter, Cursegp, Curside);
  377.  
  378.     //    Create a rotation matrix
  379.     create_2d_rotation_matrix(rotmat, F1_0/value);
  380.  
  381.     rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
  382.  
  383.      Update_flags |= UF_WORLD_CHANGED;
  384.  
  385.     return    1;
  386. }
  387.  
  388. int TexRotateRight()
  389. {
  390.     return DoTexRotateRight(192);
  391. }
  392.  
  393. int TexRotateRightBig()
  394. {
  395.     return DoTexRotateRight(64);
  396. }
  397.  
  398. //    -----------------------------------------------------------
  399. int    TexSelectActiveEdge()
  400. {
  401.     return    1;
  402. }
  403.  
  404. //    -----------------------------------------------------------
  405. int    TexRotate90Degrees()
  406. {
  407.     uvl    uvcenter;
  408.     fix    rotmat[4];
  409.  
  410.     compute_uv_side_center(&uvcenter, Cursegp, Curside);
  411.  
  412.     //    Create a rotation matrix
  413.     create_2d_rotation_matrix(rotmat, F1_0/4);
  414.  
  415.     rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
  416.  
  417.      Update_flags |= UF_WORLD_CHANGED;
  418.  
  419.     return    1;
  420. }
  421.  
  422. //    -----------------------------------------------------------
  423. int    TexSetDefault()
  424. {
  425.     Num_tilings = 1;
  426.  
  427.     Stretch_scale_x = F1_0;
  428.     Stretch_scale_y = F1_0;
  429.  
  430.     assign_default_uvs_to_side(Cursegp,Curside);
  431.  
  432.     Update_flags |= UF_GAME_VIEW_CHANGED;
  433.     return    1;
  434. }
  435.  
  436. //    -----------------------------------------------------------
  437. int    TexIncreaseTiling()
  438. {
  439.  
  440.     Num_tilings++;
  441.     assign_default_uvs_to_side(Cursegp, Curside);
  442.     Update_flags |= UF_GAME_VIEW_CHANGED;
  443.  
  444.     return    1;
  445. }
  446.  
  447. //    -----------------------------------------------------------
  448. int    TexDecreaseTiling()
  449. {
  450.  
  451.     if (--Num_tilings < 1)
  452.         Num_tilings = 1;
  453.  
  454.     assign_default_uvs_to_side(Cursegp, Curside);
  455.     Update_flags |= UF_GAME_VIEW_CHANGED;
  456.  
  457.     return    1;
  458. }
  459.  
  460.  
  461. //    direction = -1 or 1 depending on direction
  462. int    TexStretchCommon(int direction)
  463. {
  464.     fix    *sptr;
  465.  
  466.     if ((Curedge == 0) || (Curedge == 2))
  467.         sptr = &Stretch_scale_x;
  468.     else
  469.         sptr = &Stretch_scale_y;
  470.  
  471.     *sptr += direction*F1_0/64;
  472.  
  473.     if (*sptr < F1_0/16)
  474.         *sptr = F1_0/16;
  475.  
  476.     if (*sptr > 2*F1_0)
  477.         *sptr = 2*F1_0;
  478.  
  479.     stretch_uvs_from_curedge(Cursegp, Curside);
  480.  
  481.     editor_status("Stretch scale = %7.4f, use Set Default to return to 1.0", f2fl(*sptr));
  482.  
  483.     Update_flags |= UF_GAME_VIEW_CHANGED;
  484.     return    1;
  485.  
  486. }
  487.  
  488. int    TexStretchDown(void)
  489. {
  490.     return TexStretchCommon(-1);
  491.  
  492. }
  493.  
  494. int    TexStretchUp(void)
  495. {
  496.     return TexStretchCommon(1);
  497.  
  498. }
  499.  
  500.