void draw_debug_guide_entity (entity *en) { waypoint *raw; entity *member, *this_waypoint; vec3d direction, guide_pos, *member_pos, *this_waypoint_position; float length; ASSERT (en); raw = (waypoint *) get_local_entity_data (en); // // get guide position // get_local_entity_vec3d (en, VEC3D_TYPE_GUIDE_POSITION, &guide_pos); // // get waypoint position // this_waypoint_position = NULL; this_waypoint = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT); ASSERT (this_waypoint); // // draw guide position // direction.x = 0.0; direction.y = 1.0; direction.z = 0.0; create_vectored_debug_3d_object (&guide_pos, &direction, OBJECT_3D_SPHERICAL_TEST, 0.0, 1.0); if (get_local_entity_int_value (this_waypoint, INT_TYPE_POSITION_TYPE) != POSITION_TYPE_VIRTUAL) { this_waypoint_position = get_local_entity_vec3d_ptr (this_waypoint, VEC3D_TYPE_POSITION); length = get_3d_range (&guide_pos, this_waypoint_position); if (length > 0.0) { create_debug_3d_line (&guide_pos, this_waypoint_position, sys_col_yellow, 0.0); } } // // draw vector to group position // member = get_local_entity_first_child (en, LIST_TYPE_FOLLOWER); while (member) { member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); length = get_3d_range (&guide_pos, member_pos); if (length > 0.0) { create_debug_3d_line (&guide_pos, member_pos, sys_col_light_red, 0.0); } member = get_local_entity_child_succ (member, LIST_TYPE_FOLLOWER); } }
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); }