// Preview rendering of this function is non-trivial, since ephemeral edges only work for the most recent edge.
        public static PlanetariaShape create_equilateral(Vector3 center, Vector3 vertex, int faces)
        {
            PlanetariaShape shape = PlanetariaShape.Create(new List <SerializedArc>(), true);

            create_equilateral(shape, center, vertex, faces);
            return(shape);
        }
示例#2
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());
        }
示例#3
0
        public static ArcBuilder arc_builder(Vector3 first_point, bool convex, bool allow_self_intersections)
        {
            GameObject game_object = new GameObject("ArcBuilder");
            ArcBuilder result      = game_object.AddComponent <ArcBuilder>();

            result.point                    = result.previous_point = result.original_point = first_point;
            result.shape                    = PlanetariaShape.Create();
            result.must_be_convex           = convex; // must be a "convex hull"
            result.allow_self_intersections = allow_self_intersections;
            return(result);
        }
示例#4
0
        private void OnGUI()
        {
            GUILayout.BeginHorizontal();
            radius = EditorGUILayout.Slider("Radius", radius, 0, Mathf.PI);
            GUILayout.EndHorizontal();

            if (GUILayout.Button("Generate"))
            {
                PlanetariaShape procedural_circle = PlanetariaShape.Create(radius);
                AssetDatabase.CreateAsset(procedural_circle,
                                          "Assets/Planetaria/Procedural/PlanetariaShape/planetaria_shape_circle_radius" + radius + ".asset");
                AssetDatabase.SaveAssets();
            }
        }