private double ProjectMouse()
        {
            if (spline.pointCount == 0)
            {
                return(0.0);
            }
            float  closestDistance = (Event.current.mousePosition - HandleUtility.WorldToGUIPoint(spline.GetPointPosition(0))).sqrMagnitude;
            double closestPercent  = 0.0;
            double add             = spline.moveStep;

            if (spline.type == Spline.Type.Linear)
            {
                add /= 2.0;
            }
            int count = 0;

            for (double i = add; i < 1.0; i += add)
            {
                SplineSample result = spline.Evaluate(i);
                Vector2      point  = HandleUtility.WorldToGUIPoint(result.position);
                float        dist   = (point - Event.current.mousePosition).sqrMagnitude;
                if (dist < closestDistance)
                {
                    closestDistance = dist;
                    closestPercent  = i;
                }
                count++;
            }
            return(closestPercent);
        }
        public void Project(Vector3 point, SplineSample result, bool bypassCache = false)
        {
            if (_segments.Count == 0)
            {
                return;
            }
            int   closestPath = 0;
            float closestDist = Mathf.Infinity;

            for (int i = 0; i < _segments.Count; i++)
            {
                if (!_segments[i].extruded && _segments[i].type == LevelSegment.Type.Extruded)
                {
                    continue;
                }
                _segments[i].Project(point, resultAlloc, 0.0, 1.0, bypassCache ? SplinePath.EvaluateMode.Accurate : SplinePath.EvaluateMode.Cached);
                float dist = (resultAlloc.position - point).sqrMagnitude;
                if (dist < closestDist)
                {
                    closestDist = dist;
                    closestPath = i;
                    result.CopyFrom(resultAlloc);
                }
            }
            result.percent = LocalToGlobalPercent(result.percent, closestPath);
        }
Exemple #3
0
        /// <summary>
        /// Evaluate the generated path of the segment. This is the path after the segment is extruded.
        /// </summary>
        /// <param name="percent">Percent along the segment path [0-1]</param>
        /// <param name="result">The SplineSample object to write the result into</param>
        /// <param name="mode">If set to EvaluateMode.Accurate, the actual spline will be evaluated instead of the cached samples.</param>
        public virtual void Evaluate(double percent, SplineSample result, EvaluateMode mode = EvaluateMode.Cached)
        {
            if (mode == EvaluateMode.Accurate)
            {
                spline.Evaluate(result, percent);
                return;
            }
            if (samples.Length == 0)
            {
                return;
            }
            percent = DMath.Clamp01(percent);
            int    index         = DMath.FloorInt(percent * (samples.Length - 1));
            double percentExcess = (samples.Length - 1) * percent - index;

            if (result == null)
            {
                result = new SplineSample();
            }
            result.CopyFrom(samples[index]);
            if (percentExcess > 0.0 && index < samples.Length - 1)
            {
                result.Lerp(samples[index + 1], percentExcess);
            }
        }
Exemple #4
0
        void Evaluate(double percent, SplineSample result)
        {
            if (samples.Length == 0)
            {
                return;
            }
            percent = DMath.Clamp01(percent);
            int    index         = DMath.FloorInt(percent * (samples.Length - 1));
            double percentExcess = (samples.Length - 1) * percent - index;

            if (result == null)
            {
                result = new SplineSample();
            }
            result.CopyFrom(samples[index]);
            if (percentExcess > 0.0 && index < samples.Length - 1)
            {
                result.Lerp(samples[index + 1], percentExcess);
            }
            if (useRelativeCoordinates)
            {
                result.position = trsMatrix.MultiplyPoint3x4(result.position);
                result.forward  = trsMatrix.MultiplyVector(result.forward);
                result.up       = trsMatrix.MultiplyVector(result.up);
            }
        }
Exemple #5
0
        protected override void OnPostGeneration(SplinePoint[] points)
        {
            base.OnPostGeneration(points);
            double       range  = 1.0 / segmentCount;
            double       from   = range * currentSegmentIndex;
            double       to     = range * (currentSegmentIndex + 1);
            SplineSample result = new SplineSample();

            for (int i = 0; i < points.Length; i++)
            {
                double percent = DMath.Lerp(from, to, (double)i / (points.Length - 1));
                Evaluate(percent, result);
                points[i].position = result.position;
                points[i].tangent2 = result.forward;
                points[i].normal   = result.up;
                points[i].size     = result.size;
                points[i].color    = result.color;
            }
            for (int i = 0; i < points.Length; i++)
            {
                float pointDistance = 0f;
                if (i == 0)
                {
                    pointDistance = Vector3.Distance(points[i].position, points[i + 1].position);
                }
                else
                {
                    pointDistance = Vector3.Distance(points[i].position, points[i - 1].position);
                }
                points[i].tangent2 = points[i].position + points[i].tangent2 * pointDistance / 3f;
                points[i].tangent  = points[i].position + (points[i].position - points[i].tangent2);
            }
            currentSegmentIndex++;
        }
