コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: LevelGenerator.cs プロジェクト: AgostinoMatt/Runner
        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);
        }
コード例 #3
0
ファイル: SplinePath.cs プロジェクト: AgostinoMatt/Runner
        /// <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);
            }
        }
コード例 #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);
            }
        }
コード例 #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++;
        }
コード例 #6
0
ファイル: Runner.cs プロジェクト: AgostinoMatt/Runner
        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;
        }
コード例 #7
0
ファイル: NodeEditor.cs プロジェクト: Tim-dev-hub/Road-puzzle
        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();
            }
        }
コード例 #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);
        }
コード例 #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();
        }
コード例 #10
0
ファイル: Runner.cs プロジェクト: AgostinoMatt/Runner
        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;
            }
        }
コード例 #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;
        }
コード例 #12
0
ファイル: Runner.cs プロジェクト: AgostinoMatt/Runner
 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);
     }
 }
コード例 #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);
        }
コード例 #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);
     }
 }
コード例 #15
0
ファイル: LevelGenerator.cs プロジェクト: AgostinoMatt/Runner
        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;
        }
コード例 #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);
     }
 }
コード例 #17
0
        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;
        }
コード例 #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);
 }
コード例 #19
0
        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;
                }
            }
        }
コード例 #20
0
ファイル: SplineTracerEditor.cs プロジェクト: Wanyea/Galaga
        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;
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
            }
        }
コード例 #23
0
ファイル: Runner.cs プロジェクト: AgostinoMatt/Runner
 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;
 }
コード例 #24
0
        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);
            }
        }
コード例 #25
0
        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);
        }
コード例 #26
0
        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);
        }
コード例 #27
0
ファイル: Runner.cs プロジェクト: AgostinoMatt/Runner
        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);
                    }
                }
            }
        }
コード例 #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;
        }
コード例 #29
0
ファイル: LevelGenerator.cs プロジェクト: AgostinoMatt/Runner
        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();
            }
        }
コード例 #30
0
ファイル: SplinePath.cs プロジェクト: AgostinoMatt/Runner
        /// <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);
            }
        }