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

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