Ejemplo n.º 1
0
        public static Vector3[] valid_arc_intersections(Arc arc, Vector3[] intersections, // TODO: research and development
                                                        Quaternion orientation,
                                                        optional <float> max_angle = new optional <float>())
        {
            if (!max_angle.exists)
            {
                max_angle = arc.angle();
            }

            Vector3[] results = new Vector3[0];
            for (int intersection_index = 0; intersection_index < intersections.Length; ++intersection_index)
            {
                Vector3 intersection_point = intersections[intersection_index];
                if (orientation != Quaternion.identity)
                {
                    Quaternion arc_to_world = orientation;
                    Quaternion world_to_arc = Quaternion.Inverse(arc_to_world);
                    intersection_point = world_to_arc * intersection_point;
                }

                Vector3 arc_left          = arc.position(-max_angle.data / 2);
                Vector3 arc_center        = arc.position(0);
                Vector3 arc_right         = arc.position(+max_angle.data / 2);
                Vector3 boundary_midpoint = (arc_left + arc_right) / 2;

                Plane arc_validator = new Plane(arc_center, boundary_midpoint);
                if (arc_validator.GetSide(intersection_point))
                {
                    Array.Resize(ref results, results.Length + 1);
                    results[results.Length - 1] = intersections[intersection_index];
                }
            }

            return(results);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Mutator (Operating System level) - Writes (or overwrites!) the file at location "file" with the string "text_contents".
 /// </summary>
 /// <param name="file">The relative file path starting in the Unity directory (e.g. "Assets/important_file.txt"). Note: will be overwritten.</param>
 /// <param name="text_contents">The contents that will be placed in the file (overwrites file).</param>
 /// <param name="add_global_unique_identifier">Adds "_[0-9a-f]{32}" before file extension (last dot) in "file".</param>
 public static optional <TextAsset> write_file(string file, string text_contents, bool add_global_unique_identifier)
 {
     using (StreamWriter writer = new StreamWriter(file, false))
     {
         string suffix = "";
         writer.Write(text_contents);
         if (add_global_unique_identifier)
         {
             writer.Dispose();
             UnityEditor.AssetDatabase.Refresh();
             string global_unique_identifier = text_contents.GetHashCode().ToString("X");
             Debug.Log("Creating " + global_unique_identifier);
             suffix = "_" + global_unique_identifier;
             optional <string> name = Miscellaneous.inner_text(file, "/", ".");
             if (name.exists)
             {
                 UnityEditor.AssetDatabase.RenameAsset(file, name.data + suffix); // FIXME: INVESTIGATE: why does optional<string> + string work? (for safety reasons, it shouldn't)
             }
             else
             {
                 Debug.Log("Critical Error");
             }
         }
         UnityEditor.AssetDatabase.Refresh();
         optional <string> resource = Miscellaneous.inner_text(file, "/Resources/", ".");
         if (resource.exists)
         {
             resource = resource.data + suffix;
             return(Resources.Load <TextAsset>(resource.data));
         }
         return(new optional <TextAsset>());
     }
 }
Ejemplo n.º 3
0
 private void initialize_pole_light(optional <float> angle = new optional <float>())
 {
     internal_light.type      = LightType.Spot;
     internal_light.spotAngle = (range * 2) * Mathf.Rad2Deg;
     internal_cuculoris       = create_pole_texture(internal_light.spotAngle);
     cuculoris.apply_to(ref internal_cuculoris, angle.exists ? angle.data : 2 * Mathf.PI);
     internal_light.cookie       = internal_cuculoris;
     internal_transform.position = Vector3.zero;
     internal_transform.rotation = Quaternion.identity;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Mutator - Gets the attached PlanetariaComponent if it exists; otherwise it adds and returns it.
        /// </summary>
        /// <typeparam name="Subtype">The type of the PlanetariaComponent to be fetched.</typeparam>
        /// <returns>The found or newly added PlanetariaComponent.</returns>
        public Subtype GetOrAddComponent <Subtype>() where Subtype : PlanetariaComponent
        {
            optional <Subtype> result = GetComponent <Subtype>();

            if (!result.exists)
            {
                result = AddComponent <Subtype>();
            }
            return(result.data);
        }
Ejemplo n.º 5
0
 private static LevelCreatorEditor.CreateShape escape()
 {
     // Escape: close the shape so that it meets with the original point (using original point for slope)
     if (temporary_arc.exists)
     {
         temporary_arc.data.close_shape();
         temporary_arc = new optional <ArcBuilder>();
     }
     return(LevelCreatorEditor.draw_initialize);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Mutator - Gets the attached Component if it exists; otherwise it adds and returns it.
        /// </summary>
        /// <typeparam name="Subtype">The type of the Component to be fetched.</typeparam>
        /// <param name="self">Calling object (explicit)</param>
        /// <returns>The found or newly added Component.</returns>
        public static Subtype GetOrAddComponent <Subtype>(Component self) where Subtype : Component
        {
            optional <Subtype> result = self.GetComponent <Subtype>();

            if (!result.exists)
            {
                result = self.gameObject.AddComponent <Subtype>();
            }
            return(result.data);
        }
Ejemplo n.º 7
0
        public void move_position(float delta_length, optional <float> extrusion = new optional <float>()) // CONSIDER: combine move_position/set_position?
        {
            if (extrusion.exists)
            {
                last_extrusion = extrusion.data;
                initialize();
            }
            float delta_angle = delta_length * (arc_angle / arc_length);

            set_position(angular_position + delta_angle);
        }
Ejemplo n.º 8
0
        public static optional <Texture2D> fetch_image(string image_file)
        {
            optional <Texture2D> texture = new optional <Texture2D>();

            if (File.Exists(image_file))
            {
                byte[] raw_file_binary = File.ReadAllBytes(image_file);
                texture = new Texture2D(0, 0);
                texture.data.LoadImage(raw_file_binary);
            }
            return(texture);
        }
Ejemplo n.º 9
0
 private void initialize_camera(optional <Camera> internal_camera, Rect screen, int draw_order)
 {
     if (internal_camera.exists)
     {
         Camera camera = internal_camera.data;
         camera.rect  = screen;
         camera.depth = draw_order;
         camera.useOcclusionCulling = false;
         camera.nearClipPlane       = near_clip_plane;
         camera.farClipPlane        = far_clip_plane;
         camera.stereoSeparation    = 0;
         camera.stereoConvergence   = 0.01f;
     }
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Inspector - Draw an arc with lines only (basic)
        /// </summary>
        /// <param name="arc">The arc that will be rendered.</param>
        /// <param name="distance">The distance of the arc, negative or positive (overrides actual distance).</param>
        public static void draw_simple_arc(Arc arc, optional <float> distance = new optional <float>())
        {
            float start_angle = -arc.half_angle;

            float angle = distance.exists ? distance.data : arc.angle();

            int segments = 50;

            for (int segment = 1; segment <= segments; ++segment)
            {
                float end_angle = -arc.half_angle + segment / (float)segments * angle;
                Debug.DrawLine(arc.position(start_angle), arc.position(end_angle), Color.yellow, 5f);
                start_angle = end_angle;
            }
        }
Ejemplo n.º 11
0
        public override bool Equals(System.Object other_object) // FIXME:
        {
            bool equal_type = other_object is optional <Type>;

            if (!equal_type)
            {
                return(false);
            }
            optional <Type> other             = (optional <Type>)other_object;
            bool            inequal_existance = (this.exists != other.exists);
            bool            inequal_value     = (this.exists && other.exists && !this.data.Equals(other.data));
            bool            inequal           = inequal_existance || inequal_value;

            return(!inequal);
        }
Ejemplo n.º 12
0
        private void OnTriggerStay(Collider collider)
        {
            optional <SphereCollider> sphere_collider = collider as SphereCollider;

            if (!sphere_collider.exists)
            {
                Debug.LogError("This should never happen");
                return;
            }
            optional <PlanetariaCollider> other_collider = PlanetariaCache.collider_fetch(sphere_collider.data);

            if (!other_collider.exists)
            {
                Debug.LogError("This should never happen");
                return;
            }

            Quaternion shift_from_self_to_other = other_collider.data.internal_transform.rotation;

            if (this.internal_transform.rotation != Quaternion.identity) // Only shift orientation when necessary
            {
                // TODO: verify the order of operations is correct (and logic itself)
                shift_from_self_to_other = Quaternion.Inverse(this.internal_transform.rotation) * shift_from_self_to_other;
            }

            if (other_collider.data.is_field) // field collision
            {
                if (this.shape.field_collision(other_collider.data.shape, shift_from_self_to_other))
                {
                    observer.potential_field_collision(other_collider.data); // TODO: augment field (like Unity triggers) works on both the sender and receiver.
                }
            }
            else // block collision
            {
                foreach (Arc intersection in this.shape.block_collision(other_collider.data.shape, shift_from_self_to_other))
                {
                    Vector3 position = planetaria_transform.position;
                    if (other_collider.data.gameObject.internal_game_object.transform.rotation != Quaternion.identity) // Only shift orientation when necessary
                    {
                        position = Quaternion.Inverse(other_collider.data.gameObject.internal_game_object.transform.rotation) * position;
                    }
                    if (intersection.contains(position, planetaria_transform.scale / 2))
                    {
                        observer.potential_block_collision(intersection, other_collider.data); // block collisions are handled in OnCollisionStay(): notification stage
                    }
                }
            }
        }
        public static optional <SphericalCirclePlanetarium> load(string file_name, float radius)
        {
            optional <Material> material = WorldPlanetarium.load_material(file_name);

            if (!material.exists)
            {
                return(new optional <SphericalCirclePlanetarium>());
            }
            SphericalCirclePlanetarium result = new SphericalCirclePlanetarium();

            result.material = material.data;
            result.texture  = (Texture2D)WorldPlanetarium.load_texture(file_name);
            result.material.SetTexture("_MainTex", result.texture);
            result.radius_variable = radius;
            return(result);
        }
Ejemplo n.º 14
0
        public static optional <OctahedronPlanetarium> load(string file_name)
        {
            optional <Material> material = WorldPlanetarium.load_material(file_name);

            if (!material.exists)
            {
                return(new optional <OctahedronPlanetarium>());
            }
            Texture2D             texture = (Texture2D)WorldPlanetarium.load_texture(file_name);
            OctahedronPlanetarium result  = new OctahedronPlanetarium(texture.width);

            result.material = material.data;
            result.texture  = texture;
            result.material.SetTexture("_MainTex", result.texture);
            return(result);
        }
Ejemplo n.º 15
0
        public bool is_self_intersecting()
        {
            List <Arc> edges = generate_edges();

            for (int left = 0; left < edges.Count; ++left)
            {
                for (int right = left + 1; right < edges.Count; ++right)
                {
                    optional <Vector3> intersection = PlanetariaIntersection.arc_arc_intersection(edges[left], edges[right], 0);
                    if (intersection.exists)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 16
0
        public static optional <CubePlanetarium> load(string file_name)
        {
            optional <Material> material = WorldPlanetarium.load_material(file_name);

            if (!material.exists)
            {
                return(new optional <CubePlanetarium>());
            }
            int             size   = material.data.GetTexture(directions[0]).width;
            CubePlanetarium result = new CubePlanetarium(size);

            result.material = material.data;
            for (int face = 0; face < directions.Length; ++face)
            {
                Texture2D texture = (Texture2D)material.data.GetTexture(directions[face]);
                result.textures[face] = texture;
            }
            return(result);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Mutator - MouseDown finalizes equilateral shape.
        /// </summary>
        /// <returns>The next mode for the state machine.</returns>
        public static LevelCreatorEditor.CreateShape draw_equilateral(bool force_quit = false)
        {
            if (force_quit)
            {
                return(escape());
            }

            builder.data.set_edge(LevelCreatorEditor.get_mouse_position());

            // MouseUp: create first vertex of equilateral shape
            if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
            {
                builder.data.close_shape();
                builder = new optional <EquilateralBuilder>();
                return(draw_center);
            }

            return(draw_equilateral);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Mutator - Gets the designated object from the root of the scene if it exists; otherwise it creates and returns it.
        /// </summary>
        /// <param name="name">The name of the object (without double leading underscores i.e. "__").</param>
        /// <param name="hidden_internal">Whether the GameObject should be hidden unless debugging.</param>
        /// <returns>The found or newly added object from the root of the scene.</returns>
        public static GameObject GetOrAddObject(string name, bool hidden_internal = true)
        {
            if (hidden_internal)
            {
                name = "__" + name;
            }
            optional <GameObject> game_object = GameObject.Find("/" + name);

            if (!game_object.exists)
            {
                game_object = new GameObject(name);
            }
#if UNITY_EDITOR
            if (hidden_internal && !EditorGlobal.self.show_inspector)
            {
                game_object.data.hideFlags = (HideFlags.HideInHierarchy | HideFlags.HideInInspector);
            }
#endif
            return(game_object.data);
        }
Ejemplo n.º 19
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);
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 20
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>();
            }
        }
Ejemplo n.º 21
0
        private void initialize()
        {
            arc_angle = arc_visitor.arc.angle();

            float floor_length   = arc_visitor.arc.length();           // edge case
            float ceiling_length = arc_visitor.arc.length(2 * offset); // corner case

            arc_length = Mathf.Max(floor_length, ceiling_length);      // use longer distance to make movement feel consistent

            left_angle_boundary = -arc_angle / 2;
            if (concave(arc_visitor[-1], offset)) // set left boundary
            {
                optional <Vector3> intersection = PlanetariaIntersection.arc_arc_intersection(arc_visitor[0], arc_visitor[-2], offset);
                left_angle_boundary = arc_visitor.arc.position_to_angle(intersection.data);
            }

            right_angle_boundary = +arc_angle / 2;
            if (concave(arc_visitor[+1], offset)) // set right boundary
            {
                optional <Vector3> intersection = PlanetariaIntersection.arc_arc_intersection(arc_visitor[0], arc_visitor[+2], offset);
                right_angle_boundary = arc_visitor.arc.position_to_angle(intersection.data);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Mutator - Gets the attached child by its name if it exists; otherwise it adds and returns it.
        /// </summary>
        /// <param name="self">Calling object - extension method (implicit).</param>
        /// <param name="name">The name of the object (without double leading underscores i.e. "__").</param>
        /// <param name="hidden_internal">Whether the GameObject should be hidden unless debugging.</param>
        /// <returns>The found or newly added child with given name.</returns>
        public static GameObject GetOrAddChild(this Component self, string name, bool hidden_internal = true) // TODO: should this return PlanetariaGameObject; this is an inadvertently exposed API, how should I fix this? Likely by making this a non-extension
        {
            if (hidden_internal)
            {
                name = "__" + name;
            }
            optional <Transform> child = self.transform.Find(name);

            if (!child.exists)
            {
                GameObject child_object = new GameObject(name);
                child_object.transform.parent        = self.transform;
                child_object.transform.localPosition = Vector3.zero; // Ensure all children are on the same planetarium as their parent
                child = child_object.transform;
                child_object.layer = self.gameObject.layer;
            }
#if UNITY_EDITOR
            if (hidden_internal && EditorGlobal.self.show_inspector)
            {
                child.data.hideFlags = (HideFlags.HideInHierarchy | HideFlags.HideInInspector);
            }
#endif
            return(child.data.gameObject);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Inspector/Constructor - Creates a copy of the shape then sets closed=true
        /// </summary>
        /// <returns>A closed shape mirroring all properties of original but with closed=true.</returns>
        public void close(optional <Vector3> slope = new optional <Vector3>(), AppendMode permanence = AppendMode.OverwriteWithPermanent)
        {
            if (permanence == AppendMode.OverwriteWithEphemeral ||
                permanence == AppendMode.OverwriteWithPermanent)
            {
                serialized_arc_list.RemoveRange(serialized_arc_list.Count - ephemeral_arcs, ephemeral_arcs);
                ephemeral_arcs = 0;
            }

            // Add last edge! (if not already closed and Dot of last/first point is != 1)
            if (!closed())
            {
                Arc first_arc = serialized_arc_list[0];
                Arc last_arc  = serialized_arc_list[serialized_arc_list.Count - 1];
                if (!slope.exists)
                {
                    slope = first_arc.begin();
                }
                append(ArcFactory.curve(last_arc.end(), slope.data, first_arc.begin()), permanence);
            }
            initialize();

            // TODO: if field, make this a convex_hull() // TODO: add convex property
        }
Ejemplo n.º 24
0
 public static Vector3 snap(Vector3 position, bool v_pressed)
 {
     if (Event.current.control && Event.current.shift) // Edge snap on Control + Shift + click
     {
         optional <Vector3> edge_snap = closest_heuristic(ArcUtility.snap_to_edge, position);
         if (edge_snap.exists)
         {
             return(edge_snap.data);
         }
     }
     else if (EditorGlobal.self.v_pressed) // Vertex snap on V + click
     {
         optional <Vector3> vertex_snap = closest_heuristic(ArcUtility.snap_to_vertex, position);
         if (vertex_snap.exists)
         {
             return(vertex_snap.data);
         }
     }
     else if (Event.current.shift) // Grid snap on Shift + click
     {
         return(grid_snap(position));
     }
     return(position); // return the input position (if all else fails).
 }
Ejemplo n.º 25
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);
        }
Ejemplo n.º 26
0
        private void OnGUI()
        {
            if (GUILayout.Button("Image(s) to convert"))
            {
                from_file_name = EditorUtility.OpenFilePanel("PNG to convert", "Assets/Planetaria/ExampleProjects/DébrisNoirs/Art/Textures", "mat"); // TODO: multiple types
                from_file_name = from_file_name.Substring(0, from_file_name.Length - 4);
                // this is an editor tool, so the following is fine:
                int clip_index = from_file_name.IndexOf("Assets/");
                from_file_name = from_file_name.Substring(clip_index);
            }
            if (GUILayout.Button("Generated PNG(s) filename"))
            {
                to_file_name = EditorUtility.SaveFilePanel("Generated PNG filename", "Assets/Planetaria/ExampleProjects/DébrisNoirs/Art/Textures", "output_file", "png"); // TODO: multiple types and use output in conversion // FIXME: HACK: trying to make deadlines
                to_file_name = to_file_name.Substring(0, to_file_name.Length - 4);
                // this is an editor tool, so the following is fine:
                int clip_index = to_file_name.IndexOf("Assets/");
                to_file_name = to_file_name.Substring(clip_index);
            }

            GUILayout.BeginHorizontal();
            from_shape = (Shape)EditorGUILayout.EnumPopup("Current shape format", from_shape);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            to_shape = (Shape)EditorGUILayout.EnumPopup("Target shape format", to_shape);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            resolution = EditorGUILayout.IntField("Pixel resolution", resolution);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            sample_rate = EditorGUILayout.IntField("Sample rate", sample_rate);
            GUILayout.EndHorizontal();

            switch (from_shape)
            {
            case Shape.SphericalRectangle:
                GUILayout.BeginHorizontal();
                canvas = EditorGUILayout.RectField("Spherical Rectangle", canvas);
                GUILayout.EndHorizontal();
                break;

            case Shape.SphericalCircle:
                GUILayout.BeginHorizontal();
                radius = EditorGUILayout.FloatField("Spherical Circle radius", radius);
                GUILayout.EndHorizontal();
                break;
            }

            if (GUILayout.Button("Convert"))
            {
                WorldPlanetarium from;
                WorldPlanetarium to;
                switch (from_shape)
                {
                case Shape.Cube:
                    optional <CubePlanetarium> cubemap = CubePlanetarium.load(from_file_name);
                    Debug.Assert(cubemap.exists);
                    from = cubemap.data;
                    break;

                case Shape.Octahedron:
                    optional <OctahedronPlanetarium> octahedron = OctahedronPlanetarium.load(from_file_name);
                    Debug.Assert(octahedron.exists);
                    from = octahedron.data;
                    break;

                case Shape.SphericalRectangle:
                    optional <SphericalRectanglePlanetarium> rectangle = SphericalRectanglePlanetarium.load(from_file_name, canvas);
                    Debug.Assert(rectangle.exists);
                    from = rectangle.data;
                    break;

                case Shape.SphericalCircle:
                default:     // FIXME:
                    optional <SphericalCirclePlanetarium> circle = SphericalCirclePlanetarium.load(from_file_name, radius);
                    Debug.Assert(circle.exists);
                    from = circle.data;
                    break;
                }
                switch (to_shape)
                {
                case Shape.Cube:
                    to = new CubePlanetarium(resolution);
                    to.convert(from);
                    to.save(to_file_name);
                    break;

                case Shape.Octahedron:
                    to = new OctahedronPlanetarium(resolution);
                    to.convert(from);
                    to.save(to_file_name);
                    break;
                }
            }
        }
Ejemplo n.º 27
0
 private static LevelCreatorEditor.CreateShape escape()
 {
     builder.data.close_shape();
     builder = new optional <EquilateralBuilder>();
     return(LevelCreatorEditor.draw_initialize);
 }
Ejemplo n.º 28
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);
        }
Ejemplo n.º 29
0
 protected override void OnDestroy()
 {
     cleanup();
     shutter = new optional <PlanetariaCameraShutter>(); // deregisters from blink_event
 }