コード例 #1
0
ファイル: CurveEditor.cs プロジェクト: Cam582/Top-Hats
        void OnCurveGUI(Rect rect, SerializedProperty curve, CurveState state)
        {
            // Discard invisible curves
            if (!state.visible)
                return;

            var animCurve = curve.animationCurveValue;
            var keys = animCurve.keys;
            var length = keys.Length;

            // Curve drawing
            // Slightly dim non-editable curves
            var color = state.color;
            if (!state.editable)
                color.a *= 0.5f;

            Handles.color = color;
            var bounds = settings.bounds;

            if (length == 0)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, state.zeroKeyConstantValue));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, state.zeroKeyConstantValue));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else if (length == 1)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[0].value));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else
            {
                var prevKey = keys[0];
                for (int k = 1; k < length; k++)
                {
                    var key = keys[k];
                    var pts = BezierSegment(prevKey, key);

                    if (float.IsInfinity(prevKey.outTangent) || float.IsInfinity(key.inTangent))
                    {
                        var s = HardSegment(prevKey, key);
                        Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                    }
                    else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);

                    prevKey = key;
                }

                // Curve extents & loops
                if (keys[0].time > bounds.xMin)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        p1.time -= settings.bounds.width;
                        var p2 = keys[0];
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                    }
                    else
                    {
                        var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                        var p2 = CurveToCanvas(keys[0]);
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }

                if (keys[length - 1].time < bounds.xMax)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        var p2 = keys[0];
                        p2.time += settings.bounds.width;
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                    }
                    else
                    {
                        var p1 = CurveToCanvas(keys[length - 1]);
                        var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[length - 1].value));
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }
            }

            // Make sure selection is correct (undo can break it)
            bool isCurrentlySelectedCurve = curve == m_SelectedCurve;

            if (isCurrentlySelectedCurve && m_SelectedKeyframeIndex >= length)
                m_SelectedKeyframeIndex = -1;

            // Handles & keys
            for (int k = 0; k < length; k++)
            {
                bool isCurrentlySelectedKeyframe = k == m_SelectedKeyframeIndex;
                var e = Event.current;

                var pos = CurveToCanvas(keys[k]);
                var hitRect = new Rect(pos.x - 8f, pos.y - 8f, 16f, 16f);
                var offset = isCurrentlySelectedCurve
                    ? new RectOffset(5, 5, 5, 5)
                    : new RectOffset(6, 6, 6, 6);

                var outTangent = pos + CurveTangentToCanvas(keys[k].outTangent).normalized * 40f;
                var inTangent = pos - CurveTangentToCanvas(keys[k].inTangent).normalized * 40f;
                var inTangentHitRect = new Rect(inTangent.x - 7f, inTangent.y - 7f, 14f, 14f);
                var outTangentHitrect = new Rect(outTangent.x - 7f, outTangent.y - 7f, 14f, 14f);

                // Draw
                if (state.showNonEditableHandles)
                {
                    if (e.type == EventType.repaint)
                    {
                        var selectedColor = (isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                            ? settings.selectionColor
                            : state.color;

                        // Keyframe
                        EditorGUI.DrawRect(offset.Remove(hitRect), selectedColor);

                        // Tangents
                        if (isCurrentlySelectedCurve && (!state.onlyShowHandlesOnSelection || (state.onlyShowHandlesOnSelection && isCurrentlySelectedKeyframe)))
                        {
                            Handles.color = selectedColor;

                            if (k > 0 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, inTangent);
                                EditorGUI.DrawRect(offset.Remove(inTangentHitRect), selectedColor);
                            }

                            if (k < length - 1 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, outTangent);
                                EditorGUI.DrawRect(offset.Remove(outTangentHitrect), selectedColor);
                            }
                        }
                    }
                }

                // Events
                if (state.editable)
                {
                    // Keyframe move
                    if (m_EditMode == EditMode.Moving && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        EditMoveKeyframe(animCurve, keys, k);
                    }

                    // Tangent editing
                    if (m_EditMode == EditMode.TangentEdit && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        bool alreadyBroken = !(Mathf.Approximately(keys[k].inTangent, keys[k].outTangent) || (float.IsInfinity(keys[k].inTangent) && float.IsInfinity(keys[k].outTangent)));
                        EditMoveTangent(animCurve, keys, k, m_TangentEditMode, e.shift || !(alreadyBroken || e.control));
                    }

                    // Keyframe selection
                    if (e.type == EventType.mouseDown && rect.Contains(e.mousePosition))
                    {
                        if (hitRect.Contains(e.mousePosition))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.Moving;
                            e.Use();
                        }
                    }

                    // Tangent selection & edit mode
                    if (e.type == EventType.mouseDown && rect.Contains(e.mousePosition))
                    {
                        if (inTangentHitRect.Contains(e.mousePosition) && (k > 0 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.In;
                            e.Use();
                        }
                        else if (outTangentHitrect.Contains(e.mousePosition) && (k < length - 1 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.Out;
                            e.Use();
                        }
                    }

                    // Mouse up - clean up states
                    if (e.rawType == EventType.MouseUp && m_EditMode != EditMode.None)
                    {
                        m_EditMode = EditMode.None;
                    }

                    // Set cursors
                    {
                        EditorGUIUtility.AddCursorRect(hitRect, MouseCursor.MoveArrow);

                        if (k > 0 || state.loopInBounds)
                            EditorGUIUtility.AddCursorRect(inTangentHitRect, MouseCursor.RotateArrow);

                        if (k < length - 1 || state.loopInBounds)
                            EditorGUIUtility.AddCursorRect(outTangentHitrect, MouseCursor.RotateArrow);
                    }
                }
            }

            Handles.color = Color.white;
            SaveCurve(curve, animCurve);
        }