Exemple #6
0
        public virtual void StartFollow()
        {
            if (LevelGenerator.instance == null || !LevelGenerator.instance.ready || LevelGenerator.instance.segments.Count == 0)
            {
                Debug.LogError(name + " Runner attempting to start following but the Level Generator isn't ready.");
                return;
            }
            int    segmentIndex = 0;
            double localPercent = 0.0;

            switch (startMode)
            {
            case StartMode.Percent:
                localPercent = LevelGenerator.instance.GlobalToLocalPercent(startPercent, out segmentIndex);
                break;

            case StartMode.Distance:
                localPercent = LevelGenerator.instance.GlobalToLocalPercent(LevelGenerator.instance.Travel(0.0, startDistance, Spline.Direction.Forward), out segmentIndex);
                Debug.DrawRay(LevelGenerator.instance.EvaluatePosition(LevelGenerator.instance.Travel(0.0, startDistance, Spline.Direction.Forward)), Vector3.up * 10f, Color.red, 5f);
                break;

            case StartMode.Project:
                SplineSample result = new SplineSample();
                LevelGenerator.instance.Project(transform.position, result);
                localPercent = LevelGenerator.instance.GlobalToLocalPercent(result.percent, out segmentIndex);
                break;
            }
            Init(LevelGenerator.instance.segments[segmentIndex], localPercent);
            follow = true;
        }
        void AddConnection(SplineComputer computer, int pointIndex)
        {
            Node node = (Node)target;

            Node.Connection[] connections = node.GetConnections();
            if (EditorUtility.DisplayDialog("Link point?", "Add point " + (pointIndex + 1) + " to connections?", "Yes", "No"))
            {
                Undo.RecordObject(addComp, "Add connection");
                Undo.RecordObject(node, "Add Connection");
                if (connections.Length == 0)
                {
                    switch (EditorUtility.DisplayDialogComplex("Align node to point?", "This is the first connection for the node, would you like to snap or align the node's Transform the spline point.", "No", "Snap", "Snap and Align"))
                    {
                    case 1: SplinePoint point = addComp.GetPoint(pointIndex);
                        node.transform.position = point.position;
                        break;

                    case 2:
                        SplineSample result = addComp.Evaluate(pointIndex);
                        node.transform.position = result.position;
                        node.transform.rotation = result.rotation;
                        break;
                    }
                }
                computer.ConnectNode(node, pointIndex);
                addComp  = null;
                addPoint = 0;
                SceneView.RepaintAll();
                Repaint();
            }
        }
Exemple #8
0
        public static double ScreenPointToSplinePercent(SplineComputer computer, Vector2 screenPoint)
        {
            SplinePoint[] points          = computer.GetPoints();
            float         closestDistance = (screenPoint - HandleUtility.WorldToGUIPoint(points[0].position)).sqrMagnitude;
            double        closestPercent  = 0.0;
            double        add             = computer.moveStep;

            if (computer.type == Spline.Type.Linear)
            {
                add /= 2f;
            }
            int count = 0;

            for (double i = add; i < 1.0; i += add)
            {
                SplineSample result = computer.Evaluate(i);
                Vector2      point  = HandleUtility.WorldToGUIPoint(result.position);
                float        dist   = (point - screenPoint).sqrMagnitude;
                if (dist < closestDistance)
                {
                    closestDistance = dist;
                    closestPercent  = i;
                }
                count++;
            }
            return(closestPercent);
        }
Exemple #9
0
        public void DistributeEvenly()
        {
            if (selectedPoints.Count < 3)
            {
                return;
            }
            RecordUndo("Distribute Evenly");
            int min = points.Length - 1, max = 0;

            for (int i = 0; i < selectedPoints.Count; i++)
            {
                if (selectedPoints[i] < min)
                {
                    min = selectedPoints[i];
                }
                if (selectedPoints[i] > max)
                {
                    max = selectedPoints[i];
                }
            }
            double       minPercent = (double)min / (points.Length - 1);
            double       maxPercent = (double)max / (points.Length - 1);
            float        length     = calculateLength(minPercent, maxPercent);
            float        step       = length / (max - min);
            SplineSample evalResult = new SplineSample();

            evaluate(minPercent, evalResult);
            for (int i = min + 1; i < max; i++)
            {
                double percent = travel(evalResult.percent, step, Spline.Direction.Forward);
                evaluate(percent, evalResult);
                points[i].SetPosition(evalResult.position);
            }
            ResetCurrentModule();
        }
Exemple #10
0
        protected void ApplyMotion(SplineSample SplineSample, MotionModule module)
        {
            module.SplineSample = SplineSample;
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                if (targetTransform == null)
                {
                    RefreshTargets();
                }
                if (targetTransform == null)
                {
                    return;
                }
                module.ApplyTransform(targetTransform);
                return;
            }
