コード例 #1
0
//	-----------------------------------------------------------------------------------------------------------
// 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);
}
コード例 #2
0
ファイル: physics.c プロジェクト: RoosterSixOne/DXX-Retro
//	-----------------------------------------------------------------------------------------------------------
// 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);
}