コード例 #1
0
 public void stay_field(PlanetariaCollider field)
 {
     if (OnFieldStay.exists)
     {
         OnFieldStay.data(field);
     }
 }
コード例 #2
0
 public void enter_field(PlanetariaCollider field)
 {
     if (OnFieldEnter.exists)
     {
         OnFieldEnter.data(field);
     }
 }
コード例 #3
0
 internal void notify_enter_field(PlanetariaCollider field)
 {
     foreach (PlanetariaMonoBehaviour observer in observers)
     {
         observer.enter_field(field);
     }
 }
コード例 #4
0
 public void exit_field(PlanetariaCollider field)
 {
     if (OnFieldExit.exists)
     {
         OnFieldExit.data(field);
     }
 }
コード例 #5
0
 public void enter_field(PlanetariaCollider field)
 {
     if (on_field_enter.exists)
     {
         on_field_enter.data(field);
     }
 }
コード例 #6
0
 public void stay_field(PlanetariaCollider field)
 {
     if (on_field_stay.exists)
     {
         on_field_stay.data(field);
     }
 }
コード例 #7
0
 public void exit_field(PlanetariaCollider field)
 {
     if (on_field_exit.exists)
     {
         on_field_exit.data(field);
     }
 }
コード例 #8
0
        //barycentricCoordinate	The barycentric coordinate of the triangle we hit. // RESEARCH: are there any equivalents to triangles I should be creating?
        //lightmapCoord	The uv lightmap coordinate at the impact point.
        //textureCoord	The uv texture coordinate at the collision location.
        //textureCoord2	The secondary uv texture coordinate at the impact point.
        //triangleIndex	The index of the triangle that was hit.

        /// <summary>
        /// Constructor - creates the Planetaria equivalent of UnityEngine.RaycastHit
        /// </summary>
        /// <param name="raycast_arc">The path along which the raycast (inverse path for negative distances).</param>
        /// <param name="geometry_arc">The arc which intersects the raycast (i.e. the arc hit).</param>
        /// <param name="intersection_point">The intersection point of two circular arcs in 3D space.</param>
        /// <returns>The result of a point sweep / raycast in spherical 2D space.</returns>
        private PlanetariaRaycastHit(Arc raycast_arc, PlanetariaCollider planetaria_collider, Arc geometry_arc, Vector3 intersection_point, float raycast_distance)
        {
            arc      = geometry_arc;
            collider = planetaria_collider;

            distance  = raycast_arc.position_to_angle(intersection_point) * (raycast_arc.length() / raycast_arc.angle()); // TODO: verify
            distance += raycast_arc.length() / 2;
            if (raycast_distance < 0)
            {
                distance = raycast_arc.length() - distance;
            }
            positive_face_collision = true; // FIXME: HACK: LAZY: // also dynamic changes

            Transform  internal_transform = collider.gameObject.internal_game_object.GetComponent <Transform>();
            Quaternion arc_to_world       = internal_transform.rotation;
            Quaternion world_to_arc       = Quaternion.Inverse(arc_to_world);

            Vector3 local_intersection_point = world_to_arc * intersection_point;
            float   angle        = raycast_arc.position_to_angle(local_intersection_point);
            Vector3 local_normal = raycast_arc.normal(angle);

            normal    = arc_to_world * local_normal;
            point     = intersection_point;
            rigidbody = collider.GetComponent <PlanetariaRigidbody>();
            transform = Miscellaneous.GetOrAddComponent <PlanetariaTransform>(collider);
        }
コード例 #9
0
 public static void prepare(PlanetariaCollider collider)
 {
     discontinuities = new Dictionary <Arc, List <Discontinuity> >();
     find_discontinuities(collider);
     sort_discontinuities();
     collider_variable = collider;
 }