#endif
            switch (physicsMode)
            {
            case PhysicsMode.Transform:
                if (targetTransform == null)
                {
                    RefreshTargets();
                }
                if (targetTransform == null)
                {
                    return;
                }
                module.ApplyTransform(targetTransform);
                break;

            case PhysicsMode.Rigidbody:
                if (targetRigidbody == null)
                {
                    RefreshTargets();
                    if (targetRigidbody == null)
                    {
                        throw new MissingComponentException("There is no Rigidbody attached to " + name + " but the Physics mode is set to use one.");
                    }
                }
                module.ApplyRigidbody(targetRigidbody);
                break;

            case PhysicsMode.Rigidbody2D:
                if (targetRigidbody2D == null)
                {
                    RefreshTargets();
                    if (targetRigidbody2D == null)
                    {
                        throw new MissingComponentException("There is no Rigidbody2D attached to " + name + " but the Physics mode is set to use one.");
                    }
                }
                module.ApplyRigidbody2D(targetRigidbody2D);
                break;
            }
        }
Exemple #11
0
        public static void DrawSpline(Spline spline, Color color, double from = 0.0, double to = 1.0, bool drawThickness = false, bool thicknessAutoRotate = false)
        {
            double add = spline.moveStep;
            if (add < 0.0025) add = 0.0025;
            Color prevColor = Handles.color;
            Handles.color = color;
            int iterations = spline.iterations;
            if (drawThickness)
            {
                Transform editorCamera = SceneView.currentDrawingSceneView.camera.transform;
                if (positions.Length != iterations * 6) positions = new Vector3[iterations * 6];
                SplineSample prevResult = spline.Evaluate(from);
                Vector3 prevNormal = prevResult.up;
                if (thicknessAutoRotate) prevNormal = (editorCamera.position - prevResult.position).normalized;
                Vector3 prevRight = Vector3.Cross(prevResult.forward, prevNormal).normalized * prevResult.size * 0.5f;
                int pointIndex = 0;
                for (int i = 1; i < iterations; i++)
                {
                    double p = DMath.Lerp(from, to, (double)i / (iterations - 1));
                    SplineSample newResult = spline.Evaluate(p);
                    Vector3 newNormal = newResult.up;
                    if (thicknessAutoRotate) newNormal = (editorCamera.position - newResult.position).normalized;
                    Vector3 newRight = Vector3.Cross(newResult.forward, newNormal).normalized * newResult.size * 0.5f;

                    positions[pointIndex] = prevResult.position + prevRight;
                    positions[pointIndex + iterations * 2] = prevResult.position - prevRight;
                    positions[pointIndex + iterations * 4] = newResult.position - newRight;
                    pointIndex++;
                    positions[pointIndex] = newResult.position + newRight;
                    positions[pointIndex + iterations * 2] = newResult.position - newRight;
                    positions[pointIndex + iterations * 4] = newResult.position + newRight;
                    pointIndex++;
                    prevResult = newResult;
                    prevRight = newRight;
                    prevNormal = newNormal;
                }
            }
            else
            {
                if (positions.Length != iterations * 2) positions = new Vector3[iterations * 2];
                Vector3 prevPoint = spline.EvaluatePosition(from);
                int pointIndex = 0;
                for (int i = 1; i < iterations; i++)
                {
                    double p = DMath.Lerp(from, to, (double)i / (iterations - 1));
                    positions[pointIndex] = prevPoint;
                    pointIndex++;
                    positions[pointIndex] = spline.EvaluatePosition(p);
                    pointIndex++;
                    prevPoint = positions[pointIndex - 1];
                }
            }
            Handles.DrawLines(positions);
            Handles.color = prevColor;
        }
Exemple #12
0
 protected virtual void Evaluate(double percent, SplineSample result)
 {
     if (_segment.type == LevelSegment.Type.Custom && _segment.customMainPath >= 0 && _segment.customPaths.Length > 0)
     {
         _segment.customPaths[_segment.customMainPath].Evaluate(percent, result);
     }
     else
     {
         _segment.Evaluate(percent, result);
     }
 }
Exemple #13
0
        protected override void OnFollow(SplineSample followResult)
        {
            laneBlend = Mathf.MoveTowards(laneBlend, 1f, Time.deltaTime * laneSwitchSpeed);
            laneValue = Mathf.Lerp(lastLane, _lane, laneSwitchSpeedCurve.Evaluate(laneBlend));
            if (useCustomPaths) //Custom lane following
            {
                if (customPathResults.Length < _segment.customPaths.Length)
                {
                    SplineSample[] newResults = new SplineSample[_segment.customPaths.Length];
                    customPathResults.CopyTo(newResults, 0);
                    customPathResults = newResults;
                    for (int i = 0; i < customPathResults.Length; i++)
                    {
                        if (customPathResults[i] == null)
                        {
                            customPathResults[i] = new SplineSample();
                        }
                    }
                }
                for (int i = 0; i < _segment.customPaths.Length; i++)
                {
                    _segment.customPaths[i].Evaluate(_result.percent, customPathResults[i]);
                }

                if (_segment.customPaths.Length > 1) //Interpolate between custom paths
                {
                    if (lane > _segment.customPaths.Length)
                    {
                        lane = _segment.customPaths.Length;
                    }
                    if (laneValue > _segment.customPaths.Length)
                    {
                        laneValue = _segment.customPaths.Length;
                    }
                    if (lastLane > _segment.customPaths.Length)
                    {
                        lastLane = _segment.customPaths.Length;
                    }
                    _result.CopyFrom(customPathResults[lastLane - 1]);
                    _result.Lerp(customPathResults[lane - 1], Mathf.Abs(laneValue - lastLane));
                    ApplyMotion(_result, motion);
                    return;
                }
                else if (_segment.customPaths.Length > 0)
                {
                    _result.CopyFrom(customPathResults[0]);                                        //Use custom path but apply offset
                }
            }

            laneModule.CopyFrom(motion); //Copy the motion from the existing module
            //Apply lane offset:
            laneModule.offset += Vector2.Lerp(-laneVector * width * 0.5f, laneVector * width * 0.5f, (laneValue - 1f) / (laneCount - 1));
            ApplyMotion(_result, laneModule);
        }
