// ----------------------------------------------------------------------------------------------------------- // add rotational velocity & acceleration void do_physics_sim_rot(object *obj) { vms_angvec tangles; vms_matrix rotmat,new_orient; //fix rotdrag_scale; physics_info *pi; Assert(FrameTime > 0); //Get MATT if hit this! pi = &obj->mtype.phys_info; if (!(pi->rotvel.x || pi->rotvel.y || pi->rotvel.z || pi->rotthrust.x || pi->rotthrust.y || pi->rotthrust.z)) return; if (obj->mtype.phys_info.drag) { int count; vms_vector accel; fix drag,r,k; count = FrameTime / FT; r = FrameTime % FT; k = fixdiv(r,FT); drag = (obj->mtype.phys_info.drag*5)/2; if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_copy_scale(&accel,&obj->mtype.phys_info.rotthrust,fixdiv(f1_0,obj->mtype.phys_info.mass)); while (count--) { vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel); vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag); } //do linear scale on remaining bit of time vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k); vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag)); } else { fix total_drag=f1_0; while (count--) total_drag = fixmul(total_drag,f1_0-drag); //do linear scale on remaining bit of time total_drag = fixmul(total_drag,f1_0-fixmul(k,drag)); vm_vec_scale(&obj->mtype.phys_info.rotvel,total_drag); } } //now rotate object //unrotate object for bank caused by turn if (obj->mtype.phys_info.turnroll) { vms_matrix new_pm; tangles.p = tangles.h = 0; tangles.b = -obj->mtype.phys_info.turnroll; vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat); obj->orient = new_pm; } tangles.p = fixmul(obj->mtype.phys_info.rotvel.x,FrameTime); tangles.h = fixmul(obj->mtype.phys_info.rotvel.y,FrameTime); tangles.b = fixmul(obj->mtype.phys_info.rotvel.z,FrameTime); vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_orient,&obj->orient,&rotmat); obj->orient = new_orient; if (obj->mtype.phys_info.flags & PF_TURNROLL) set_object_turnroll(obj); //re-rotate object for bank caused by turn if (obj->mtype.phys_info.turnroll) { vms_matrix new_pm; tangles.p = tangles.h = 0; tangles.b = obj->mtype.phys_info.turnroll; vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat); obj->orient = new_pm; } check_and_fix_matrix(&obj->orient); }
// ----------------------------------------------------------------------------------------------------------- // add rotational velocity & acceleration void do_physics_sim_rot(object *obj) { vms_angvec tangles; vms_matrix rotmat,new_orient; //fix rotdrag_scale; physics_info *pi; Assert(FrameTime > 0); //Get MATT if hit this! pi = &obj->mtype.phys_info; if (!(pi->rotvel.x || pi->rotvel.y || pi->rotvel.z || pi->rotthrust.x || pi->rotthrust.y || pi->rotthrust.z)) return; if (obj->mtype.phys_info.drag) { int count; vms_vector accel; fix drag,r,k; count = FrameTime / FT; r = FrameTime % FT; k = fixdiv(r,FT); drag = (obj->mtype.phys_info.drag*5)/2; const char ORIGINAL = 0; const char LINEAR_INTERPOLATION = 1; const char GEOMETRIC_DRAG = 2; const char STRATEGY = ORIGINAL; if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_copy_scale(&accel,&obj->mtype.phys_info.rotthrust,fixdiv(f1_0,obj->mtype.phys_info.mass)); } if(STRATEGY == ORIGINAL) { while (count--) { if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel); } vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag); } //do linear scale on remaining bit of time if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k); } vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag)); } else if (STRATEGY == LINEAR_INTERPOLATION) { vms_vector target_rotvel; vm_vec_copy_scale(&target_rotvel, &obj->mtype.phys_info.rotvel, F1_0); // Target 21.3 FPS -- three iterations for(int i = 0; i < 3; i++) { if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_add2(&target_rotvel, &accel); } vm_vec_scale(&target_rotvel,f1_0-drag); } fix target_frametime = F1_0 / 64 * 3; fix interpolation_fraction = fixdiv(FrameTime, target_frametime); vm_vec_sub2(&target_rotvel, &obj->mtype.phys_info.rotvel); vm_vec_scale(&target_rotvel, interpolation_fraction); vm_vec_add2(&obj->mtype.phys_info.rotvel, &target_rotvel); } else if(STRATEGY == GEOMETRIC_DRAG) { while (count--) { if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel); } vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag); } //do linear scale on remaining bit of time if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k); } double target_frametime = 3.0/64.0; const double fix_offset = 65536.0; double interpolation_fraction = ((double)(r) / fix_offset) / target_frametime ; double ddrag = (double)(drag) / fix_offset; double kdrag = pow((1.0 - ddrag), interpolation_fraction*3); fix fractional_drag = (fix)(kdrag * fix_offset); vm_vec_scale(&obj->mtype.phys_info.rotvel,fractional_drag); //vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag)); } /* fix k_drag = f1_0-fixmul(k,drag); if(FrameTime < F1_0/30) { // Pegged to 30 FPS for now double fix_offset = (double) F1_0; double target_framerate = 20.0; double ddrag = ((double) drag)/fix_offset; //double target_drag = (1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag*2.0/15.0); // Drag value multiplied by at 30 hz double target_drag = (1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag*2.0/15.0); // Drag value at 20 hz double frame_pow = 20.0 * ((double)(FrameTime)/fix_offset); double frame_drag = pow(target_drag, frame_pow); k_drag = (fix) (frame_drag*fix_offset); } if (obj->mtype.phys_info.flags & PF_USES_THRUST) { vm_vec_copy_scale(&accel,&obj->mtype.phys_info.rotthrust,fixdiv(f1_0,obj->mtype.phys_info.mass)); // CED -- fix this for frame independence! while (count--) { vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel); vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag); } //do linear scale on remaining bit of time vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k); //vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag)); vm_vec_scale(&obj->mtype.phys_info.rotvel,k_drag); } else { fix total_drag=f1_0; while (count--) total_drag = fixmul(total_drag,f1_0-drag); //do linear scale on remaining bit of time //total_drag = fixmul(total_drag,f1_0-fixmul(k,drag)); total_drag = fixmul(total_drag,k_drag); vm_vec_scale(&obj->mtype.phys_info.rotvel,total_drag); } */ } //now rotate object //unrotate object for bank caused by turn if (obj->mtype.phys_info.turnroll) { vms_matrix new_pm; tangles.p = tangles.h = 0; tangles.b = -obj->mtype.phys_info.turnroll; vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat); obj->orient = new_pm; } tangles.p = fixmul(obj->mtype.phys_info.rotvel.x,FrameTime); tangles.h = fixmul(obj->mtype.phys_info.rotvel.y,FrameTime); tangles.b = fixmul(obj->mtype.phys_info.rotvel.z,FrameTime); vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_orient,&obj->orient,&rotmat); obj->orient = new_orient; if (obj->mtype.phys_info.flags & PF_TURNROLL) set_object_turnroll(obj); //re-rotate object for bank caused by turn if (obj->mtype.phys_info.turnroll) { vms_matrix new_pm; tangles.p = tangles.h = 0; tangles.b = obj->mtype.phys_info.turnroll; vm_angles_2_matrix(&rotmat,&tangles); vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat); obj->orient = new_pm; } check_and_fix_matrix(&obj->orient); }