コード例 #2
0
ファイル: CurveEditor.cs プロジェクト: Cam582/Top-Hats
        void EditMoveTangent(AnimationCurve curve, Keyframe[] keys, int keyframeIndex, Tangent targetTangent, bool linkTangents)
        {
            var pos = CanvasToCurve(Event.current.mousePosition);

            float time = keys[keyframeIndex].time;
            float value = keys[keyframeIndex].value;

            pos -= new Vector3(time, value);

            if (targetTangent == Tangent.In && pos.x > 0f)
                pos.x = 0f;

            if (targetTangent == Tangent.Out && pos.x < 0f)
                pos.x = 0f;

            float tangent;

            if (Mathf.Approximately(pos.x, 0f))
                tangent = pos.y < 0f ? float.PositiveInfinity : float.NegativeInfinity;
            else
                tangent = pos.y / pos.x;

            float inTangent = keys[keyframeIndex].inTangent;
            float outTangent = keys[keyframeIndex].outTangent;

            if (targetTangent == Tangent.In || linkTangents)
                inTangent = tangent;
            if (targetTangent == Tangent.Out || linkTangents)
                outTangent = tangent;

            SetKeyframe(curve, keyframeIndex, new Keyframe(time, value, inTangent, outTangent));
        }
コード例 #3
0
        public HomePageViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;

            Data           = new ObservableCollection <ObservablePoint>();
            _axialData     = new HashSet <ObservablePoint>();
            _axialDataPlot = new LineSeries
            {
                Title           = "Axial",
                Fill            = Brushes.Transparent,
                Stroke          = Brushes.Black,
                LineSmoothness  = 0,
                StrokeDashArray = new DoubleCollection {
                    2
                },
                Values     = new ChartValues <ObservablePoint>(),
                DataLabels = true
            };

            _radialData     = new HashSet <ObservablePoint>();
            _radialDataPlot = new LineSeries
            {
                Title           = "Radial Data",
                Fill            = Brushes.Transparent,
                Stroke          = Brushes.Orange,
                LineSmoothness  = 0,
                StrokeDashArray = new DoubleCollection {
                    2
                },
                Values = new ChartValues <ObservablePoint>()
            };

            _radialCurvePlot = new LineSeries
            {
                Title = "Radial Curve"
            };

            _axialCurvePlot = new LineSeries
            {
                Title          = "Axial",
                Fill           = Brushes.Transparent,
                Stroke         = Brushes.Red,
                LineSmoothness = 0.2,
                Values         = new ChartValues <ObservablePoint>()
            };

            _tgPlot = new LineSeries
            {
                Title  = "Tg",
                Fill   = Brushes.Transparent,
                Stroke = Brushes.Green,
                Values = new ChartValues <ObservablePoint>()
            };

            _generatedCurveDataPlot = new LineSeries
            {
                Title             = "Generated Data",
                Fill              = Brushes.Transparent,
                Stroke            = Brushes.Magenta,
                PointGeometrySize = 0.1,
                Values            = new ChartValues <ObservablePoint>()
            };

            StressStrainCurveSeries = new SeriesCollection();
            StressStrainCurveSeries.Add(_axialDataPlot);
            StressStrainCurveSeries.Add(_radialDataPlot);
            StressStrainCurveSeries.Add(_axialCurvePlot);
            StressStrainCurveSeries.Add(_tgPlot);
            StressStrainCurveSeries.Add(_generatedCurveDataPlot);

            //Commands

            StressStrainCurveModeCommand = new DelegateCommand(() =>
            {
                _regionManager.RequestNavigate(Configurations.Regions.ChartRegion, nameof(StressStrainCurveChartPage));
            });

            PoissonsRatioStressCurveModeCommand = new DelegateCommand(() =>
            {
                _regionManager.RequestNavigate(Configurations.Regions.ChartRegion, nameof(PoissonsRatioStressCurveChartPage));
            });

            ModulusStressCurveModeCommand = new DelegateCommand(() =>
            {
                _regionManager.RequestNavigate(Configurations.Regions.ChartRegion, nameof(ModulusStressCurveChartPage));
            });

            AddDataCommand  = new DelegateCommand(() => AddData(_inputMicrostrain, _inputStress));
            EditDataCommand = new DelegateCommand <ChartPoint>(p =>

            {
                EditMicrostrain = p.X;
                EditStress      = p.Y;
            });

            MouseDoubleClickCommand = new DelegateCommand(() =>
            {
                AddData(_currentXData, _currentYData);
            });

            SmoothDataCommand = new DelegateCommand(async() => await SmoothData());

            ResetCommand = new DelegateCommand(() =>
            {
                Data.Clear();
                _axialData.Clear();
                _axialDataPlot.Values.Clear();
                _axialCurvePlot.Values.Clear();
                _tgPlot.Values.Clear();
                _generatedCurveDataPlot.Values.Clear();
                _radialData.Clear();
                _radialDataPlot.Values.Clear();
            });

            DrawTangentCommand = new DelegateCommand <bool?>(v =>
            {
                _tgPlot.Values.Clear();

                _tgPlot.Visibility = (bool)v ? Visibility.Visible : Visibility.Hidden;
                if ((bool)v)
                {
                    var x = _axialData.OrderBy(d => d.X).Select(d => d.X).ToArray();
                    var y = _axialData.OrderBy(d => d.X).Select(d => d.Y).ToArray();
                    var t = PolynomialRegression.LeastSquartPolynonial(x, y, PolynomDegree);

                    var tgY = Tangent.Y(t, _axialData.OrderBy(p => p.X).Last().X);

                    _tgPlot.Values.Add(new ObservablePoint {
                        X = 0, Y = 0
                    });
                    _tgPlot.Values.Add(new ObservablePoint {
                        X = _axialData.OrderBy(p => p.X).Last().X, Y = tgY
                    });
                }
            });

            GenerateDataCommand = new DelegateCommand(() =>
            {
                _generatedCurveDataPlot.Values.Clear();
                var x = _axialData.OrderBy(d => d.X).Select(d => d.X).ToArray();
                var y = _axialData.OrderBy(d => d.X).Select(d => d.Y).ToArray();
                var t = PolynomialRegression.LeastSquartPolynonial(x, y, PolynomDegree);
                Task.Run(() =>
                {
                    var generatedData = PolynomialRegression.Generate(t, 50, _axialData.OrderBy(d => d.X).Last().X, GeneratedDataNoise);
                    var strain        = generatedData.Item1;
                    var stress        = generatedData.Item2;
                    for (int i = 0; i < strain.Length; i++)
                    {
                        _generatedCurveDataPlot.Values.Add(new ObservablePoint {
                            X = strain[i], Y = stress[i]
                        });
                    }
                });
            });
        }
