1 /* $Id: texture.c,v 1.3 2004-12-19 15:21:11 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Texture map assignment.
22 static char rcsid[] = "$Id: texture.c,v 1.3 2004-12-19 15:21:11 btb Exp $";
45 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum);
46 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter);
48 // -----------------------------------------------------------
54 compute_uv_side_center(&uvcenter, Cursegp, Curside);
56 // Create a rotation matrix
62 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
64 Update_flags |= UF_WORLD_CHANGED;
69 // -----------------------------------------------------------
75 compute_uv_side_center(&uvcenter, Cursegp, Curside);
77 // Create a rotation matrix
83 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
85 Update_flags |= UF_WORLD_CHANGED;
90 // -----------------------------------------------------------
91 int DoTexSlideLeft(int value)
99 vp = Side_to_verts[Curside];
100 sidep = &Cursegp->sides[Curside];
102 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
104 if (dist < F1_0/(64*value))
105 dist = F1_0/(64*value);
107 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
108 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
110 for (v=0; v<4; v++) {
111 sidep->uvls[v].u -= duvl03.u;
112 sidep->uvls[v].v -= duvl03.v;
115 Update_flags |= UF_WORLD_CHANGED;
122 return DoTexSlideLeft(3);
125 int TexSlideLeftBig()
127 return DoTexSlideLeft(1);
130 // -----------------------------------------------------------
131 int DoTexSlideUp(int value)
139 vp = Side_to_verts[Curside];
140 sidep = &Cursegp->sides[Curside];
142 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
145 if (dist < F1_0/(64*value))
146 dist = F1_0/(64*value);
148 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
149 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
151 for (v=0; v<4; v++) {
152 sidep->uvls[v].u -= duvl03.u;
153 sidep->uvls[v].v -= duvl03.v;
156 Update_flags |= UF_WORLD_CHANGED;
163 return DoTexSlideUp(3);
168 return DoTexSlideUp(1);
172 // -----------------------------------------------------------
173 int DoTexSlideDown(int value)
181 vp = Side_to_verts[Curside];
182 sidep = &Cursegp->sides[Curside];
184 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
186 if (dist < F1_0/(64*value))
187 dist = F1_0/(64*value);
189 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
190 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
192 for (v=0; v<4; v++) {
193 sidep->uvls[v].u += duvl03.u;
194 sidep->uvls[v].v += duvl03.v;
197 Update_flags |= UF_WORLD_CHANGED;
204 return DoTexSlideDown(3);
207 int TexSlideDownBig()
209 return DoTexSlideDown(1);
212 // -----------------------------------------------------------
213 // Compute the center of the side in u,v coordinates.
214 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum)
217 side *sidep = &segp->sides[sidenum];
222 for (v=0; v<4; v++) {
223 uvcenter->u += sidep->uvls[v].u;
224 uvcenter->v += sidep->uvls[v].v;
232 // -----------------------------------------------------------
233 // rotate point *uv by matrix rotmat, return *uvrot
234 void rotate_uv_point(uvl *uvrot, fix *rotmat, uvl *uv, uvl *uvcenter)
236 uvrot->u = fixmul(uv->u - uvcenter->u,rotmat[0]) + fixmul(uv->v - uvcenter->v,rotmat[1]) + uvcenter->u;
237 uvrot->v = fixmul(uv->u - uvcenter->u,rotmat[2]) + fixmul(uv->v - uvcenter->v,rotmat[3]) + uvcenter->v;
240 // -----------------------------------------------------------
241 // Compute the center of the side in u,v coordinates.
242 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter)
245 side *sidep = &segp->sides[sidenum];
248 for (v=0; v<4; v++) {
249 rotate_uv_point(&tuv, rotmat, &sidep->uvls[v], uvcenter);
250 sidep->uvls[v] = tuv;
254 // -----------------------------------------------------------
255 // ang is in 0..ffff = 0..359.999 degrees
256 // rotmat is filled in with 4 fixes
257 void create_2d_rotation_matrix(fix *rotmat, fix ang)
261 fix_sincos(ang, &sinang, &cosang);
271 // -----------------------------------------------------------
272 int DoTexRotateLeft(int value)
277 compute_uv_side_center(&uvcenter, Cursegp, Curside);
279 // Create a rotation matrix
280 create_2d_rotation_matrix(rotmat, -F1_0/value);
282 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
284 Update_flags |= UF_WORLD_CHANGED;
291 return DoTexRotateLeft(192);
294 int TexRotateLeftBig()
296 return DoTexRotateLeft(64);
300 // -----------------------------------------------------------
301 int DoTexSlideRight(int value)
309 vp = Side_to_verts[Curside];
310 sidep = &Cursegp->sides[Curside];
312 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
314 if (dist < F1_0/(64*value))
315 dist = F1_0/(64*value);
317 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
318 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
320 for (v=0; v<4; v++) {
321 sidep->uvls[v].u += duvl03.u;
322 sidep->uvls[v].v += duvl03.v;
325 Update_flags |= UF_WORLD_CHANGED;
332 return DoTexSlideRight(3);
335 int TexSlideRightBig()
337 return DoTexSlideRight(1);
340 // -----------------------------------------------------------
341 int DoTexRotateRight(int value)
346 compute_uv_side_center(&uvcenter, Cursegp, Curside);
348 // Create a rotation matrix
349 create_2d_rotation_matrix(rotmat, F1_0/value);
351 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
353 Update_flags |= UF_WORLD_CHANGED;
360 return DoTexRotateRight(192);
363 int TexRotateRightBig()
365 return DoTexRotateRight(64);
368 // -----------------------------------------------------------
369 int TexSelectActiveEdge()
374 // -----------------------------------------------------------
375 int TexRotate90Degrees()
380 compute_uv_side_center(&uvcenter, Cursegp, Curside);
382 // Create a rotation matrix
383 create_2d_rotation_matrix(rotmat, F1_0/4);
385 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
387 Update_flags |= UF_WORLD_CHANGED;
392 // -----------------------------------------------------------
397 Stretch_scale_x = F1_0;
398 Stretch_scale_y = F1_0;
400 assign_default_uvs_to_side(Cursegp,Curside);
402 Update_flags |= UF_GAME_VIEW_CHANGED;
406 // -----------------------------------------------------------
407 int TexIncreaseTiling()
411 assign_default_uvs_to_side(Cursegp, Curside);
412 Update_flags |= UF_GAME_VIEW_CHANGED;
417 // -----------------------------------------------------------
418 int TexDecreaseTiling()
421 if (--Num_tilings < 1)
424 assign_default_uvs_to_side(Cursegp, Curside);
425 Update_flags |= UF_GAME_VIEW_CHANGED;
431 // direction = -1 or 1 depending on direction
432 int TexStretchCommon(int direction)
436 if ((Curedge == 0) || (Curedge == 2))
437 sptr = &Stretch_scale_x;
439 sptr = &Stretch_scale_y;
441 *sptr += direction*F1_0/64;
449 stretch_uvs_from_curedge(Cursegp, Curside);
451 editor_status("Stretch scale = %7.4f, use Set Default to return to 1.0", f2fl(*sptr));
453 Update_flags |= UF_GAME_VIEW_CHANGED;
458 int TexStretchDown(void)
460 return TexStretchCommon(-1);
464 int TexStretchUp(void)
466 return TexStretchCommon(1);