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/ksegsize.c,v $
17 * $Date: 2004-12-19 13:54:27 $
19 * Functions for sizing segments
21 * $Log: not supported by cvs2svn $
22 * Revision 1.1.1.1 1999/06/14 22:03:32 donut
23 * Import of d1x 1.37 source.
25 * Revision 2.1 1995/03/08 16:07:21 yuan
26 * Added segment sizing default functions.
28 * Revision 2.0 1995/02/27 11:35:46 john
29 * Version 2.0! No anonymous unions, Watcom 10.0, with no need
32 * Revision 1.15 1994/11/17 14:47:42 mike
33 * validation functions moved from editor to game.
35 * Revision 1.14 1994/08/25 21:57:45 mike
38 * Revision 1.13 1994/07/18 10:44:43 mike
39 * Fix uv propagation after segment sizing.
41 * Revision 1.12 1994/05/04 19:16:34 mike
42 * *** empty log message ***
44 * Revision 1.11 1994/05/03 18:31:00 mike
47 * Revision 1.10 1994/05/03 11:05:14 mike
48 * Overhaul segment sizing system to allow sizing of non-free vertices,
49 * and also sizing of vertices on a side, edge or a single vertex.
51 * Revision 1.9 1993/12/12 17:16:00 mike
52 * Kill some mprintf code.
55 * Revision 1.8 1993/12/10 11:10:53 mike
56 * Fix bugs in tmap propagation in segment sizing.
58 * Revision 1.7 1993/12/06 13:25:30 mike
59 * Fix bug in setting size of New_segment after segment scale.
61 * Revision 1.6 1993/11/17 18:57:52 mike
62 * Change scaling to be additive.
64 * Revision 1.5 1993/11/12 16:52:57 mike
65 * *** empty log message ***
67 * Revision 1.4 1993/11/05 17:32:47 john
71 * Revision 1.3 1993/10/19 11:22:11 matt
72 * Removed extra includes
74 * Revision 1.2 1993/10/17 14:17:52 mike
75 * Add big scale changes for segment.
77 * Revision 1.1 1993/10/13 18:53:01 john
84 static char rcsid[] = "$Id: ksegsize.c,v 1.1 2004-12-19 13:54:27 btb Exp $";
100 #define MAX_MODIFIED_VERTICES 32
101 int Modified_vertices[MAX_MODIFIED_VERTICES];
102 int Modified_vertex_index = 0;
104 // ------------------------------------------------------------------------------------------
105 void validate_modified_segments(void)
108 char modified_segments[MAX_SEGMENTS];
110 for (v=0; v<=Highest_segment_index; v++)
111 modified_segments[v] = 0;
113 for (v=0; v<Modified_vertex_index; v++) {
114 v0 = Modified_vertices[v];
116 for (seg = 0; seg <= Highest_segment_index; seg++) {
117 short *vp = Segments[seg].verts;
118 if (Segments[seg].segnum != -1)
119 for (w=0; w<MAX_VERTICES_PER_SEGMENT; w++)
121 modified_segments[seg] = 1;
125 for (v=0; v<=Highest_segment_index; v++)
126 if (modified_segments[v]) {
129 // mprintf(0, "Validating segment #%04i\n", v);
130 validate_segment(&Segments[v]);
131 for (s=0; s<MAX_SIDES_PER_SEGMENT; s++) {
133 assign_default_uvs_to_side(&Segments[v], s);
138 // ------------------------------------------------------------------------------------------
139 // Scale vertex *vertp by vector *vp, scaled by scale factor scale_factor
140 void scale_vert_aux(int vertex_ind, vms_vector *vp, fix scale_factor)
142 vms_vector *vertp = &Vertices[vertex_ind];
144 vertp->x += fixmul(vp->x,scale_factor)/2;
145 vertp->y += fixmul(vp->y,scale_factor)/2;
146 vertp->z += fixmul(vp->z,scale_factor)/2;
148 Assert(Modified_vertex_index < MAX_MODIFIED_VERTICES);
149 Modified_vertices[Modified_vertex_index++] = vertex_ind;
152 // ------------------------------------------------------------------------------------------
153 void scale_vert(segment *sp, int vertex_ind, vms_vector *vp, fix scale_factor)
155 switch (SegSizeMode) {
156 case SEGSIZEMODE_FREE:
157 if (is_free_vertex(vertex_ind))
158 scale_vert_aux(vertex_ind, vp, scale_factor);
160 case SEGSIZEMODE_ALL:
161 scale_vert_aux(vertex_ind, vp, scale_factor);
163 case SEGSIZEMODE_CURSIDE: {
166 if (sp->verts[Side_to_verts[Curside][v]] == vertex_ind)
167 scale_vert_aux(vertex_ind, vp, scale_factor);
170 case SEGSIZEMODE_EDGE: {
174 if (sp->verts[Side_to_verts[Curside][(Curedge+v)%4]] == vertex_ind)
175 scale_vert_aux(vertex_ind, vp, scale_factor);
178 case SEGSIZEMODE_VERTEX:
179 if (sp->verts[Side_to_verts[Curside][Curvert]] == vertex_ind)
180 scale_vert_aux(vertex_ind, vp, scale_factor);
183 Error("Unsupported SegSizeMode in ksegsize.c/scale_vert = %i\n", SegSizeMode);
188 // ------------------------------------------------------------------------------------------
189 void scale_free_verts(segment *sp, vms_vector *vp, int side, fix scale_factor)
195 verts = Side_to_verts[side];
197 for (v=0; v<4; v++) {
198 vertex_ind = sp->verts[(int) verts[v]];
199 if (SegSizeMode || is_free_vertex(vertex_ind))
200 scale_vert(sp, vertex_ind, vp, scale_factor);
206 // -----------------------------------------------------------------------------
207 // Make segment *sp bigger in dimension dimension by amount amount.
208 void med_scale_segment_new(segment *sp, int dimension, fix amount)
212 Modified_vertex_index = 0;
214 med_extract_matrix_from_segment(sp, &mat);
218 scale_free_verts(sp, &mat.rvec, WLEFT, -amount);
219 scale_free_verts(sp, &mat.rvec, WRIGHT, +amount);
222 scale_free_verts(sp, &mat.uvec, WBOTTOM, -amount);
223 scale_free_verts(sp, &mat.uvec, WTOP, +amount);
226 scale_free_verts(sp, &mat.fvec, WFRONT, -amount);
227 scale_free_verts(sp, &mat.fvec, WBACK, +amount);
231 validate_modified_segments();
234 // ------------------------------------------------------------------------------------------
235 // Extract a vector from a segment. The vector goes from the start face to the end face.
236 // The point on each face is the average of the four points forming the face.
237 void extract_vector_from_segment_side(segment *sp, int side, vms_vector *vp, int vla, int vlb, int vra, int vrb)
241 vm_vec_sub(&v1,&Vertices[sp->verts[Side_to_verts[side][vra]]],&Vertices[sp->verts[Side_to_verts[side][vla]]]);
242 vm_vec_sub(&v2,&Vertices[sp->verts[Side_to_verts[side][vrb]]],&Vertices[sp->verts[Side_to_verts[side][vlb]]]);
243 vm_vec_add(vp, &v1, &v2);
245 vm_vec_scale(vp, F1_0/2);
248 // ------------------------------------------------------------------------------------------
249 // Extract the right vector from segment *sp, return in *vp.
250 // The forward vector is defined to be the vector from the the center of the left face of the segment
251 // to the center of the right face of the segment.
252 void med_extract_right_vector_from_segment_side(segment *sp, int sidenum, vms_vector *vp)
254 extract_vector_from_segment_side(sp, sidenum, vp, 3, 2, 0, 1);
257 // ------------------------------------------------------------------------------------------
258 // Extract the up vector from segment *sp, return in *vp.
259 // The forward vector is defined to be the vector from the the center of the bottom face of the segment
260 // to the center of the top face of the segment.
261 void med_extract_up_vector_from_segment_side(segment *sp, int sidenum, vms_vector *vp)
263 extract_vector_from_segment_side(sp, sidenum, vp, 1, 2, 0, 3);
267 // -----------------------------------------------------------------------------
268 // Increase the size of Cursegp in dimension dimension by amount
269 int segsize_common(int dimension, fix amount)
272 int propagated[MAX_SIDES_PER_SEGMENT];
273 vms_vector uvec, rvec, fvec, scalevec;
275 Degenerate_segment_found = 0;
277 med_scale_segment_new(Cursegp, dimension, amount);
279 med_extract_up_vector_from_segment_side(Cursegp, Curside, &uvec);
280 med_extract_right_vector_from_segment_side(Cursegp, Curside, &rvec);
281 extract_forward_vector_from_segment(Cursegp, &fvec);
283 scalevec.x = vm_vec_mag(&rvec);
284 scalevec.y = vm_vec_mag(&uvec);
285 scalevec.z = vm_vec_mag(&fvec);
287 if (Degenerate_segment_found) {
288 Degenerate_segment_found = 0;
289 // mprintf(0, "Applying scale would create degenerate segments. Aborting scale.\n");
290 editor_status("Applying scale would create degenerate segments. Aborting scale.");
291 med_scale_segment_new(Cursegp, dimension, -amount);
295 med_create_new_segment(&scalevec);
297 // For all segments to which Cursegp is connected, propagate tmap (uv coordinates) from the connected
298 // segment back to Cursegp. This will meaningfully propagate uv coordinates to all sides which havve
299 // an incident edge. It will also do some sides more than once. And it is probably just not what you want.
300 for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
303 for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
304 if (IS_CHILD(Cursegp->children[i])) {
306 for (s=0; s<MAX_SIDES_PER_SEGMENT; s++)
308 propagated[(int) Side_opposite[i]]--;
309 med_propagate_tmaps_to_segments(&Segments[Cursegp->children[i]],Cursegp,1);
312 // Now, for all sides that were not adjacent to another side, and therefore did not get tmaps
313 // propagated to them, treat as a back side.
314 for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
315 if (!propagated[i]) {
316 med_propagate_tmaps_to_back_side(Cursegp, i, 1);
319 // New stuff, assign default texture to all affected sides.
321 Update_flags |= UF_WORLD_CHANGED;
326 // -----------------------------------------------------------------------------
327 // ---------- segment size control ----------
329 int IncreaseSegLength()
331 return segsize_common(ZDIM,+F1_0);
334 int DecreaseSegLength()
336 return segsize_common(ZDIM,-F1_0);
339 int DecreaseSegWidth()
341 return segsize_common(XDIM,-F1_0);
344 int IncreaseSegWidth()
346 return segsize_common(XDIM,+F1_0);
349 int IncreaseSegHeight()
351 return segsize_common(YDIM,+F1_0);
354 int DecreaseSegHeight()
356 return segsize_common(YDIM,-F1_0);
360 int IncreaseSegLengthBig()
362 return segsize_common(ZDIM,+5 * F1_0);
365 int DecreaseSegLengthBig()
367 return segsize_common(ZDIM,-5 * F1_0);
370 int DecreaseSegWidthBig()
372 return segsize_common(XDIM,-5 * F1_0);
375 int IncreaseSegWidthBig()
377 return segsize_common(XDIM,+5 * F1_0);
380 int IncreaseSegHeightBig()
382 return segsize_common(YDIM,+5 * F1_0);
385 int DecreaseSegHeightBig()
387 return segsize_common(YDIM,-5 * F1_0);
391 int IncreaseSegLengthDefault()
393 return segsize_common(ZDIM,+40 *F1_0);
396 int DecreaseSegLengthDefault()
398 return segsize_common(ZDIM,-40*F1_0);
401 int IncreaseSegWidthDefault()
403 return segsize_common(XDIM,+40*F1_0);
406 int DecreaseSegWidthDefault()
408 return segsize_common(XDIM,-40*F1_0);
411 int IncreaseSegHeightDefault()
413 return segsize_common(YDIM,+40 * F1_0);
416 int DecreaseSegHeightDefault()
418 return segsize_common(YDIM,-40 * F1_0);
423 // ---------------------------------------------------------------------------
424 int ToggleSegSizeMode(void)
427 if (SegSizeMode > SEGSIZEMODE_MAX)
428 SegSizeMode = SEGSIZEMODE_MIN;
433 // ---------------------------------------------------------------------------
434 int PerturbCursideCommon(fix amount)
436 int saveSegSizeMode = SegSizeMode;
437 vms_vector fvec, rvec, uvec;
438 fix fmag, rmag, umag;
441 SegSizeMode = SEGSIZEMODE_CURSIDE;
443 Modified_vertex_index = 0;
445 extract_forward_vector_from_segment(Cursegp, &fvec);
446 extract_right_vector_from_segment(Cursegp, &rvec);
447 extract_up_vector_from_segment(Cursegp, &uvec);
449 fmag = vm_vec_mag(&fvec);
450 rmag = vm_vec_mag(&rvec);
451 umag = vm_vec_mag(&uvec);
453 for (v=0; v<4; v++) {
454 vms_vector perturb_vec;
456 perturb_vec.x = fixmul(rmag, d_rand()*2 - 32767);
457 perturb_vec.y = fixmul(umag, d_rand()*2 - 32767);
458 perturb_vec.z = fixmul(fmag, d_rand()*2 - 32767);
460 scale_vert(Cursegp, Cursegp->verts[Side_to_verts[Curside][v]], &perturb_vec, amount);
463 // validate_segment(Cursegp);
464 // if (SegSizeMode) {
465 // for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
466 // if (Cursegp->children[i] != -1)
467 // validate_segment(&Segments[Cursegp->children[i]]);
470 validate_modified_segments();
471 SegSizeMode = saveSegSizeMode;
473 Update_flags |= UF_WORLD_CHANGED;
479 // ---------------------------------------------------------------------------
480 int PerturbCurside(void)
482 PerturbCursideCommon(F1_0/10);
487 // ---------------------------------------------------------------------------
488 int PerturbCursideBig(void)
490 PerturbCursideCommon(F1_0/2);