protected override sealed void Awake()
 {
     base.Awake();
     initialize();
     StartCoroutine(wait_for_fixed_update());
     observer = new CollisionObserver();
     observer.initialize(this, this.GetComponentsInParent <PlanetariaMonoBehaviour>());
 }
Example #2
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);
        }
Example #3
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);
        }