private void synchronize_velocity_air_to_ground() { if (observer.exists) { horizontal_velocity = Vector3.Dot(velocity, Bearing.right(planetaria_transform.position, collision.geometry_visitor.normal())); vertical_velocity = Vector3.Dot(velocity, collision.geometry_visitor.normal()); } }
private void synchronize_velocity_ground_to_air() { if (observer.exists) { Vector3 x = horizontal_velocity * Bearing.right(planetaria_transform.position, collision.geometry_visitor.normal()); Vector3 y = vertical_acceleration * Time.fixedDeltaTime * collision.geometry_visitor.normal(); velocity = x + y; } }
private void grounded_accelerate(float delta) { Vector3 normal = collision.geometry_visitor.normal(); Vector3 right = Bearing.right(collision.geometry_visitor.position(), normal); acceleration = get_acceleration(); horizontal_acceleration = Vector3.Dot(acceleration, right); vertical_acceleration = Vector3.Dot(acceleration, normal) - collision.magnetism; vertical_velocity += vertical_acceleration * Time.fixedDeltaTime; if (!collision.grounded(internal_velocity)) // TODO: check centripedal force { derail(0, vertical_acceleration * delta); // Force OnCollisionExit, "un-collision" (and accelerate for a frame) } }
/// <summary> /// Inspector - Determine the type of corner connecting the left-hand-side and right-hand-side Arcs (concave/convex/straight). /// </summary> /// <param name="left">Arc that will connect to beginning.</param> /// <param name="right">Arc that will connect to end.</param> /// <returns> /// GeometryType.ConvexCorner if the corner arc is convex. /// GeometryType.ConcaveCorner if the corner arc is concave. /// GeometryType.StraightCorner if the corner arc is a straight angle. /// </returns> public static ArcType corner_type(Arc left, Arc right) { // Both cases Vector3 normal_for_left = left.end_normal(); // Straight angle check Vector3 normal_for_right = right.begin_normal(); // Convex/Concave check Vector3 rightward_for_right = Bearing.right(right.begin(), right.begin_normal()); if (Vector3.Dot(normal_for_left, normal_for_right) > 1 - Precision.tolerance) { return(ArcType.StraightCorner); } else { return(Vector3.Dot(normal_for_left, rightward_for_right) < Precision.tolerance ? ArcType.ConvexCorner : ArcType.ConcaveCorner); } }
public void derail(float x_velocity, float y_velocity) { if (observer.exists && observer.data.colliding()) { BlockCollision collision = observer.data.collisions()[0]; collision.geometry_visitor.move_position(0, transform.scale / 2 * (1 + 1e-3f)); // extrude the player so they do not accidentally re-collide (immediately) // FIXME: magic number, move to Precision.* x_velocity += horizontal_velocity; //y_velocity += vertical_velocity; planetaria_transform.position = collision.geometry_visitor.position(); Vector3 normal = collision.geometry_visitor.normal(); Vector3 right = Bearing.right(planetaria_transform.position, normal); velocity = right * x_velocity + normal * y_velocity; Debug.DrawRay(planetaria_transform.position, velocity, Color.yellow, 1f); acceleration = get_acceleration(); // TODO: accelerate vertically observer.data.clear_block_collision(); observer = new optional <CollisionObserver>(); } }
public bool collide(BlockCollision collision, CollisionObserver observer) { if (this.observer.exists) { this.observer.data.clear_block_collision(); } aerial_move(-collision.overshoot); // this only (truly) works with perpendicular vectors? this.observer = observer; this.collision = collision; horizontal_velocity = Vector3.Dot(velocity, Bearing.right(planetaria_transform.position, collision.geometry_visitor.normal())); vertical_velocity = Vector3.Dot(velocity, collision.geometry_visitor.normal()); if (vertical_velocity < 0) { vertical_velocity *= -collision.elasticity; } grounded_accelerate(0); return(this.observer.exists); }