// ------------------------------------------------------------------------------------------------------ int ObjectMoveRight(void) { object *obj; vms_vector rvec; vms_vector newpos; if (Cur_object_index == -1) { editor_status("No current object, cannot move."); return 1; } obj = &Objects[Cur_object_index]; extract_right_vector_from_segment(&Segments[obj->segnum], &rvec); vm_vec_normalize(&rvec); vm_vec_add(&newpos, &obj->pos, vm_vec_scale(&rvec, OBJ_SCALE)); if (!verify_object_seg(obj, &newpos)) obj->pos = newpos; Update_flags |= UF_WORLD_CHANGED; return 1; }
// --------------------------------------------------------------------------- int PerturbCursideCommon(fix amount) { int saveSegSizeMode = SegSizeMode; vms_vector fvec, rvec, uvec; fix fmag, rmag, umag; int v; SegSizeMode = SEGSIZEMODE_CURSIDE; Modified_vertex_index = 0; extract_forward_vector_from_segment(Cursegp, &fvec); extract_right_vector_from_segment(Cursegp, &rvec); extract_up_vector_from_segment(Cursegp, &uvec); fmag = vm_vec_mag(&fvec); rmag = vm_vec_mag(&rvec); umag = vm_vec_mag(&uvec); for (v=0; v<4; v++) { vms_vector perturb_vec; perturb_vec.x = fixmul(rmag, rand()*2 - 32767); perturb_vec.y = fixmul(umag, rand()*2 - 32767); perturb_vec.z = fixmul(fmag, rand()*2 - 32767); scale_vert(Cursegp, Cursegp->verts[Side_to_verts[Curside][v]], &perturb_vec, amount); } // validate_segment(Cursegp); // if (SegSizeMode) { // for (i=0; i<MAX_SIDES_PER_SEGMENT; i++) // if (Cursegp->children[i] != -1) // validate_segment(&Segments[Cursegp->children[i]]); // } validate_modified_segments(); SegSizeMode = saveSegSizeMode; Update_flags |= UF_WORLD_CHANGED; mine_changed = 1; return 1; }
void generate_banked_curve(fix maxscale, vms_equation coeffs) { vms_vector vec_dir, tvec, b4r4t; vms_vector coord,prev_point; fix enddist, nextdist; int firstsegflag; fixang rangle, uangle, angle, scaled_ang=0; fix t; if (CurveNumSegs) { const vcsegptr_t cursegp = Cursegp; extract_up_vector_from_segment(cursegp, b4r4t); uangle = vm_vec_delta_ang( b4r4t, r4t, r4 ); if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4; if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4; if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4; if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4; extract_right_vector_from_segment(cursegp, b4r4t); rangle = vm_vec_delta_ang( b4r4t, r4t, r4 ); if (rangle >= F1_0/8) rangle -= F1_0/4; if (rangle >= F1_0/8) rangle -= F1_0/4; if (rangle <= -F1_0/8) rangle += F1_0/4; if (rangle <= -F1_0/8) rangle += F1_0/4; angle = uangle; if (abs(rangle) < abs(uangle)) angle = rangle; delete_curve(); coord = prev_point = p1; #define MAGIC_NUM 0.707*F1_0 if (maxscale) scaled_ang = fixdiv(angle,fixmul(maxscale,MAGIC_NUM)); t=0; tvec = r1save; firstsegflag = 1; enddist = F1_0; nextdist = 0; while ( enddist > fixmul( nextdist, 1.5*F1_0 )) { vms_matrix rotmat; if (firstsegflag==1) firstsegflag=0; else extract_forward_vector_from_segment(cursegp, tvec); nextdist = vm_vec_mag(tvec); // nextdist := distance to next point t = curve_dist(&coeffs, 3, t, prev_point, nextdist); // t = argument at which function is forward vector magnitude units away from prev_point (in 3-space, not along curve) coord = evaluate_curve(&coeffs, 3, t); // coord := point about forward vector magnitude units away from prev_point enddist = vm_vec_dist(coord, p4); // enddist := distance from current to end point, vec_dir used as a temporary variable //vm_vec_normalize(vm_vec_sub(&vec_dir, &coord, &prev_point)); vm_vec_normalized_dir(vec_dir, coord, prev_point); if (!med_attach_segment(Cursegp, vmsegptr(&New_segment), Curside, AttachSide)) { med_extract_matrix_from_segment(cursegp, &rotmat); // rotmat := matrix describing orientation of Cursegp const auto tdest = vm_vec_rotate(vec_dir,rotmat); // tdest := vec_dir in reference frame of Cursegp vec_dir = tdest; const auto rotmat2 = vm_vec_ang_2_matrix(vec_dir,scaled_ang); med_rotate_segment( Cursegp, rotmat2 ); prev_point = coord; Curside = Side_opposite[AttachSide]; CurveSegs[CurveNumSegs]=Cursegp; CurveNumSegs++; } } } }
int generate_curve( fix r1scale, fix r4scale ) { vms_vector vec_dir, tvec; vms_vector coord,prev_point; vms_equation coeffs; fix enddist, nextdist; int firstsegflag; fix t, maxscale; fixang rangle, uangle; const vcsegptr_t cursegp = Cursegp; compute_center_point_on_side(p1, cursegp, Curside); switch( Curside ) { case WLEFT: extract_right_vector_from_segment(cursegp, r1); vm_vec_scale(r1, -F1_0 ); break; case WTOP: extract_up_vector_from_segment(cursegp, r1); break; case WRIGHT: extract_right_vector_from_segment(cursegp, r1); break; case WBOTTOM: extract_up_vector_from_segment(cursegp, r1); vm_vec_scale(r1, -F1_0 ); break; case WBACK: extract_forward_vector_from_segment(cursegp, r1); break; case WFRONT: extract_forward_vector_from_segment(cursegp, r1); vm_vec_scale(r1, -F1_0 ); break; } const vcsegptr_t markedsegp = Markedsegp; compute_center_point_on_side(p4, markedsegp, Markedside); switch( Markedside ) { case WLEFT: extract_right_vector_from_segment(markedsegp, r4); extract_up_vector_from_segment(markedsegp, r4t); break; case WTOP: extract_up_vector_from_segment(markedsegp, r4); vm_vec_scale(r4, -F1_0 ); extract_forward_vector_from_segment(markedsegp, r4t); vm_vec_scale(r4t, -F1_0 ); break; case WRIGHT: extract_right_vector_from_segment(markedsegp, r4); vm_vec_scale(r4, -F1_0 ); extract_up_vector_from_segment(markedsegp, r4t); break; case WBOTTOM: extract_up_vector_from_segment(markedsegp, r4); extract_forward_vector_from_segment(markedsegp, r4t); break; case WBACK: extract_forward_vector_from_segment(markedsegp, r4); vm_vec_scale(r4, -F1_0 ); extract_up_vector_from_segment(markedsegp, r4t); break; case WFRONT: extract_forward_vector_from_segment(markedsegp, r4); extract_up_vector_from_segment(markedsegp, r4t); break; } r1save = r1; tvec = r1; vm_vec_scale(r1,r1scale); vm_vec_scale(r4,r4scale); create_curve( p1, p4, r1, r4, coeffs ); OriginalSeg = Cursegp; OriginalMarkedSeg = Markedsegp; OriginalSide = Curside; OriginalMarkedSide = Markedside; CurveNumSegs = 0; coord = prev_point = p1; t=0; firstsegflag = 1; enddist = F1_0; nextdist = 0; while ( enddist > fixmul( nextdist, 1.5*F1_0 )) { vms_matrix rotmat; if (firstsegflag==1) firstsegflag=0; else extract_forward_vector_from_segment(cursegp, tvec); nextdist = vm_vec_mag(tvec); // nextdist := distance to next point t = curve_dist(&coeffs, 3, t, prev_point, nextdist); // t = argument at which function is forward vector magnitude units away from prev_point (in 3-space, not along curve) coord = evaluate_curve(&coeffs, 3, t); // coord := point about forward vector magnitude units away from prev_point enddist = vm_vec_dist(coord, p4); // enddist := distance from current to end point, vec_dir used as a temporary variable //vm_vec_normalize(vm_vec_sub(&vec_dir, &coord, &prev_point)); vm_vec_normalized_dir(vec_dir, coord, prev_point); if (!med_attach_segment(Cursegp, vmsegptr(&New_segment), Curside, AttachSide)) { med_extract_matrix_from_segment(cursegp, &rotmat); // rotmat := matrix describing orientation of Cursegp const auto tdest = vm_vec_rotate(vec_dir,rotmat); // tdest := vec_dir in reference frame of Cursegp vec_dir = tdest; const auto rotmat2 = vm_vector_2_matrix(vec_dir,nullptr,nullptr); med_rotate_segment( Cursegp, rotmat2 ); prev_point = coord; Curside = Side_opposite[AttachSide]; CurveSegs[CurveNumSegs]=Cursegp; CurveNumSegs++; } else return 0; } extract_up_vector_from_segment(cursegp, tvec); uangle = vm_vec_delta_ang( tvec, r4t, r4 ); if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4; if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4; if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4; if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4; extract_right_vector_from_segment(cursegp, tvec); rangle = vm_vec_delta_ang( tvec, r4t, r4 ); if (rangle >= F1_0/8) rangle -= F1_0/4; if (rangle >= F1_0/8) rangle -= F1_0/4; if (rangle <= -F1_0/8) rangle += F1_0/4; if (rangle <= -F1_0/8) rangle += F1_0/4; if ((uangle != 0) && (rangle != 0)) { maxscale = CurveNumSegs*F1_0; generate_banked_curve(maxscale, coeffs); } if (CurveNumSegs) { med_form_bridge_segment( Cursegp, Side_opposite[AttachSide], Markedsegp, Markedside ); CurveSegs[CurveNumSegs] = vmsegptr(Markedsegp->children[Markedside]); CurveNumSegs++; } Cursegp = OriginalSeg; Curside = OriginalSide; med_create_new_segment_from_cursegp(); //warn_if_concave_segments(); if (CurveNumSegs) return 1; else return 0; }