public void stay_block(BlockCollision collision)
 {
     if (on_block_stay.exists)
     {
         on_block_stay.data(collision);
     }
 }
 public void exit_block(BlockCollision collision)
 {
     if (on_block_exit.exists)
     {
         on_block_exit.data(collision);
     }
 }
 public void exit_block(BlockCollision collision)
 {
     if (OnBlockExit.exists)
     {
         OnBlockExit.data(collision);
     }
 }
 public void enter_block(BlockCollision collision)
 {
     if (on_block_enter.exists)
     {
         on_block_enter.data(collision);
     }
 }
 public void enter_block(BlockCollision collision)
 {
     if (OnBlockEnter.exists)
     {
         OnBlockEnter.data(collision);
     }
 }
 public void stay_block(BlockCollision collision)
 {
     if (OnBlockStay.exists)
     {
         OnBlockStay.data(collision);
     }
 }
예제 #7
0
        internal void notify_all_block()
        {
            if (collision_candidates.Count > 0)
            {
                BlockCollision next_collision = collision_candidates.Aggregate(
                    (closest, next_candidate) =>
                    closest.distance < next_candidate.distance ? closest : next_candidate);

                if (current_collisions.Count > 1)
                {
                    Debug.LogError("This should never happen.");
                }

                while (current_collisions.Count > 0)
                {
                    BlockCollision collision = current_collisions[current_collisions.Count - 1];
                    collision.self.get_observer().notify_exit_block(collision);
                    collision.other.get_observer().notify_exit_block(collision);
                }
                next_collision.self.get_observer().notify_enter_block(next_collision);
                next_collision.other.get_observer().notify_enter_block(next_collision);
                collision_candidates.Clear();
            }
            notify_stay_block();
        }
예제 #8
0
 internal void notify_enter_block(BlockCollision collision)
 {
     current_collisions.Add(collision);
     foreach (PlanetariaMonoBehaviour observer in observers)
     {
         observer.enter_block(collision);
     }
 }
예제 #9
0
 public void clear_block_collision()
 {
     while (current_collisions.Count > 0)
     {
         BlockCollision collision = current_collisions[current_collisions.Count - 1];
         collision.self.get_observer().notify_exit_block(collision);
         collision.other.get_observer().notify_exit_block(collision);
         current_collisions.Remove(collision);
     }
     collision_candidates.Clear();
 }
예제 #10
0
        internal void notify_exit_block(BlockCollision collision)
        {
            foreach (PlanetariaMonoBehaviour observer in observers)
            {
                observer.exit_block(collision);
            }

            //Debug.LogError(collision.GetHashCode() + " vs " + (current_collisions.Count > 0 ? current_collisions[0].GetHashCode().ToString() : ""));

            int before_count = current_collisions.Count;

            current_collisions.Remove(collision);
            int after_count = current_collisions.Count;

            Debug.Assert(before_count > after_count || after_count == 0,
                         before_count + " should be greater than " + after_count + " for " + collision.GetHashCode() + " vs " + (after_count > 0 ? current_collisions[0].GetHashCode().ToString() : ""));
        }
예제 #11
0
 public void potential_block_collision(Arc arc, PlanetariaCollider collider)
 {
     if (planetaria_rigidbody.exists)
     {
         if (current_collisions.Count == 0 || current_collisions[0].other != collider)
         {
             optional <BlockCollision> collision = BlockCollision.block_collision(this, arc, collider, planetaria_transformation, planetaria_rigidbody.data);
             if (collision.exists)
             {
                 if (planetaria_rigidbody.exists)
                 {
                     if (planetaria_rigidbody.data.collide(collision.data, this))
                     {
                         collision_candidates.Add(collision.data);
                     }
                 }
             }
         }
     }
 }
예제 #12
0
        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>();
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        public static optional <BlockCollision> block_collision(CollisionObserver observer, Arc arc, PlanetariaCollider collider, PlanetariaTransform transformation, PlanetariaRigidbody rigidbody)
        {
            optional <ArcVisitor> arc_visitor = collider.shape.arc_visitor(arc);

            if (!arc_visitor.exists)
            {
                Debug.LogError("This should never happen");
                return(new optional <BlockCollision>());
            }

            Quaternion block_to_world = collider.gameObject.internal_game_object.transform.rotation;
            Quaternion world_to_block = Quaternion.Inverse(block_to_world);

            Vector3 last_position    = world_to_block * rigidbody.get_previous_position();
            Vector3 current_position = world_to_block * rigidbody.get_position();

            float extrusion = transformation.scale / 2;
            optional <Vector3> intersection_point = PlanetariaIntersection.arc_path_intersection(arc, last_position, current_position, extrusion);

            if (!intersection_point.exists) // theoretically only happens with moving objects for discrete collision checks
            {
                // these functions are general inverses of one another, but also serve to constrain/normalize the position to the arc path.
                float intersection_angle = arc.position_to_angle(current_position);
                if (Mathf.Abs(intersection_angle) <= arc.angle() / 2)      // if the intersection is valid
                {
                    intersection_point = arc.position(intersection_angle); // set the collision to the extruded collision point
                }
            }
            if (!intersection_point.exists)
            {
                Debug.LogError("Research why this happened.");
                return(new optional <BlockCollision>());
            }
            BlockCollision result = new BlockCollision();
            float          angle  = arc.position_to_angle(intersection_point.data);

            result.geometry_visitor = ShapeVisitor.geometry_visitor(arc_visitor.data, angle, extrusion, collider.gameObject.internal_game_object.transform);
            intersection_point.data = block_to_world * intersection_point.data;
            result.distance         = Vector3.Angle(intersection_point.data, rigidbody.get_previous_position()) * Mathf.Deg2Rad;
            result.overshoot        = Vector3.Angle(intersection_point.data, rigidbody.get_position()) * Mathf.Deg2Rad;
            result.observer         = observer;
            result.self             = observer.collider();
            result.other            = collider;

            PlanetariaPhysicMaterial self  = result.self.material;
            PlanetariaPhysicMaterial other = result.other.material;

            result.elasticity = PlanetariaPhysics.blend(
                self.elasticity, self.elasticity_combine,
                other.elasticity, other.elasticity_combine);

            result.friction = PlanetariaPhysics.blend(
                self.friction, self.friction_combine,
                other.friction, other.friction_combine);

            result.magnetism =
                -(self.magnetism - other.magnetism * self.induced_magnetism_multiplier) *
                (other.magnetism - self.magnetism * other.induced_magnetism_multiplier);

            return(result);
        }