Exemple #14
0
 protected override void Evaluate(double percent, SplineSample result)
 {
     if (usePreviousLane)
     {
         _segment.customPaths[_lastLane - 1].Evaluate(percent, result);
     }
     else
     {
         _segment.customPaths[_lane - 1].Evaluate(percent, result);
     }
 }
Exemple #15
0
        public void Evaluate(double percent, SplineSample result)
        {
            if (_segments.Count == 0)
            {
                return;
            }
            int    pathIndex;
            double localPercent = GlobalToLocalPercent(percent, out pathIndex);

            _segments[pathIndex].Evaluate(localPercent, result);
            result.percent = percent;
        }
Exemple #16
0
 void SetTRS()
 {
     if (LevelGenerator.instance.segments.Count > 0)
     {
         SplineSample result = new SplineSample();
         LevelGenerator.instance.Evaluate(1.0, result);
         trsMatrix.SetTRS(transform.InverseTransformPoint(result.position), Quaternion.Inverse(transform.rotation) * result.rotation, Vector3.one);
     }
     else
     {
         trsMatrix.SetTRS(Vector3.zero, Quaternion.identity, Vector3.one);
     }
 }
        public override void Continue(LevelSegment segment)
        {
            base.Continue(segment);
            SplineSample sample = new SplineSample();

            segment.Evaluate(1.0, sample);
            SplinePoint lastPoint = segment.path.spline.points[segment.path.spline.points.Length - 1];

            lastPointHL.position = transform.InverseTransformPoint(lastPoint.position);
            lastPointHL.rotation = (Quaternion.Inverse(transform.rotation) * sample.rotation).eulerAngles;
            lastPointHL.size     = sample.size;
            lastPointHL.color    = sample.color;
        }
Exemple #18
0
 protected override void OnFollow(SplineSample followResult)
 {
     if (laneLerp != 1f)
     {
         usePreviousLane = true;
         Traverse(previousLaneResult);
         usePreviousLane = false;
         laneLerp        = Mathf.MoveTowards(laneLerp, 1f, Time.deltaTime * laneSwitchSpeed);
         SplineSample.Lerp(previousLaneResult, _result, laneSwitchSpeedCurve.Evaluate(laneLerp), newLaneResult);
         followResult = newLaneResult;
     }
     base.OnFollow(followResult);
 }
        void SetNormals(int mode)
        {
            mode--;
            Vector3 avg = Vector3.zero;

            for (int i = 0; i < selectedPoints.Count; i++)
            {
                avg += points[selectedPoints[i]].position;
            }
            if (selectedPoints.Count > 1)
            {
                avg /= selectedPoints.Count;
            }
            Camera editorCamera = SceneView.lastActiveSceneView.camera;

            for (int i = 0; i < selectedPoints.Count; i++)
            {
                switch (mode)
                {
                case 0: points[selectedPoints[i]].normal *= -1; break;

                case 1: points[selectedPoints[i]].normal = Vector3.Normalize(editorCamera.transform.position - points[selectedPoints[i]].position); break;

                case 2: points[selectedPoints[i]].normal = editorCamera.transform.forward; break;

                case 3: points[selectedPoints[i]].normal = CalculatePointNormal(points, selectedPoints[i], isClosed); break;

                case 4: points[selectedPoints[i]].normal = Vector3.left; break;

                case 5: points[selectedPoints[i]].normal = Vector3.right; break;

                case 6: points[selectedPoints[i]].normal = Vector3.up; break;

                case 7: points[selectedPoints[i]].normal = Vector3.down; break;

                case 8: points[selectedPoints[i]].normal = Vector3.forward; break;

                case 9: points[selectedPoints[i]].normal = Vector3.back; break;

                case 10: points[selectedPoints[i]].normal = Vector3.Normalize(avg - points[selectedPoints[i]].position); break;

                case 11:
                    SplineSample result = new SplineSample();
                    editor.evaluateAtPoint(selectedPoints[i], result);
                    points[selectedPoints[i]].normal = Vector3.Cross(result.forward, result.right).normalized;
                    break;
                }
            }
        }
