예제 #1
0
파일: ps_anim.c 프로젝트: Comanche93/eech
void update_person_animation (entity *en)
{
	person
		*raw;

	int
		wrapped,
		state;

	float
		frequency,
		remainder;

	ASSERT( en );

	raw = (person *) get_local_entity_data (en);

	//update character animation

	get_keyframed_animation_state (raw->person_animation_state, &state, &remainder);

	if (get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		if (state != PERSON_ANIM_NONE)
		{
			frequency = 1.0 / person_animation_database[state].duration;

			wrapped = update_entity_simple_keyframed_value (en, &remainder, frequency);

			if ( (wrapped) && (!person_animation_database[state].repeat) )
			{
				int
					state_selector;

				// set new animation that isn't same as previous
				state_selector = rand16 () % 4;

				switch ( state_selector )
				{

					case 0: state = ( state == PERSON_ANIM_STAND1 ) ? PERSON_ANIM_STAND2 : PERSON_ANIM_STAND1; break;
					case 1: state = ( state == PERSON_ANIM_STAND2 ) ? PERSON_ANIM_STAND3 : PERSON_ANIM_STAND2; break;
					case 2: state = ( state == PERSON_ANIM_STAND3 ) ? PERSON_ANIM_STAND4 : PERSON_ANIM_STAND3; break;
					case 3: state = ( state == PERSON_ANIM_STAND4 ) ? PERSON_ANIM_STAND1 : PERSON_ANIM_STAND4; break;
				}
				
				remainder = 0.0;
		
				raw->person_animation_state = state + remainder;

				ASSERT ( raw->person_animation_state < NUM_PERSON_ANIMS );
			}
			else
			{
				raw->person_animation_state = state + remainder;

				ASSERT ( raw->person_animation_state < NUM_PERSON_ANIMS );
			}
		}
	}
	else
	{
		raw->person_animation_state += 1.4 * get_entity_movement_delta_time ();

		if (raw->person_animation_state >= 1.0)
		{
			raw->person_animation_state = 1.0;
		}
	}
}
예제 #2
0
void ship_vehicle_death_movement (entity *en)
{

	ship_vehicle
		*raw;

	float
		speed,
		heading,
		pitch,
		roll;

	vec3d
		*pos,
		*velocity,
		new_pos;

	raw = get_local_entity_data (en);

	//
	// work out new position 
	//

	velocity = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR);

	pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

	new_pos.x = pos->x + (velocity->x * get_entity_movement_delta_time());
	new_pos.y = pos->y + (velocity->y * get_entity_movement_delta_time());
	new_pos.z = pos->z + (velocity->z * get_entity_movement_delta_time());
	
	//
	// update velocity
	//

	velocity->x -= (velocity->x * 0.2 * get_entity_movement_delta_time ());
	velocity->z -= (velocity->z * 0.2 * get_entity_movement_delta_time ());
	velocity->y -= (SHIP_SINK_RATE * get_entity_movement_delta_time ());

	speed = get_3d_vector_magnitude (velocity);

	set_local_entity_float_value (en, FLOAT_TYPE_VELOCITY, speed);

	//
	// update attitude
	//
		
	heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude);

	pitch = get_pitch_from_attitude_matrix (raw->vh.mob.attitude);

	pitch += (SHIP_SINK_DELTA_PITCH_RATE * get_entity_movement_delta_time());

	roll = get_roll_from_attitude_matrix (raw->vh.mob.attitude);
	
	roll += (SHIP_SINK_DELTA_ROLL_RATE * get_entity_movement_delta_time());

	get_3d_transformation_matrix (raw->vh.mob.attitude, heading, pitch, roll);

	//
	// set new position
	//

	set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos);

	clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_FIRE);
	clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_EXPLOSION_TRAIL);

	//
	// remove ship if totally obscured (i.e. sunk)
	//

	if (get_comms_model () == COMMS_MODEL_SERVER)
	{

		struct OBJECT_3D_BOUNDS
			*bounding_box;

		vec3d
			d;

		float
			obscured_altitude;

		bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (en, INT_TYPE_OBJECT_3D_SHAPE));

		d.x = bounding_box->xmax - bounding_box->xmin;
		d.y = bounding_box->ymax - bounding_box->ymin;
		d.z = bounding_box->zmax - bounding_box->zmin;

		obscured_altitude = -(0.5 * get_3d_vector_magnitude (&d));

		if (new_pos.y < obscured_altitude)
		{
			//
			// ship is no longer visible
			//

			destroy_client_server_entity_family (en);
		}
	}
}
예제 #3
0
파일: co_grstab.c 프로젝트: Comanche93/eech
void handle_ground_stabilisation (void)
{

	// loke 030322
	// handle the ground stabilisation
	// improved stabilization thealx 130218

	if (eo_ground_stabilised)
	{
		vec3d
			*velocity;

		matrix3x3
			attitude;
				
		float
			accel,
			delta_pitch,
			delta_roll,
			heading,
			anglex,
			angley,
			correctionx;
				
		float
			horizontal_pan_offset,
			vertical_pan_offset;
						
		velocity = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_MOTION_VECTOR);
		accel = velocity->y * get_entity_movement_delta_time();


		get_local_entity_attitude_matrix (get_gunship_entity (), attitude);

		heading = atan2 (attitude [2][0], attitude [2][2]);

		delta_pitch = pitch - asin (attitude [2][1]);
		pitch = asin (attitude [2][1]);

		delta_roll = roll - atan2 (-attitude [0][1], attitude [1][1]);
		roll = atan2 (-attitude [0][1], attitude [1][1]);

		if (eo_azimuth > (PI / 2))
		{
			anglex = PI - eo_azimuth;
			correctionx = - cos (anglex);
		}
		else if (eo_azimuth < (- PI / 2))
		{
			anglex = - PI - eo_azimuth;
			correctionx = - cos (anglex);
		}
		else
		{
			anglex = eo_azimuth;
			correctionx = cos (anglex);
		}

		angley = eo_elevation;				
				 
		// GCsDriver start 180 deg. bug workaround

		// problem :
		// when crossing 180 deg stabilised view switches focus to 109 or 250 deg
		// crossing 0 / 360 deg is fine

		// solution : ?
		// sth like this should do but what`s the C equivalent ?
		// horizontal_pan_offset = mod((eo_ground_stabilisation_value_heading - heading), 2*pi);

		// workaround :
		// if we cross border we have to invert the rad
		// this gives just a little "glitch" when crossing 180 AND 0/360 deg
		// glitch width depends on turn rate (and distance centered point to 180/0 line)

		if ((eo_ground_stabilisation_value_heading > 0)&&(heading < 0))
		{
			eo_ground_stabilisation_value_heading *= -1;
			anglex *= -1;
 		}
		else if ((eo_ground_stabilisation_value_heading < 0)&&(heading > 0))
		{
			eo_ground_stabilisation_value_heading *= -1;
			anglex *= -1;
		}
				
		// GCsDriver end 180 deg. bug workaround
					
		horizontal_pan_offset = (eo_ground_stabilisation_value_heading - heading) * cos(angley) + delta_roll * sin(angley) * correctionx + sin(anglex) * sin(delta_pitch) * eo_elevation;
		
		vertical_pan_offset = (eo_ground_stabilisation_value_pitch - pitch) * correctionx - delta_roll * sin(anglex) - 0.00028 * accel;

		eo_azimuth +=  horizontal_pan_offset;

		if (eo_azimuth > 0)
		{
			eo_azimuth = min (eo_azimuth, eo_max_azimuth);
		}
		else
		{
			eo_azimuth = max (eo_azimuth, eo_min_azimuth);
		}
				
		eo_elevation += vertical_pan_offset;

		if (vertical_pan_offset > 0)
		{
			eo_elevation = min (eo_elevation, eo_max_elevation);
		}
		else
		{
			eo_elevation = max (eo_elevation, eo_min_elevation);
		}

		eo_ground_stabilisation_value_heading = heading;

		eo_ground_stabilisation_value_pitch = pitch;
	}
}
예제 #4
0
void ship_vehicle_movement (entity *en)
{
	ship_vehicle
		*raw;

	entity
		*guide,
		*current_waypoint;

	vec3d
		wp_pos,
		wp_vec,
		new_pos;

	float
		roll,
		pitch,
		heading,
		sqr_range,
		turn_rate,
		required_heading,
		delta_heading,
		current_velocity,
		new_velocity;

	raw = get_local_entity_data (en);

	//
	// abort if mobile is not moving (i.e. landed, or dead)
	//

	if (!get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING))
	{

		return;
	}

	//
	// abort if the mobile has no PRIMARY guide (also stops ships from moving if just engaging)
	//

	guide = get_local_entity_primary_guide (en);

	if (!guide)
	{
		return;
	}

	current_waypoint = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT);

	ASSERT (current_waypoint);

	current_velocity = raw->vh.mob.velocity;

	//
	// GET WAYPOINT POSITION
	//

	ship_movement_get_waypoint_position (en, &wp_pos);

	wp_vec.x = wp_pos.x - raw->vh.mob.position.x;
	wp_vec.y = 0;
	wp_vec.z = wp_pos.z - raw->vh.mob.position.z;

	sqr_range = ((wp_vec.x * wp_vec.x) + (wp_vec.z * wp_vec.z));

	#if DEBUG_MODULE

	create_vectored_debug_3d_object (&wp_pos, (vec3d *) &raw->vh.mob.attitude [1], OBJECT_3D_RED_ARROW, 0, 0.20);

	#endif
	
	// ????
	if (fabs (sqr_range) < 1 * CENTIMETRE)
	{
		wp_vec.z = 0;
		wp_vec.y = 0;
		wp_vec.z = 1;
	}

	////////////////////////////////////////
	//
	// angles
	//
	////////////////////////////////////////

	// heading

	normalise_3d_vector (&wp_vec);

	heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude);

	required_heading = atan2 (wp_vec.x, wp_vec.z);

	{

		float
			angle,
			range,
			v;

		range = sqrt (sqr_range);
	
		v = sqrt (0.5 * range * vehicle_database [raw->vh.mob.sub_type].g_max);

		angle = ((raw->vh.mob.attitude [2][0] * wp_vec.x) + (raw->vh.mob.attitude [2][2] * wp_vec.z));

		if (angle < 0.707) // 45 degs.
		{

			// wp behind ship
	
			#if DEBUG_MODULE
		
			debug_log ("SH_MOVE: ship cannot reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max);

			#endif

			new_velocity = bound (v, 0.0, get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY));
		}
		else
		{
	
			#if DEBUG_MODULE
		
			debug_log ("SH_MOVE: ship can reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max);

			#endif

			new_velocity = get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY);
		}
	}

	turn_rate = 0.0;

	if (raw->vh.mob.velocity != 0.0)
	{

		turn_rate = fabs (vehicle_database [raw->vh.mob.sub_type].g_max / raw->vh.mob.velocity);
	}

	delta_heading = required_heading - heading;

	if (delta_heading <= -PI)
	{

		delta_heading += PI2;
	}

	if (delta_heading >= PI)
	{

		delta_heading -= PI2;
	}

	delta_heading = bound (delta_heading, -turn_rate, turn_rate);

	heading += delta_heading * get_entity_movement_delta_time ();

	pitch = 0.0;

	roll = 0.0;

	////////////////////////////////////////
	//
	// attitude
	//
	////////////////////////////////////////

	get_3d_transformation_matrix (raw->vh.mob.attitude, heading, rad (pitch), rad (roll));

	////////////////////////////////////////
	//
	// velocity
	//
	////////////////////////////////////////

	{
		float
			maximum_acceleration,
			required_acceleration;

		required_acceleration = (new_velocity - raw->vh.mob.velocity);

		maximum_acceleration = get_local_entity_float_value (en, FLOAT_TYPE_MAX_ACCELERATION);
		
		raw->vh.mob.velocity += min (required_acceleration, maximum_acceleration) * get_entity_movement_delta_time ();
	}

	////////////////////////////////////////
	//
	// position
	//
	////////////////////////////////////////

	new_pos.x = raw->vh.mob.position.x + (raw->vh.mob.velocity * raw->vh.mob.zv.x * get_entity_movement_delta_time ());
	new_pos.y = 0.0;
	new_pos.z = raw->vh.mob.position.z + (raw->vh.mob.velocity * raw->vh.mob.zv.z * get_entity_movement_delta_time ());

	bound_position_to_map_volume (&new_pos);

	//
	// Calculate motion vector for view system
	//

	raw->vh.mob.motion_vector.x = (new_pos.x - raw->vh.mob.position.x) * get_one_over_delta_time ();
	raw->vh.mob.motion_vector.y = 0.0;
	raw->vh.mob.motion_vector.z = (new_pos.z - raw->vh.mob.position.z) * get_one_over_delta_time ();

	new_pos.y = 0.0;

	set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos);
}