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.
14 * $Source: /cvs/cvsroot/d2x/main/editor/texture.c,v $
17 * $Date: 2004-12-19 13:54:27 $
19 * Texture map assignment.
21 * $Log: not supported by cvs2svn $
22 * Revision 1.2 2003/03/09 06:34:09 donut
23 * change byte typedef to sbyte to avoid conflict with win32 byte which is unsigned
25 * Revision 1.1.1.1 1999/06/14 22:04:34 donut
26 * Import of d1x 1.37 source.
28 * Revision 2.0 1995/02/27 11:34:50 john
29 * Version 2.0! No anonymous unions, Watcom 10.0, with no need
32 * Revision 1.13 1994/08/04 19:13:15 matt
33 * Changed a bunch of vecmat calls to use multiple-function routines, and to
34 * allow the use of C macros for some functions
36 * Revision 1.12 1994/08/03 10:31:56 mike
37 * Texture map propagation without uv assignment.
39 * Revision 1.11 1994/07/14 19:36:34 yuan
40 * Tuning texture slides.
42 * Revision 1.10 1994/07/14 19:29:08 yuan
45 * Revision 1.9 1994/07/14 14:43:06 yuan
48 * Revision 1.8 1994/07/14 11:12:42 yuan
49 * Made sliding 3x more sensitive
51 * Revision 1.7 1994/07/14 10:49:56 yuan
52 * Made texture rotation 3x finer
54 * Revision 1.6 1994/02/14 12:06:00 mike
55 * change segment data structure.
57 * Revision 1.5 1993/12/06 13:26:52 mike
58 * Make rotation and sliding work for triangulated sides.
60 * Revision 1.4 1993/12/04 17:18:46 mike
61 * Add tiling functions, set_default.
63 * Revision 1.3 1993/12/03 18:39:12 unknown
64 * Add texture map sliding, allow to work on triangulated sides.
66 * Revision 1.2 1993/11/30 17:06:09 mike
67 * Texture map functions.
69 * Revision 1.1 1993/11/29 16:00:57 mike
77 static char rcsid[] = "$Id: texture.c,v 1.1 2004-12-19 13:54:27 btb Exp $";
96 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum);
97 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter);
99 // -----------------------------------------------------------
105 compute_uv_side_center(&uvcenter, Cursegp, Curside);
107 // Create a rotation matrix
113 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
115 Update_flags |= UF_WORLD_CHANGED;
120 // -----------------------------------------------------------
126 compute_uv_side_center(&uvcenter, Cursegp, Curside);
128 // Create a rotation matrix
134 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
136 Update_flags |= UF_WORLD_CHANGED;
141 // -----------------------------------------------------------
142 int DoTexSlideLeft(int value)
150 vp = Side_to_verts[Curside];
151 sidep = &Cursegp->sides[Curside];
153 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
155 if (dist < F1_0/(64*value))
156 dist = F1_0/(64*value);
158 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
159 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
161 for (v=0; v<4; v++) {
162 sidep->uvls[v].u -= duvl03.u;
163 sidep->uvls[v].v -= duvl03.v;
166 Update_flags |= UF_WORLD_CHANGED;
173 return DoTexSlideLeft(3);
176 int TexSlideLeftBig()
178 return DoTexSlideLeft(1);
181 // -----------------------------------------------------------
182 int DoTexSlideUp(int value)
190 vp = Side_to_verts[Curside];
191 sidep = &Cursegp->sides[Curside];
193 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
196 if (dist < F1_0/(64*value))
197 dist = F1_0/(64*value);
199 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
200 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
202 for (v=0; v<4; v++) {
203 sidep->uvls[v].u -= duvl03.u;
204 sidep->uvls[v].v -= duvl03.v;
207 Update_flags |= UF_WORLD_CHANGED;
214 return DoTexSlideUp(3);
219 return DoTexSlideUp(1);
223 // -----------------------------------------------------------
224 int DoTexSlideDown(int value)
232 vp = Side_to_verts[Curside];
233 sidep = &Cursegp->sides[Curside];
235 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
237 if (dist < F1_0/(64*value))
238 dist = F1_0/(64*value);
240 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
241 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
243 for (v=0; v<4; v++) {
244 sidep->uvls[v].u += duvl03.u;
245 sidep->uvls[v].v += duvl03.v;
248 Update_flags |= UF_WORLD_CHANGED;
255 return DoTexSlideDown(3);
258 int TexSlideDownBig()
260 return DoTexSlideDown(1);
263 // -----------------------------------------------------------
264 // Compute the center of the side in u,v coordinates.
265 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum)
268 side *sidep = &segp->sides[sidenum];
273 for (v=0; v<4; v++) {
274 uvcenter->u += sidep->uvls[v].u;
275 uvcenter->v += sidep->uvls[v].v;
283 // -----------------------------------------------------------
284 // rotate point *uv by matrix rotmat, return *uvrot
285 void rotate_uv_point(uvl *uvrot, fix *rotmat, uvl *uv, uvl *uvcenter)
287 uvrot->u = fixmul(uv->u - uvcenter->u,rotmat[0]) + fixmul(uv->v - uvcenter->v,rotmat[1]) + uvcenter->u;
288 uvrot->v = fixmul(uv->u - uvcenter->u,rotmat[2]) + fixmul(uv->v - uvcenter->v,rotmat[3]) + uvcenter->v;
291 // -----------------------------------------------------------
292 // Compute the center of the side in u,v coordinates.
293 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter)
296 side *sidep = &segp->sides[sidenum];
299 for (v=0; v<4; v++) {
300 rotate_uv_point(&tuv, rotmat, &sidep->uvls[v], uvcenter);
301 sidep->uvls[v] = tuv;
305 // -----------------------------------------------------------
306 // ang is in 0..ffff = 0..359.999 degrees
307 // rotmat is filled in with 4 fixes
308 void create_2d_rotation_matrix(fix *rotmat, fix ang)
312 fix_sincos(ang, &sinang, &cosang);
322 // -----------------------------------------------------------
323 int DoTexRotateLeft(int value)
328 compute_uv_side_center(&uvcenter, Cursegp, Curside);
330 // Create a rotation matrix
331 create_2d_rotation_matrix(rotmat, -F1_0/value);
333 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
335 Update_flags |= UF_WORLD_CHANGED;
342 return DoTexRotateLeft(192);
345 int TexRotateLeftBig()
347 return DoTexRotateLeft(64);
351 // -----------------------------------------------------------
352 int DoTexSlideRight(int value)
360 vp = Side_to_verts[Curside];
361 sidep = &Cursegp->sides[Curside];
363 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
365 if (dist < F1_0/(64*value))
366 dist = F1_0/(64*value);
368 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
369 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
371 for (v=0; v<4; v++) {
372 sidep->uvls[v].u += duvl03.u;
373 sidep->uvls[v].v += duvl03.v;
376 Update_flags |= UF_WORLD_CHANGED;
383 return DoTexSlideRight(3);
386 int TexSlideRightBig()
388 return DoTexSlideRight(1);
391 // -----------------------------------------------------------
392 int DoTexRotateRight(int value)
397 compute_uv_side_center(&uvcenter, Cursegp, Curside);
399 // Create a rotation matrix
400 create_2d_rotation_matrix(rotmat, F1_0/value);
402 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
404 Update_flags |= UF_WORLD_CHANGED;
411 return DoTexRotateRight(192);
414 int TexRotateRightBig()
416 return DoTexRotateRight(64);
419 // -----------------------------------------------------------
420 int TexSelectActiveEdge()
425 // -----------------------------------------------------------
426 int TexRotate90Degrees()
431 compute_uv_side_center(&uvcenter, Cursegp, Curside);
433 // Create a rotation matrix
434 create_2d_rotation_matrix(rotmat, F1_0/4);
436 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
438 Update_flags |= UF_WORLD_CHANGED;
443 // -----------------------------------------------------------
448 Stretch_scale_x = F1_0;
449 Stretch_scale_y = F1_0;
451 assign_default_uvs_to_side(Cursegp,Curside);
453 Update_flags |= UF_GAME_VIEW_CHANGED;
457 // -----------------------------------------------------------
458 int TexIncreaseTiling()
462 assign_default_uvs_to_side(Cursegp, Curside);
463 Update_flags |= UF_GAME_VIEW_CHANGED;
468 // -----------------------------------------------------------
469 int TexDecreaseTiling()
472 if (--Num_tilings < 1)
475 assign_default_uvs_to_side(Cursegp, Curside);
476 Update_flags |= UF_GAME_VIEW_CHANGED;
482 // direction = -1 or 1 depending on direction
483 int TexStretchCommon(int direction)
487 if ((Curedge == 0) || (Curedge == 2))
488 sptr = &Stretch_scale_x;
490 sptr = &Stretch_scale_y;
492 *sptr += direction*F1_0/64;
500 stretch_uvs_from_curedge(Cursegp, Curside);
502 editor_status("Stretch scale = %7.4f, use Set Default to return to 1.0", f2fl(*sptr));
504 Update_flags |= UF_GAME_VIEW_CHANGED;
509 int TexStretchDown(void)
511 return TexStretchCommon(-1);
515 int TexStretchUp(void)
517 return TexStretchCommon(1);