コード例 #10
0
        /// <summary>
        /// Inspector - Finds the collision points between an arc extrapolated to be distance long (the PlanetariaRaycastHit structs have no particular order)
        /// </summary>
        /// <param name="arc">A fragment that defines the arc in space (might not be fully used or return collisions after the end of the arc).</param>
        /// <param name="distance">The distance to raycast (may be greater than or less than the length of the arc - or negative).</param>
        /// <param name="layer_mask">The collision mask that defines which objects will be ignored.</param>
        /// <returns>All of the collision points of the Raycast (listed exactly once).</returns>
        private static PlanetariaRaycastHit[] unordered_raycast_all(Arc arc, float distance, int layer_mask, bool collide_with_fields)
        {
            //float angle = arc.angle(); // this would determine the intersections for the un-modified arc (ignoring distance)

            // desired_angle = desired_length * (partial_angle/partial_length) i.e. length * length_to_angle ratio
            float desired_angle = distance * (arc.angle() / arc.length()); // TODO: verify negative distances go backwards

            desired_angle = Mathf.Clamp(desired_angle, -2 * Mathf.PI, 2 * Mathf.PI);

            // primative arc points
            Vector3 arc_left   = arc.position(-arc.angle() / 2);
            Vector3 arc_center = arc.position(-arc.angle() / 2 + desired_angle / 2);
            Vector3 arc_right  = arc.position(-arc.angle() / 2 + desired_angle);

            SerializedArc ray_arc = ArcFactory.curve(arc_left, arc_center, arc_right);

            PlanetariaShape ray_shape = PlanetariaShape.Create(new List <SerializedArc> {
                ray_arc
            }, false);

            // composites
            Vector3 arc_boundary_midpoint = (arc_left + arc_right) / 2;                      // if the arc is like a wooden bow, this is the midpoint of the string
            Vector3 arc_forward           = (arc_center - arc_boundary_midpoint).normalized; // the direction a hypothetical arrow would travel
            Vector3 arc_up = arc.floor().normal;                                             // orthogonal/perpendicular to the imaginary "bow"

            // UnityEngine.Physics.OverlapBox() requirements
            // FIXME: OPTIMIZE: half_extents currently provides unnecessary false positives because the "width" of plane (the depth into the distance and zero height are fine)
            Vector3    half_extents = new Vector3(1, 0, 1);                    // The largest collision "box" for a unit sphere is a radius of 1 in the x-z plane; height along y is 0.
            Vector3    center       = arc_boundary_midpoint + arc_forward * 1; // The center of the "box" must be offset 1 (the radius) along the forward axis from the two arc boundaries.
            Quaternion rotation     = Quaternion.LookRotation(arc_forward, arc_up);

            // SphereColliders (only) that represent potential collisions (not guaranteed).
            Collider[] colliders = Physics.OverlapBox(center, half_extents, rotation, layer_mask, QueryTriggerInteraction.Collide); // TODO: verify this casts properly
            List <PlanetariaRaycastHit> raycast_hits = new List <PlanetariaRaycastHit>();

            Debug.Log(colliders.Length);
            foreach (SphereCollider sphere_collider in colliders)
            {
                PlanetariaCollider planetaria_collider = PlanetariaCache.collider_fetch(sphere_collider);
                if (planetaria_collider.is_field && !collide_with_fields)
                {
                    Debug.LogError("Why?");
                    continue;
                }
                Quaternion geometry_rotation = planetaria_collider.gameObject.internal_game_object.transform.rotation;
                Debug.Log("Found a collider with " + planetaria_collider.shape.Length + " arcs.");
                foreach (Arc geometry_arc in ray_shape.block_collision(planetaria_collider.shape, geometry_rotation))
                {
                    Vector3[] intersections = PlanetariaIntersection.raycast_intersection(arc, geometry_arc, distance, geometry_rotation); // TODO: verify distance is indeed the angle in this scenario
                    Debug.Log("Found an arc with " + intersections.Length + " intersections.");
                    foreach (Vector3 intersection in intersections)
                    {
                        PlanetariaRaycastHit single_collision = PlanetariaRaycastHit.hit(arc, planetaria_collider, geometry_arc, intersection, distance);
                        raycast_hits.Add(single_collision);
                    }
                }
            }
            return(raycast_hits.ToArray());
        }
コード例 #11
0
 internal void notify_exit_field(PlanetariaCollider field)
 {
     foreach (PlanetariaMonoBehaviour observer in observers)
     {
         observer.exit_field(field);
     }
     //current_fields.Remove(field); // Don't want invalidated iterators - swap at end of loop
 }
コード例 #12
0
 public static PlanetariaCollider collider_fetch(SphereCollider key)
 {
     if (!collider_cache.ContainsKey(key))
     {
         PlanetariaCollider planetaria_collider = key.GetComponent <PlanetariaCollider>();
         Debug.Assert(planetaria_collider, "SphereColliders must be matched with PlanetariaColliders");
         collider_cache.Add(key, planetaria_collider);
     }
     return(collider_cache[key]);
 }
