1 /* $Id: texture.c,v 1.2 2004-12-19 14:53:48 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.
23 static char rcsid[] = "$Id: texture.c,v 1.2 2004-12-19 14:53:48 btb Exp $";
42 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum);
43 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter);
45 // -----------------------------------------------------------
51 compute_uv_side_center(&uvcenter, Cursegp, Curside);
53 // Create a rotation matrix
59 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
61 Update_flags |= UF_WORLD_CHANGED;
66 // -----------------------------------------------------------
72 compute_uv_side_center(&uvcenter, Cursegp, Curside);
74 // Create a rotation matrix
80 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
82 Update_flags |= UF_WORLD_CHANGED;
87 // -----------------------------------------------------------
88 int DoTexSlideLeft(int value)
96 vp = Side_to_verts[Curside];
97 sidep = &Cursegp->sides[Curside];
99 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
101 if (dist < F1_0/(64*value))
102 dist = F1_0/(64*value);
104 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
105 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
107 for (v=0; v<4; v++) {
108 sidep->uvls[v].u -= duvl03.u;
109 sidep->uvls[v].v -= duvl03.v;
112 Update_flags |= UF_WORLD_CHANGED;
119 return DoTexSlideLeft(3);
122 int TexSlideLeftBig()
124 return DoTexSlideLeft(1);
127 // -----------------------------------------------------------
128 int DoTexSlideUp(int value)
136 vp = Side_to_verts[Curside];
137 sidep = &Cursegp->sides[Curside];
139 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
142 if (dist < F1_0/(64*value))
143 dist = F1_0/(64*value);
145 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
146 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
148 for (v=0; v<4; v++) {
149 sidep->uvls[v].u -= duvl03.u;
150 sidep->uvls[v].v -= duvl03.v;
153 Update_flags |= UF_WORLD_CHANGED;
160 return DoTexSlideUp(3);
165 return DoTexSlideUp(1);
169 // -----------------------------------------------------------
170 int DoTexSlideDown(int value)
178 vp = Side_to_verts[Curside];
179 sidep = &Cursegp->sides[Curside];
181 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[1]]], &Vertices[Cursegp->verts[vp[0]]]);
183 if (dist < F1_0/(64*value))
184 dist = F1_0/(64*value);
186 duvl03.u = fixdiv(sidep->uvls[1].u - sidep->uvls[0].u,dist);
187 duvl03.v = fixdiv(sidep->uvls[1].v - sidep->uvls[0].v,dist);
189 for (v=0; v<4; v++) {
190 sidep->uvls[v].u += duvl03.u;
191 sidep->uvls[v].v += duvl03.v;
194 Update_flags |= UF_WORLD_CHANGED;
201 return DoTexSlideDown(3);
204 int TexSlideDownBig()
206 return DoTexSlideDown(1);
209 // -----------------------------------------------------------
210 // Compute the center of the side in u,v coordinates.
211 void compute_uv_side_center(uvl *uvcenter, segment *segp, int sidenum)
214 side *sidep = &segp->sides[sidenum];
219 for (v=0; v<4; v++) {
220 uvcenter->u += sidep->uvls[v].u;
221 uvcenter->v += sidep->uvls[v].v;
229 // -----------------------------------------------------------
230 // rotate point *uv by matrix rotmat, return *uvrot
231 void rotate_uv_point(uvl *uvrot, fix *rotmat, uvl *uv, uvl *uvcenter)
233 uvrot->u = fixmul(uv->u - uvcenter->u,rotmat[0]) + fixmul(uv->v - uvcenter->v,rotmat[1]) + uvcenter->u;
234 uvrot->v = fixmul(uv->u - uvcenter->u,rotmat[2]) + fixmul(uv->v - uvcenter->v,rotmat[3]) + uvcenter->v;
237 // -----------------------------------------------------------
238 // Compute the center of the side in u,v coordinates.
239 void rotate_uv_points_on_side(segment *segp, int sidenum, fix *rotmat, uvl *uvcenter)
242 side *sidep = &segp->sides[sidenum];
245 for (v=0; v<4; v++) {
246 rotate_uv_point(&tuv, rotmat, &sidep->uvls[v], uvcenter);
247 sidep->uvls[v] = tuv;
251 // -----------------------------------------------------------
252 // ang is in 0..ffff = 0..359.999 degrees
253 // rotmat is filled in with 4 fixes
254 void create_2d_rotation_matrix(fix *rotmat, fix ang)
258 fix_sincos(ang, &sinang, &cosang);
268 // -----------------------------------------------------------
269 int DoTexRotateLeft(int value)
274 compute_uv_side_center(&uvcenter, Cursegp, Curside);
276 // Create a rotation matrix
277 create_2d_rotation_matrix(rotmat, -F1_0/value);
279 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
281 Update_flags |= UF_WORLD_CHANGED;
288 return DoTexRotateLeft(192);
291 int TexRotateLeftBig()
293 return DoTexRotateLeft(64);
297 // -----------------------------------------------------------
298 int DoTexSlideRight(int value)
306 vp = Side_to_verts[Curside];
307 sidep = &Cursegp->sides[Curside];
309 dist = vm_vec_dist(&Vertices[Cursegp->verts[vp[3]]], &Vertices[Cursegp->verts[vp[0]]]);
311 if (dist < F1_0/(64*value))
312 dist = F1_0/(64*value);
314 duvl03.u = fixdiv(sidep->uvls[3].u - sidep->uvls[0].u,dist);
315 duvl03.v = fixdiv(sidep->uvls[3].v - sidep->uvls[0].v,dist);
317 for (v=0; v<4; v++) {
318 sidep->uvls[v].u += duvl03.u;
319 sidep->uvls[v].v += duvl03.v;
322 Update_flags |= UF_WORLD_CHANGED;
329 return DoTexSlideRight(3);
332 int TexSlideRightBig()
334 return DoTexSlideRight(1);
337 // -----------------------------------------------------------
338 int DoTexRotateRight(int value)
343 compute_uv_side_center(&uvcenter, Cursegp, Curside);
345 // Create a rotation matrix
346 create_2d_rotation_matrix(rotmat, F1_0/value);
348 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
350 Update_flags |= UF_WORLD_CHANGED;
357 return DoTexRotateRight(192);
360 int TexRotateRightBig()
362 return DoTexRotateRight(64);
365 // -----------------------------------------------------------
366 int TexSelectActiveEdge()
371 // -----------------------------------------------------------
372 int TexRotate90Degrees()
377 compute_uv_side_center(&uvcenter, Cursegp, Curside);
379 // Create a rotation matrix
380 create_2d_rotation_matrix(rotmat, F1_0/4);
382 rotate_uv_points_on_side(Cursegp, Curside, rotmat, &uvcenter);
384 Update_flags |= UF_WORLD_CHANGED;
389 // -----------------------------------------------------------
394 Stretch_scale_x = F1_0;
395 Stretch_scale_y = F1_0;
397 assign_default_uvs_to_side(Cursegp,Curside);
399 Update_flags |= UF_GAME_VIEW_CHANGED;
403 // -----------------------------------------------------------
404 int TexIncreaseTiling()
408 assign_default_uvs_to_side(Cursegp, Curside);
409 Update_flags |= UF_GAME_VIEW_CHANGED;
414 // -----------------------------------------------------------
415 int TexDecreaseTiling()
418 if (--Num_tilings < 1)
421 assign_default_uvs_to_side(Cursegp, Curside);
422 Update_flags |= UF_GAME_VIEW_CHANGED;
428 // direction = -1 or 1 depending on direction
429 int TexStretchCommon(int direction)
433 if ((Curedge == 0) || (Curedge == 2))
434 sptr = &Stretch_scale_x;
436 sptr = &Stretch_scale_y;
438 *sptr += direction*F1_0/64;
446 stretch_uvs_from_curedge(Cursegp, Curside);
448 editor_status("Stretch scale = %7.4f, use Set Default to return to 1.0", f2fl(*sptr));
450 Update_flags |= UF_GAME_VIEW_CHANGED;
455 int TexStretchDown(void)
457 return TexStretchCommon(-1);
461 int TexStretchUp(void)
463 return TexStretchCommon(1);