Exemple #20
0
        protected void DrawResult(SplineSample result)
        {
            SplineTracer tracer = (SplineTracer)target;

            Handles.color = Color.white;
            Handles.DrawLine(tracer.transform.position, result.position);
            SplineEditorHandles.DrawSolidSphere(result.position, HandleUtility.GetHandleSize(result.position) * 0.2f);
            Handles.color = Color.blue;
            Handles.DrawLine(result.position, result.position + result.forward * HandleUtility.GetHandleSize(result.position) * 0.5f);
            Handles.color = Color.green;
            Handles.DrawLine(result.position, result.position + result.up * HandleUtility.GetHandleSize(result.position) * 0.5f);
            Handles.color = Color.red;
            Handles.DrawLine(result.position, result.position + result.right * HandleUtility.GetHandleSize(result.position) * 0.5f);
            Handles.color = Color.white;
        }
        protected override void KeyHandles(SplineSampleModifier.Key key, bool edit)
        {
            if (!isOpen)
            {
                return;
            }
            bool         is2D   = user.spline != null && user.spline.is2D;
            SplineSample result = new SplineSample();
            List <SplineSampleModifier.Key> keys = module.GetKeys();

            OffsetModifier.OffsetKey offsetKey = (OffsetModifier.OffsetKey)key;
            user.spline.Evaluate(offsetKey.position, result);
            matrix.SetTRS(result.position, Quaternion.LookRotation(result.direction, result.normal), Vector3.one * result.size);
            Vector3 pos = matrix.MultiplyPoint(offsetKey.offset);

            if (is2D)
            {
                Handles.DrawLine(result.position, result.position + result.right * offsetKey.offset.x * result.size);
                Handles.DrawLine(result.position, result.position - result.right * offsetKey.offset.x * result.size);
            }
            else
            {
                Handles.DrawWireDisc(result.position, result.direction, offsetKey.offset.magnitude * result.size);
            }
            Handles.DrawLine(result.position, pos);

            if (edit)
            {
                Vector3 lastPos = pos;
                pos = SplineEditorHandles.FreeMoveRectangle(pos, HandleUtility.GetHandleSize(pos) * 0.1f);
                if (pos != lastPos)
                {
                    pos   = matrix.inverse.MultiplyPoint(pos);
                    pos.z = 0f;
                    if (is2D)
                    {
                        offsetKey.offset = Vector2.right * pos.x;
                    }
                    else
                    {
                        offsetKey.offset = pos;
                    }
                    user.Rebuild();
                }
            }

            base.KeyHandles(key, edit);
        }
        protected void OffsetPoints(SplinePoint[] points, Vector3 offset, Space space)
        {
            if (offset != Vector3.zero)
            {
                segment.stitch = false;
            }
            SplineSample result = new SplineSample();

            if (space == Space.Self && segment.previous != null)
            {
                segment.previous.Evaluate(1.0, result);
            }
            for (int i = 0; i < points.Length; i++)
            {
                points[i].SetPosition(points[i].position + offset);
            }
        }