コード例 #13
0
 public void initialize(PlanetariaCollider observed, PlanetariaMonoBehaviour[] observers)
 {
     this.planetaria_collider       = observed;
     this.planetaria_rigidbody      = observed.GetComponent <PlanetariaRigidbody>();
     this.planetaria_transformation = observed.GetComponent <PlanetariaTransform>();
     foreach (PlanetariaMonoBehaviour observer in observers)
     {
         if (!this.observers.Contains(observer))
         {
             this.observers.Add(observer);
         }
     }
 }
コード例 #14
0
 /// <summary>
 /// Mutator - find all intersections along x=0 or z=0 arcs in southern hemisphere.
 /// </summary>
 /// <param name="block">The block (set of arcs) to be inspected.</param>
 private static void find_discontinuities(PlanetariaCollider collider)
 {
     foreach (Arc arc in collider.shape.arcs)
     {
         for (int dimension = 0; dimension < 2; ++dimension) // Intersect already gets quadrants 3-4 by proxy
         {
             float     angle         = (Mathf.PI / 2) * dimension;
             Vector3   begin         = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle));
             Vector3   end           = Vector3.down;
             Vector3[] intersections = PlanetariaIntersection.arc_path_intersections(arc, begin, end, 0);
             add_intersections(arc, intersections);
         }
     }
 }
コード例 #15
0
        public static optional <TextAsset> render(PlanetariaCollider collider, float width)
        {
            VectorGraphicsWriter.begin_canvas();
            VectorGraphicsWriter.begin_shape();

            BlockRendererIterator.prepare(collider);

            foreach (ArcIterator arc_iterator in BlockRendererIterator.arc_iterator())
            {
                ShapeRenderer.partition_arc(arc_iterator.arc, arc_iterator.begin, arc_iterator.end);
            }

            VectorGraphicsWriter.end_shape(Color.black, width);
            return(VectorGraphicsWriter.end_canvas());
        }
コード例 #16
0
        private static bool platform_collision(Arc arc, PlanetariaCollider collider, PlanetariaTransform transformation, PlanetariaRigidbody rigidbody, optional <Vector3> intersection_point)
        {
            Vector3 velocity = Bearing.attractor(rigidbody.get_previous_position(), rigidbody.get_position());

            if (intersection_point.exists)
            {
                float   arc_angle            = arc.position_to_angle(intersection_point.data);
                Vector3 normal               = arc.normal(arc_angle);
                bool    upward_facing_normal = Vector3.Dot(normal, rigidbody.get_acceleration()) <= 0;
                bool    moving_toward        = Vector3.Dot(normal, velocity) <= 0;

                if (upward_facing_normal && moving_toward)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #17
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);
                     }
                 }
             }
         }
     }
 }
コード例 #18
0
        private static void draw_planetaria_collider_gizmos(PlanetariaCollider self, GizmoType gizmo_type)
        {
            PlanetariaShapeEditor.draw_shape(self.shape, self.gameObject.internal_game_object.transform.rotation);

            /*
             * if (!self.is_field)
             * {
             *  PlanetariaArcColliderEditor.draw_arc(self.shape.block_list[arc_identifier],
             *          self.gameObject.internal_game_object.transform.rotation, mask);
             * }
             * else
             * {
             *  for (int index = 0; index < self.shape.field_list.Length; ++index)
             *  {
             *      if (!mask[index])
             *      {
             *          PlanetariaSphereColliderEditor.draw_sphere(self.shape.field_list[index],
             *          self.gameObject.internal_game_object.transform.rotation);
             *      }
             *  }
             * }
             */
        }
コード例 #19
0
 /// <summary>
 /// Named Constructor - creates the Planetaria equivalent of UnityEngine.RaycastHit
 /// </summary>
 /// <returns>The result of a point sweep / raycast in spherical 2D space.</returns>
 public static PlanetariaRaycastHit hit(Arc raycast_arc, PlanetariaCollider planetaria_collider, Arc geometry_arc, Vector3 intersection_point, float raycast_distance)
 {
     return(new PlanetariaRaycastHit(raycast_arc, planetaria_collider, geometry_arc, intersection_point, raycast_distance));
 }
コード例 #20
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);
        }
コード例 #21
0
 public void potential_field_collision(PlanetariaCollider field)
 {
     field_candidates.Add(field);
 }
コード例 #22
0
 public static void cache(PlanetariaCollider collider)
 {
     PlanetariaCache.collider_cache.Add(collider.get_sphere_collider(), collider);
 }
コード例 #23
0
 public static void uncache(PlanetariaCollider collider)
 {
     PlanetariaCache.collider_cache.Remove(collider.get_sphere_collider());
 }