コード例 #4
0
 protected virtual void EvaluateTangent(Tangent tangentExpression)
 {
 }
コード例 #5
0
 public void Visit(Tangent tangentExpression) => EvaluateTangent(tangentExpression);
コード例 #6
0
        /// <summary>
        /// The matricies can only be calculated if the mesh has all positions, indices and uv coordinates initialized.
        /// Thus call this after initializing the mesh.
        /// </summary>
        private void CalcTangentsAndBitangents()
        {
            float maxId = IDs.Max();

            if (maxId > TexCoord.Count)
            {
                throw new ArgumentException("Not all TexCoords are set, tangents and bitangents can not be calculated.");
            }

            //Calculate TBN for every triangle in the mesh
            List <Vector3> tangentPerTriangle   = new List <Vector3>();
            List <Vector3> bitangentPerTriangle = new List <Vector3>();

            for (int i = 0; i < IDs.Count; i += 3)
            {
                int id0 = (int)IDs[i + 0];
                int id1 = (int)IDs[i + 1];
                int id2 = (int)IDs[i + 2];

                Vector3 p0 = Position[id0];
                Vector3 p1 = Position[id1];
                Vector3 p2 = Position[id2];

                Vector3 q1 = p1 - p0;
                Vector3 q2 = p2 - p0;

                float u0 = TexCoord[id0].X;
                float u1 = TexCoord[id1].X;
                float u2 = TexCoord[id2].X;

                float v0 = TexCoord[id0].Y;
                float v1 = TexCoord[id1].Y;
                float v2 = TexCoord[id2].Y;

                Vector2 s = new Vector2(u1 - u0, u2 - u0);
                Vector2 t = new Vector2(v1 - v0, v2 - v0);

                var leftSide  = Mat2x2(t.Y, -t.X, -s.Y, s.X);
                var rightSide = VecToMat(q1, q2);
                var det       = (1.0f / (s.X * t.Y - s.Y * t.X));

                Matrix4x4 tb = Matrix4x4.Multiply(Matrix4x4.Multiply(leftSide, det), rightSide);

                Vector3 tan   = new Vector3(tb.M11, tb.M12, tb.M13);
                Vector3 bitan = new Vector3(tb.M21, tb.M22, tb.M23);

                tangentPerTriangle.Add(Vector3.Normalize(tan));
                bitangentPerTriangle.Add(Vector3.Normalize(bitan));
            }

            //Average TBN on every vertex
            for (int i = 0; i < Position.Count; i++)
            {
                int     countOfPointMatches = 0;
                Vector3 resultingTangent    = Vector3.Zero;
                Vector3 resultingBitangent  = Vector3.Zero;

                for (int k = 0; k < IDs.Count; k += 3)
                {
                    int id0 = (int)IDs[k + 0];
                    int id1 = (int)IDs[k + 1];
                    int id2 = (int)IDs[k + 2];

                    if (id0 == i || id1 == i || id2 == i)
                    {
                        countOfPointMatches++;
                        resultingTangent   += tangentPerTriangle[(k - k % 3) / 3];
                        resultingBitangent += bitangentPerTriangle[(k - k % 3) / 3];
                    }
                }

                if (countOfPointMatches != 0)
                {
                    resultingTangent   = resultingTangent / countOfPointMatches;
                    resultingBitangent = resultingBitangent / countOfPointMatches;
                }

                Tangent.Add(resultingTangent);
                Bitangent.Add(resultingBitangent);
            }
        }
コード例 #7
0
        public static void TangentHasCorrectType()
        {
            var tangent = new Tangent(One);

            Assert.AreEqual(SymbolType.Tangent, tangent.Type);
        }