Exemple #23
0
 internal void CopyFrom(MotionModule input)
 {
     enabled        = input.enabled;
     offset         = input.offset;
     useSplineSizes = input.useSplineSizes;
     rotationOffset = input.rotationOffset;
     baseScale      = input.baseScale;
     SplineSample   = input.SplineSample;
     applyPositionX = input.applyPositionX;
     applyPositionY = input.applyPositionY;
     applyPositionZ = input.applyPositionZ;
     applyRotationX = input.applyRotationX;
     applyRotationY = input.applyRotationY;
     applyRotationZ = input.applyRotationZ;
     applyScaleX    = input.applyScaleX;
     applyScaleY    = input.applyScaleY;
     applyScaleZ    = input.applyScaleZ;
 }
        protected void OffsetPoints(SplinePoint[] points, Vector3 offset, Space space)
        {
            if (offset != Vector3.zero)
            {
                segment.stitch = false;
            }
            SplineSample result = new SplineSample();

            if (space == Space.Self && segment.previous != null)
            {
                segment.previous.Evaluate(1.0, result);
                offset = result.forward * offset.z + result.right * offset.x + result.up * offset.y;
            }
            transform.InverseTransformDirection(offset);
            for (int i = 0; i < points.Length; i++)
            {
                points[i].SetPosition(points[i].position + offset);
            }
        }
        protected override void KeyHandles(SplineSampleModifier.Key key, bool edit)
        {
            RotationModifier.RotationKey rotationKey = (RotationModifier.RotationKey)key;
            SplineSample result = new SplineSample();

            user.spline.Evaluate(rotationKey.position, result);
            if (rotationKey.useLookTarget)
            {
                if (rotationKey.target != null)
                {
                    Handles.DrawDottedLine(result.position, rotationKey.target.position, 5f);
                    if (edit)
                    {
                        Vector3 lastPos = rotationKey.target.position;
                        rotationKey.target.position = Handles.PositionHandle(rotationKey.target.position, Quaternion.identity);
                        if (lastPos != rotationKey.target.position)
                        {
                            user.Rebuild();
                        }
                    }
                }
            }
            else
            {
                Quaternion directionRot = Quaternion.LookRotation(result.forward, result.up);
                Quaternion rot          = directionRot * Quaternion.Euler(rotationKey.rotation);
                SplineEditorHandles.DrawArrowCap(result.position, rot, HandleUtility.GetHandleSize(result.position));

                if (edit)
                {
                    Vector3 lastEuler = rot.eulerAngles;
                    rot = Handles.RotationHandle(rot, result.position);
                    rot = Quaternion.Inverse(directionRot) * rot;
                    rotationKey.rotation = rot.eulerAngles;
                    if (rot.eulerAngles != lastEuler)
                    {
                        user.Rebuild();
                    }
                }
            }
            base.KeyHandles(key, edit);
        }
        public override void DrawScene()
        {
            bool   change       = false;
            Camera editorCamera = SceneView.currentDrawingSceneView.camera;

            for (int i = 0; i < spline.pointCount; i++)
            {
                Vector3 pos = spline.GetPointPosition(i);
                if (SplineEditorHandles.CircleButton(pos, Quaternion.LookRotation(editorCamera.transform.position - pos), HandleUtility.GetHandleSize(pos) * 0.12f, 1f, spline.editorPathColor))
                {
                    SplitAtPoint(i);
                    change = true;
                    break;
                }
            }
            SplineSample projected = spline.Evaluate(ProjectMouse());

            if (!change)
            {
                float   pointValue = (float)projected.percent * (spline.pointCount - 1);
                int     pointIndex = Mathf.FloorToInt(pointValue);
                float   size       = HandleUtility.GetHandleSize(projected.position) * 0.3f;
                Vector3 up         = Vector3.Cross(editorCamera.transform.forward, projected.forward).normalized *size + projected.position;
                Vector3 down       = Vector3.Cross(projected.forward, editorCamera.transform.forward).normalized *size + projected.position;
                Handles.color = spline.editorPathColor;
                Handles.DrawLine(up, down);
                Handles.color = Color.white;
                if (pointValue - pointIndex > spline.moveStep)
                {
                    if (SplineEditorHandles.CircleButton(projected.position, Quaternion.LookRotation(editorCamera.transform.position - projected.position), HandleUtility.GetHandleSize(projected.position) * 0.12f, 1f, spline.editorPathColor))
                    {
                        SplitAtPercent(projected.percent);
                        change = true;
                    }
                }
                SceneView.RepaintAll();
            }
            Handles.color = Color.white;
            SplineDrawer.DrawSplineComputer(spline, 0.0, projected.percent, 1f);
            SplineDrawer.DrawSplineComputer(spline, projected.percent, 1.0, 0.4f);
        }
Exemple #27
0
        protected void Traverse(SplineSample input)
        {
            float absFollowSpeed = followSpeed;

            Spline.Direction direction = Spline.Direction.Forward;
            if (absFollowSpeed < 0f)
            {
                absFollowSpeed *= -1f;
                direction       = Spline.Direction.Backward;
            }
            float travelDistance = Time.deltaTime * absFollowSpeed;
            float traveled;

            Evaluate(Travel(input.percent, travelDistance, direction, out traveled), input);

            if (traveled < travelDistance && ((direction == Spline.Direction.Forward && input.percent > 0.99999) || (direction == Spline.Direction.Backward && input.percent < 0.00001)))
            {
                //we have reached the end of the segment
                if (direction == Spline.Direction.Forward)
                {
                    if (_segment.next != null)
                    {
                        _segment = _segment.next;
                        OnEnteredSegment(_segment);
                        Evaluate(Travel(0.0, travelDistance - traveled, direction, out traveled), input);
                    }
                }
                else
                {
                    if (_segment.previous != null)
                    {
                        _segment = _segment.previous;
                        OnEnteredSegment(_segment);
                        Evaluate(Travel(1.0, travelDistance - traveled, direction, out traveled), input);
                    }
                }
            }
        }
