// ----------------------------------------------------------------------------- // Make segment *sp bigger in dimension dimension by amount amount. void med_scale_segment_new(segment *sp, int dimension, fix amount) { vms_matrix mat; Modified_vertex_index = 0; med_extract_matrix_from_segment(sp, &mat); switch (dimension) { case XDIM: scale_free_verts(sp, &mat.rvec, WLEFT, -amount); scale_free_verts(sp, &mat.rvec, WRIGHT, +amount); break; case YDIM: scale_free_verts(sp, &mat.uvec, WBOTTOM, -amount); scale_free_verts(sp, &mat.uvec, WTOP, +amount); break; case ZDIM: scale_free_verts(sp, &mat.fvec, WFRONT, -amount); scale_free_verts(sp, &mat.fvec, WBACK, +amount); break; } validate_modified_segments(); }
void reset_object(short objnum) { object *obj = &Objects[objnum]; med_extract_matrix_from_segment(&Segments[obj->segnum],&obj->orient); }
static void reset_object(const vobjptridx_t obj) { med_extract_matrix_from_segment(vcsegptr(obj->segnum), &obj->orient); }
// ------------------------------------------------------------------------------------ int place_object(segment *segp, vms_vector *object_pos, int object_type) { short objnum; object *obj; vms_matrix seg_matrix; med_extract_matrix_from_segment(segp,&seg_matrix); switch(ObjType[object_type]) { case OL_HOSTAGE: objnum = obj_create(OBJ_HOSTAGE, -1, segp-Segments,object_pos,&seg_matrix,HOSTAGE_SIZE, CT_NONE,MT_NONE,RT_HOSTAGE); if ( objnum < 0 ) return 0; obj = &Objects[objnum]; // Fill in obj->id and other hostage info hostage_init_info( objnum ); obj->control_type = CT_POWERUP; obj->rtype.vclip_info.vclip_num = Hostage_vclip_num[ObjId[object_type]]; obj->rtype.vclip_info.frametime = Vclip[obj->rtype.vclip_info.vclip_num].frame_time; obj->rtype.vclip_info.framenum = 0; break; case OL_ROBOT: objnum = obj_create(OBJ_ROBOT,ObjId[object_type],segp-Segments,object_pos, &seg_matrix,Polygon_models[Robot_info[ObjId[object_type]].model_num].rad, CT_AI,MT_PHYSICS,RT_POLYOBJ); if ( objnum < 0 ) return 0; obj = &Objects[objnum]; //Set polygon-object-specific data obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num; obj->rtype.pobj_info.subobj_flags = 0; //set Physics info obj->mtype.phys_info.mass = Robot_info[obj->id].mass; obj->mtype.phys_info.drag = Robot_info[obj->id].drag; obj->mtype.phys_info.flags |= (PF_LEVELLING); obj->shields = Robot_info[obj->id].strength; { int hide_segment; if (Markedsegp) hide_segment = Markedsegp-Segments; else hide_segment = -1; // robots which lunge forward to attack cannot have behavior type still. if (Robot_info[obj->id].attack_type) init_ai_object(obj-Objects, AIB_NORMAL, hide_segment); else init_ai_object(obj-Objects, AIB_STILL, hide_segment); } break; case OL_POWERUP: objnum = obj_create(OBJ_POWERUP,ObjId[object_type], segp-Segments,object_pos,&seg_matrix,Powerup_info[ObjId[object_type]].size, CT_POWERUP,MT_NONE,RT_POWERUP); if ( objnum < 0 ) return 0; obj = &Objects[objnum]; //set powerup-specific data obj->rtype.vclip_info.vclip_num = Powerup_info[obj->id].vclip_num; obj->rtype.vclip_info.frametime = Vclip[obj->rtype.vclip_info.vclip_num].play_time/Vclip[obj->rtype.vclip_info.vclip_num].num_frames; obj->rtype.vclip_info.framenum = 0; if (obj->id == POW_VULCAN_WEAPON) obj->ctype.powerup_info.count = VULCAN_WEAPON_AMMO_AMOUNT; else obj->ctype.powerup_info.count = 1; break; case OL_CLUTTER: case OL_CONTROL_CENTER: { int obj_type,control_type; if (ObjType[object_type]==OL_CONTROL_CENTER) { obj_type = OBJ_CNTRLCEN; control_type = CT_CNTRLCEN; } else { obj_type = OBJ_CLUTTER; control_type = CT_NONE; } objnum = obj_create(obj_type,object_type,segp-Segments,object_pos, &seg_matrix,Polygon_models[ObjId[object_type]].rad, control_type,MT_NONE,RT_POLYOBJ); if ( objnum < 0 ) return 0; obj = &Objects[objnum]; obj->shields = ObjStrength[object_type]; //Set polygon-object-specific data obj->shields = ObjStrength[object_type]; obj->rtype.pobj_info.model_num = ObjId[object_type]; obj->rtype.pobj_info.subobj_flags = 0; break; } case OL_PLAYER: { objnum = obj_create(OBJ_PLAYER,ObjId[object_type],segp-Segments,object_pos, &seg_matrix,Polygon_models[Player_ship->model_num].rad, CT_NONE,MT_PHYSICS,RT_POLYOBJ); if ( objnum < 0 ) return 0; obj = &Objects[objnum]; //Set polygon-object-specific data obj->rtype.pobj_info.model_num = Player_ship->model_num; obj->rtype.pobj_info.subobj_flags = 0; //for (i=0;i<MAX_SUBMODELS;i++) // vm_angvec_zero(&obj->rtype.pobj_info.anim_angles[i]); //set Physics info vm_vec_zero(&obj->mtype.phys_info.velocity); obj->mtype.phys_info.mass = Player_ship->mass; obj->mtype.phys_info.drag = Player_ship->drag; obj->mtype.phys_info.flags |= PF_TURNROLL | PF_LEVELLING | PF_WIGGLE; obj->shields = i2f(100); break; } default: break; } Cur_object_index = objnum; //Cur_object_seg = Cursegp; show_objects_in_segment(Cursegp); //mprintf the objects Update_flags |= UF_WORLD_CHANGED; 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; }