Exemple #28
0
        public static void DrawSplineComputer(SplineComputer comp, double fromPercent = 0.0, double toPercent = 1.0, float alpha = 1f)
        {
            if (comp == null)
            {
                return;
            }
            Color prevColor   = Handles.color;
            Color orange      = new Color(1f, 0.564f, 0f);
            Color handleColor = comp.editorPathColor;

            handleColor.a = alpha;
            Handles.color = handleColor;
            if (comp.pointCount < 2)
            {
                return;
            }

            if (comp.type == Spline.Type.BSpline && comp.pointCount > 1)
            {
                SplinePoint[] compPoints = comp.GetPoints();
                Handles.color = new Color(handleColor.r, handleColor.g, handleColor.b, 0.5f * alpha);
                for (int i = 0; i < compPoints.Length - 1; i++)
                {
                    Handles.DrawLine(compPoints[i].position, compPoints[i + 1].position);
                }
                Handles.color = handleColor;
            }

            if (!comp.drawThinckness)
            {
                if (positions.Length != comp.sampleCount * 2)
                {
                    positions = new Vector3[comp.sampleCount * 2];
                }
                Vector3 prevPoint  = comp.EvaluatePosition(fromPercent);
                int     pointIndex = 0;
                for (int i = 1; i < comp.sampleCount; i++)
                {
                    positions[pointIndex] = prevPoint;
                    pointIndex++;
                    positions[pointIndex] = comp.samples[i].position;
                    pointIndex++;
                    prevPoint = positions[pointIndex - 1];
                }
                Handles.DrawLines(positions);
            }
            else
            {
                Transform editorCamera = SceneView.currentDrawingSceneView.camera.transform;
                if (positions.Length != comp.sampleCount * 6)
                {
                    positions = new Vector3[comp.sampleCount * 6];
                }
                SplineSample prevResult = comp.Evaluate(fromPercent);
                Vector3      prevNormal = prevResult.normal;
                if (comp.billboardThickness)
                {
                    prevNormal = (editorCamera.position - prevResult.position).normalized;
                }
                Vector3 prevRight  = Vector3.Cross(prevResult.direction, prevNormal).normalized *prevResult.size * 0.5f;
                int     pointIndex = 0;
                for (int i = 1; i < comp.sampleCount; i++)
                {
                    SplineSample newResult = comp.samples[i];
                    Vector3      newNormal = newResult.normal;
                    if (comp.billboardThickness)
                    {
                        newNormal = (editorCamera.position - newResult.position).normalized;
                    }
                    Vector3 newRight = Vector3.Cross(newResult.direction, newNormal).normalized *newResult.size * 0.5f;

                    positions[pointIndex] = prevResult.position + prevRight;
                    positions[pointIndex + comp.sampleCount * 2] = prevResult.position - prevRight;
                    positions[pointIndex + comp.sampleCount * 4] = newResult.position - newRight;
                    pointIndex++;
                    positions[pointIndex] = newResult.position + newRight;
                    positions[pointIndex + comp.sampleCount * 2] = newResult.position - newRight;
                    positions[pointIndex + comp.sampleCount * 4] = newResult.position + newRight;
                    pointIndex++;
                    prevResult = newResult;
                    prevRight  = newRight;
                    prevNormal = newNormal;
                }
                Handles.DrawLines(positions);
            }
            Handles.color = prevColor;
        }
Exemple #29
0
        IEnumerator CreateSegment()
        {
            while (!levels[levelIndex].isReady && !testMode)
            {
                yield return(null);
            }
            HandleLevelChange();
            while (LevelSegment.generationState != LevelSegment.GenerationState.Idle)
            {
                yield return(null);
            }
            if (levels[levelIndex].IsDone() && !testMode)
            {
                yield break;
            }
            LevelSegment segment = null;

            if (testMode)
            {
                GameObject go = Instantiate(debugSegments[Random.Range(0, debugSegments.Length)]);
                segment = go.GetComponent <LevelSegment>();
            }
            else
            {
                segment = levels[levelIndex].InstantiateSegment();
            }
            Transform  segmentTrs = segment.transform;
            Vector3    spawnPos   = segmentTrs.position;
            Quaternion spawnRot   = segmentTrs.rotation;

            if (segments.Count > 0)
            {
                SplineSample lastSegmentEndResult = new SplineSample();
                _segments[_segments.Count - 1].Evaluate(1.0, lastSegmentEndResult);
                spawnPos = lastSegmentEndResult.position;
                spawnRot = lastSegmentEndResult.rotation;
                switch (segment.axis)
                {
                case LevelSegment.Axis.X: spawnRot = Quaternion.AngleAxis(90f, Vector3.up) * spawnRot; break;

                case LevelSegment.Axis.Y: spawnRot = Quaternion.AngleAxis(90f, Vector3.right) * spawnRot; break;
                }
            }

            segmentTrs.position = spawnPos;
            if (segment.objectProperties[0].extrusionSettings.applyRotation)
            {
                segmentTrs.rotation = spawnRot;
            }


            if (segment.type == LevelSegment.Type.Extruded)
            {
                switch (segment.axis)
                {
                case LevelSegment.Axis.X:
                    segment.transform.position += segment.transform.right * segment.GetBounds().size.x;
                    break;

                case LevelSegment.Axis.Y:
                    segment.transform.position += segment.transform.up * segment.GetBounds().size.y;
                    break;

                case LevelSegment.Axis.Z:
                    segment.transform.position += segment.transform.forward * segment.GetBounds().size.z;
                    break;
                }
            }

            if (_segments.Count > 0)
            {
                segment.previous = _segments[_segments.Count - 1];
            }
            segment.level = levels[levelIndex];

            if (segment.type == LevelSegment.Type.Custom)
            {
                Quaternion entranceRotationDelta = segment.customEntrance.rotation * Quaternion.Inverse(spawnRot);
                segment.transform.rotation = segment.transform.rotation * Quaternion.Inverse(entranceRotationDelta);
                if (segment.customKeepUpright)
                {
                    segment.transform.rotation = Quaternion.FromToRotation(segment.customEntrance.up, Vector3.up) * segment.transform.rotation;
                }
                Vector3 entranceOffset = segment.transform.position - segment.customEntrance.position;
                segment.transform.position = spawnPos + entranceOffset;
            }

            if (segmentIndex == int.MaxValue)
            {
                segmentIndex = 2;
            }
            segment.Initialize(segmentIndex++);
            segment.transform.parent = transform;
            currentPathGenerator.GeneratePath(segment);
            _segments.Add(segment);
            //Remove old segments
            if (type == Type.Infinite && _segments.Count > maxSegments)
            {
                StartCoroutine(CleanupRoutine());
            }
            if (levels[levelIndex].IsDone() && !testMode)
            {
                if (levelIteration == LevelIteration.Ordered && levelIndex >= levels.Length - 1)
                {
                    if (onLevelsDepleted != null)
                    {
                        onLevelsDepleted();
                    }
                    yield break;
                }
                if (levelIteration == LevelIteration.None)
                {
                    if (onLevelsDepleted != null)
                    {
                        onLevelsDepleted();
                    }
                    yield break;
                }
                NextLevel();
            }
        }
Exemple #30
0
        /// <summary>
        /// Project a world space point onto the spline and write to a SplineSample.
        /// </summary>
        /// <param name="point">3D Point in world space</param>
        /// <param name="result">The SplineSample object to write the result into</param>
        /// <param name="from">Sample from [0-1] default: 0.0</param>
        /// <param name="to">Sample to [0-1] default: 1.0</param>
        /// <returns></returns>
        public virtual void Project(Vector3 point, SplineSample result, double from = 0.0, double to = 1.0, EvaluateMode mode = EvaluateMode.Cached)
        {
            if (mode == EvaluateMode.Accurate)
            {
                spline.Evaluate(result, spline.Project(point, 4, from, to));
                return;
            }
            if (samples.Length == 0)
            {
                return;
            }
            if (samples.Length == 1)
            {
                if (result == null)
                {
                    result = new SplineSample(samples[0]);
                }
                else
                {
                    result.CopyFrom(samples[0]);
                }
                return;
            }
            //First make a very rough sample of the from-to region
            int steps = 2;

            if (spline != null)
            {
                steps = (spline.points.Length - 1) * 6;                 //Sampling six points per segment is enough to find the closest point range
            }
            int step = samples.Length / steps;

            if (step < 1)
            {
                step = 1;
            }
            float minDist   = (point - samples[0].position).sqrMagnitude;
            int   fromIndex = 0;
            int   toIndex   = samples.Length - 1;

            if (from != 0.0)
            {
                fromIndex = DMath.FloorInt(from * (samples.Length - 1));
            }
            if (to != 1.0)
            {
                toIndex = Mathf.CeilToInt((float)to * (samples.Length - 1));
            }
            int checkFrom = fromIndex;
            int checkTo   = toIndex;

            //Find the closest point range which will be checked in detail later
            for (int i = fromIndex; i <= toIndex; i += step)
            {
                if (i > toIndex)
                {
                    i = toIndex;
                }
                float dist = (point - samples[i].position).sqrMagnitude;
                if (dist < minDist)
                {
                    minDist   = dist;
                    checkFrom = Mathf.Max(i - step, 0);
                    checkTo   = Mathf.Min(i + step, samples.Length - 1);
                }
                if (i == toIndex)
                {
                    break;
                }
            }
            minDist = (point - samples[checkFrom].position).sqrMagnitude;

            int index = checkFrom;

            //Find the closest result within the range
            for (int i = checkFrom + 1; i <= checkTo; i++)
            {
                float dist = (point - samples[i].position).sqrMagnitude;
                if (dist < minDist)
                {
                    minDist = dist;
                    index   = i;
                }
            }
            //Project the point on the line between the two closest samples
            int backIndex = index - 1;

            if (backIndex < 0)
            {
                backIndex = 0;
            }
            int frontIndex = index + 1;

            if (frontIndex > samples.Length - 1)
            {
                frontIndex = samples.Length - 1;
            }
            Vector3 back             = LinearAlgebraUtility.ProjectOnLine(samples[backIndex].position, samples[index].position, point);
            Vector3 front            = LinearAlgebraUtility.ProjectOnLine(samples[index].position, samples[frontIndex].position, point);
            float   backLength       = (samples[index].position - samples[backIndex].position).magnitude;
            float   frontLength      = (samples[index].position - samples[frontIndex].position).magnitude;
            float   backProjectDist  = (back - samples[backIndex].position).magnitude;
            float   frontProjectDist = (front - samples[frontIndex].position).magnitude;

            if (backIndex < index && index < frontIndex)
            {
                if ((point - back).sqrMagnitude < (point - front).sqrMagnitude)
                {
                    SplineSample.Lerp(samples[backIndex], samples[index], backProjectDist / backLength, result);
                }
                else
                {
                    SplineSample.Lerp(samples[frontIndex], samples[index], frontProjectDist / frontLength, result);
                }
            }
            else if (backIndex < index)
            {
                SplineSample.Lerp(samples[backIndex], samples[index], backProjectDist / backLength, result);
            }
            else
            {
                SplineSample.Lerp(samples[frontIndex], samples[index], frontProjectDist / frontLength, result);
            }
        }