示例#1
0
        protected override void OnSceneGUI()
        {
            // Bounds
            if (CurvyGlobalManager.Gizmos.HasFlag(CurvySplineGizmos.Bounds))
            {
                DTHandles.PushHandlesColor(new Color(0.3f, 0, 0));
                DTHandles.WireCubeCap(Target.Bounds.center, Target.Bounds.size);
                DTHandles.PopHandlesColor();
            }
            Handles.BeginGUI();

            mUserValuesLabel = new GUIStyle(EditorStyles.boldLabel);
            mUserValuesLabel.normal.textColor = Color.green;


            if (CurvyGlobalManager.Gizmos.HasFlag(CurvySplineGizmos.Labels))
            {
                GUIStyle stLabel = new GUIStyle(EditorStyles.boldLabel);
                stLabel.normal.textColor = Color.white;
                Handles.Label(Target.transform.position - new Vector3(-0.5f, 0.2f, 0), Target.name, stLabel);
                stLabel.normal.textColor = Color.red;
                foreach (CurvySplineSegment cp in Target.ControlPoints)
                {
                    Handles.Label(cp.transform.position + new Vector3(-0.5f, HandleUtility.GetHandleSize(cp.transform.position) * 0.35f, 0), cp.name, stLabel);
                }
            }

            Handles.EndGUI();
            // Snap Transform
            if (Target && DT._UseSnapValuePrecision)
            {
                Target.transform.localPosition    = DTMath.SnapPrecision(Target.transform.localPosition, 3);
                Target.transform.localEulerAngles = DTMath.SnapPrecision(Target.transform.localEulerAngles, 3);
            }
        }
示例#2
0
            public long Evaluate(
                EnemyObjectExpressionInfo enemyObjectExpressionInfo,                 // nullable
                long playerXMillis,
                long playerYMillis,
                long elapsedMillisecondsPerIteration,
                IDTDeterministicRandom rng)
            {
                long operand1 = this.operand1.Evaluate(
                    enemyObjectExpressionInfo: enemyObjectExpressionInfo,
                    playerXMillis: playerXMillis,
                    playerYMillis: playerYMillis,
                    elapsedMillisecondsPerIteration: elapsedMillisecondsPerIteration,
                    rng: rng);
                long operand2 = this.operand2.Evaluate(
                    enemyObjectExpressionInfo: enemyObjectExpressionInfo,
                    playerXMillis: playerXMillis,
                    playerYMillis: playerYMillis,
                    elapsedMillisecondsPerIteration: elapsedMillisecondsPerIteration,
                    rng: rng);

                if (this.changeUndefinedOutputToZero && operand1 == 0L && operand2 == 0L)
                {
                    return(0);
                }

                return(DTMath.ArcTangentScaled(operand1, operand2));
            }
示例#3
0
        public static Offset GetOffset(
            long speedInMillipixelsPerMillisecond,
            long movementDirectionInMillidegrees,
            long elapsedMillisecondsPerIteration)
        {
            if (speedInMillipixelsPerMillisecond < 0)
            {
                throw new Exception();
            }

            if (speedInMillipixelsPerMillisecond == 0)
            {
                return new Offset {
                           DeltaXInMillipixels = 0, DeltaYInMillipixels = 0
                }
            }
            ;

            movementDirectionInMillidegrees = DTMath.NormalizeAngleInMillidegrees(movementDirectionInMillidegrees);

            long numberOfMillipixels = speedInMillipixelsPerMillisecond * elapsedMillisecondsPerIteration;

            return(new Offset
            {
                DeltaXInMillipixels = numberOfMillipixels * DTMath.SineScaled(milliDegrees: movementDirectionInMillidegrees) / 1000L,
                DeltaYInMillipixels = numberOfMillipixels * DTMath.CosineScaled(milliDegrees: movementDirectionInMillidegrees) / 1000L
            });
        }
示例#4
0
        float getCrossValue(float globalF, CGBoundsGroup group)
        {
            switch (group.DistributionMode)
            {
            case CGBoundsGroup.DistributionModeEnum.Parent:
                return(DTMath.MapValue(-0.5f, 0.5f, CrossBase + m_CrossCurve.Evaluate(globalF) + group.PositionOffset.Next));

            case CGBoundsGroup.DistributionModeEnum.Self:
                return(DTMath.MapValue(-0.5f, 0.5f, group.PositionOffset.Next));
            }
            return(0);
        }
        /*! \cond PRIVATE */

        void getScaleInternal(float f, Vector3 baseScale, ref Vector3 scale)
        {
            if (ScaleMode == ScaleModeEnum.Advanced)
            {
                float scf = DTMath.Repeat(f - ScaleOffset, 1);
                float scx = baseScale.x * m_ScaleCurveX.Evaluate(scf);
                scale.Set(scx,
                          (m_ScaleUniform) ? scx : baseScale.y * m_ScaleCurveY.Evaluate(scf),
                          1);
            }
            else
            {
                scale = baseScale;
            }
        }
示例#6
0
        // 0 degrees is going straight up
        // 90 degrees is going right
        // 180 degrees is straight down
        // 270 degrees is going left
        // (Note function returns value in millidegrees)
        public static long?GetMovementDirectionInMillidegrees(long currentX, long currentY, long desiredX, long desiredY)
        {
            long deltaX = desiredX - currentX;
            long deltaY = desiredY - currentY;

            if (deltaX == 0 && deltaY == 0)
            {
                return(null);
            }

            long angleInMillidegrees = DTMath.ArcTangentScaled(x: deltaX, y: deltaY);
            long angle2 = -angleInMillidegrees + 90L * 1000L;

            return(DTMath.NormalizeAngleInMillidegrees(angle2));
        }
示例#7
0
            public long Evaluate(
                EnemyObjectExpressionInfo enemyObjectExpressionInfo,                 // nullable
                long playerXMillis,
                long playerYMillis,
                long elapsedMillisecondsPerIteration,
                IDTDeterministicRandom rng)
            {
                long operand = this.operand.Evaluate(
                    enemyObjectExpressionInfo: enemyObjectExpressionInfo,
                    playerXMillis: playerXMillis,
                    playerYMillis: playerYMillis,
                    elapsedMillisecondsPerIteration: elapsedMillisecondsPerIteration,
                    rng: rng);

                return(DTMath.CosineScaled(operand));
            }
示例#8
0
        /// <summary>
        /// Clamps a float to a range
        /// </summary>
        public static float ClampValue(float tf, CurvyClamping clamping, float minTF, float maxTF)
        {
            switch (clamping)
            {
            case CurvyClamping.Loop:
                float v1 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
                return(DTMath.MapValue(minTF, maxTF, Mathf.Repeat(v1, 1), 0, 1));

            case CurvyClamping.PingPong:
                float v2 = DTMath.MapValue(0, 1, tf, minTF, maxTF);
                return(DTMath.MapValue(minTF, maxTF, Mathf.PingPong(v2, 1), 0, 1));

            default:
                return(Mathf.Clamp(tf, minTF, maxTF));
            }
        }
示例#9
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            base.OnGUI(position, property, label);

            // GUI
            EditorGUI.PropertyField(position, property, label);


            maxV = Attribute.MaxValue;

            if (!string.IsNullOrEmpty(Attribute.MaxFieldOrPropertyName))
            {
                maxV = GetMemberValue <float>(property, Attribute.MaxFieldOrPropertyName);
            }

            // Clamp and snap
            switch (property.propertyType)
            {
            case SerializedPropertyType.Float:
                if (DT._UseSnapValuePrecision && Attribute.Precision > -1)
                {
                    property.floatValue = DTMath.SnapPrecision(property.floatValue, Attribute.Precision);
                }
                if (property.floatValue > maxV)
                {
                    property.floatValue = maxV;
                }

                break;

            case SerializedPropertyType.Integer:
                if (property.intValue > maxV)
                {
                    property.intValue = (int)maxV;
                }
                break;
            }
            label.tooltip = "";
        }
示例#10
0
        void validateTo()
        {
            ppTo.floatValue = DTMath.SnapPrecision(ppTo.floatValue, Attribute.Precision);
            switch (mOptions.ClampTo)
            {
            case DTValueClamping.Min:
                ppTo.floatValue = Mathf.Max(mOptions.ToMin, ppTo.floatValue);
                break;

            case DTValueClamping.Max:
                ppTo.floatValue = Mathf.Min(mOptions.ToMax, ppTo.floatValue);
                break;

            case DTValueClamping.Range:
                ppTo.floatValue = Mathf.Clamp(ppTo.floatValue, mOptions.ToMin, mOptions.ToMax);
                if (minmax)
                {
                    ppTo.floatValue = Mathf.Max(ppTo.floatValue, ppFrom.floatValue);
                }
                break;
            }
        }
示例#11
0
        public override void OnModuleSceneDebugGUI()
        {
            base.OnModuleSceneDebugGUI();
            CGVolume vol = Target.InData.GetData <CGVolume>();

            if (vol)
            {
                Handles.matrix = Target.Generator.transform.localToWorldMatrix;

                if (Target.ShowPathSamples)
                {
                    CGEditorUtility.SceneGUIPlot(vol.Position, 0.1f, Target.PathColor);
                    if (Target.ShowIndex)
                    {
                        var labels = Enumerable.Range(0, vol.Count).Select(i => i.ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(vol.Position, labels, Color.black, Vector2.zero);
                    }
                }
                if (Target.ShowCrossSamples)
                {
                    int vtLo = Target.LimitCross.From * vol.CrossSize;
                    int vtHi = vtLo + vol.CrossSize;
                    if (!Target.LimitCross.SimpleValue)
                    {
                        vtLo = Target.LimitCross.Low * vol.CrossSize;
                        vtHi = (Target.LimitCross.High + 1) * vol.CrossSize;
                    }

                    vtLo = Mathf.Clamp(vtLo, 0, vol.VertexCount);
                    vtHi = Mathf.Clamp(vtHi, vtLo, vol.VertexCount);
                    var range = vol.Vertex.SubArray <Vector3>(vtLo, vtHi - vtLo);
                    CGEditorUtility.SceneGUIPlot(range, 0.1f, Color.white);

                    if (Target.ShowIndex)
                    {
                        var labels = Enumerable.Range(vtLo, vtHi).Select(i => i.ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(range, labels, Color.black, Vector2.zero);
                    }

                    if (Target.ShowMap)
                    {
                        var labels = Enumerable.Range(vtLo, vtHi).Select(i => DTMath.SnapPrecision(vol.CrossMap[i], 3).ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(range, labels, new Color(1, 0, 1), new Vector2(10, 20));
                    }

                    if (Target.ShowNormals)
                    {
                        DTHandles.PushHandlesColor(Target.NormalColor);

                        for (int i = vtLo; i < vtHi; i++)
                        {
                            Handles.DrawLine(vol.Vertex[i], vol.Vertex[i] + vol.VertexNormal[i] * 2);
                        }

                        DTHandles.PopHandlesColor();
                    }
                }
                if (Target.Interpolate)
                {
                    Vector3 pos;
                    Vector3 tan;
                    Vector3 up;
                    vol.InterpolateVolume(Target.InterpolatePathF, Target.InterpolateCrossF, out pos, out tan, out up);
                    Handles.ConeCap(0, pos, Quaternion.LookRotation(up, tan), 1f);
                }
                Handles.matrix = Matrix4x4.identity;
            }
        }
示例#12
0
        public static void DoGUI(Rect position, SerializedProperty property, DTPropertyAttribute attribute, GUIContent label, AttributeOptionsFlags flags, VectorExPropertyDrawer drawer = null)
        {
            if (property.propertyType != SerializedPropertyType.Vector2 && property.propertyType != SerializedPropertyType.Vector3 && property.propertyType != SerializedPropertyType.Quaternion)
            {
                Debug.LogError("DevTools: [VectorEx] only valid for Vector and Quaternion fields!");
            }
            else
            {
                Rect posb = position.WithoutLabel();
                posb.height = EditorGUIUtility.singleLineHeight;

                int buttons = 0;
                if (flags.HasFlag(AttributeOptionsFlags.Clipboard))
                {
                    buttons += 2;
                }
                if (flags.HasFlag(AttributeOptionsFlags.One))
                {
                    buttons++;
                }
                if (flags.HasFlag(AttributeOptionsFlags.Zero))
                {
                    buttons++;
                }
                if (flags.HasFlag(AttributeOptionsFlags.Negate))
                {
                    buttons++;
                }

                Rect r = position.WithoutLabel();
                r.width -= buttons * 20;

                if (flags.HasFlag(AttributeOptionsFlags.Compact) || EditorGUIUtility.wideMode)
                {
                    if (drawer != null)
                    {
                        drawer.PushCustomColors();
                    }
                    EditorGUI.PrefixLabel(position, label);

                    if (property.propertyType == SerializedPropertyType.Vector2)
                    {
                        EditorGUI.BeginChangeCheck();
                        Vector2 v = DTGUI.CompactVector2Field(r, property.vector2Value);
                        if (EditorGUI.EndChangeCheck())
                        {
                            property.vector2Value = DT._UseSnapValuePrecision ? DTMath.SnapPrecision(v, attribute.Precision) : v;
                        }
                    }
                    else if (property.propertyType == SerializedPropertyType.Vector3)
                    {
                        EditorGUI.BeginChangeCheck();
                        Vector3 v = DTGUI.CompactVector3Field(r, property.vector3Value);
                        if (EditorGUI.EndChangeCheck())
                        {
                            property.vector3Value = DT._UseSnapValuePrecision ? DTMath.SnapPrecision(v, attribute.Precision) : v;
                        }
                    }
                    else if (property.propertyType == SerializedPropertyType.Quaternion)
                    {
                        EditorGUI.BeginChangeCheck();
                        Vector3 v = DTGUI.CompactVector3Field(r, DT._UseSnapValuePrecision ? DTMath.SnapPrecision(property.quaternionValue.eulerAngles, attribute.Precision) : property.quaternionValue.eulerAngles);
                        if (EditorGUI.EndChangeCheck())
                        {
                            property.quaternionValue = Quaternion.Euler(v);
                        }
                    }
                    if (drawer != null)
                    {
                        drawer.PopCustomColors();
                    }
                }
                else
                {
                    EditorGUI.BeginChangeCheck();
                    if (drawer != null)
                    {
                        drawer.PushCustomColors();
                    }
                    EditorGUI.PropertyField(position, property, label);
                    if (drawer != null)
                    {
                        drawer.PopCustomColors();
                    }
                    if (EditorGUI.EndChangeCheck() && DT._UseSnapValuePrecision)
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            property.vector2Value = DTMath.SnapPrecision(property.vector2Value, attribute.Precision);
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            property.vector3Value = DTMath.SnapPrecision(property.vector3Value, attribute.Precision);
                        }
                    }
                }

                // Buttons
                posb       = posb.ShiftXBy(r.width);
                posb.width = 19;
                if (flags.HasFlag(AttributeOptionsFlags.Clipboard))
                {
                    if (GUI.Button(posb, new GUIContent("C", "Copy"), EditorStyles.miniButton))
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            DT.ClipboardCopy(property.vector2Value);
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            DT.ClipboardCopy(property.vector3Value);
                        }
                    }
                    posb.x += 20;
                    // Can Paste?
                    if (property.propertyType == SerializedPropertyType.Vector2)
                    {
                        GUI.enabled = DT.ClipboardCanPasteTo <Vector2>();
                    }
                    else if (property.propertyType == SerializedPropertyType.Vector3)
                    {
                        GUI.enabled = DT.ClipboardCanPasteTo <Vector3>();
                    }

                    if (GUI.Button(posb, new GUIContent("P", "Pastge"), EditorStyles.miniButton))
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            property.vector2Value = DT.ClipboardPaste <Vector2>();
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            property.vector3Value = DT.ClipboardPaste <Vector3>();
                        }
                    }
                    GUI.enabled = true;
                    posb.x     += 20;
                }
                if (flags.HasFlag(AttributeOptionsFlags.Zero))
                {
                    if (GUI.Button(posb, new GUIContent("0", "Set to zero"), EditorStyles.miniButton))
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            property.vector2Value = Vector2.zero;
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            property.vector3Value = Vector3.zero;
                        }
                    }
                    posb.x += 20;
                }
                if (flags.HasFlag(AttributeOptionsFlags.One))
                {
                    if (GUI.Button(posb, new GUIContent("1", "Set to one"), EditorStyles.miniButton))
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            property.vector2Value = Vector2.one;
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            property.vector3Value = Vector3.one;
                        }
                    }
                    posb.x += 20;
                }
                if (flags.HasFlag(AttributeOptionsFlags.Negate))
                {
                    if (GUI.Button(posb, new GUIContent("~", "Negate"), EditorStyles.miniButton))
                    {
                        if (property.propertyType == SerializedPropertyType.Vector2)
                        {
                            property.vector2Value *= -1;
                        }
                        else if (property.propertyType == SerializedPropertyType.Vector3)
                        {
                            property.vector3Value *= -1;
                        }
                    }
                    posb.x += 20;
                }
            }
        }
        /*! \endcond */
        #endregion

        #region ### Public Methods ###

        public override void Refresh()
        {
            base.Refresh();
            if (Length == 0)
            {
                Reset();
            }
            else
            {
                var req = new List <CGDataRequestParameter>();
                req.Add(new CGDataRequestRasterization(this.From, this.Length, CGUtility.CalculateSamplePointsCacheSize(Resolution, InPath.SourceSlot().OnRequestPathModule.PathLength *this.Length), AngleThreshold, (Optimize) ? CGDataRequestRasterization.ModeEnum.Optimized : CGDataRequestRasterization.ModeEnum.Even));
                var path = InPath.GetData <CGPath>(req.ToArray());
                req.Clear();
                req.Add(new CGDataRequestRasterization(this.CrossFrom, this.CrossLength, CGUtility.CalculateSamplePointsCacheSize(CrossResolution, InCross.SourceSlot().OnRequestPathModule.PathLength *this.CrossLength), CrossAngleThreshold, (CrossOptimize) ? CGDataRequestRasterization.ModeEnum.Optimized : CGDataRequestRasterization.ModeEnum.Even));

                if (CrossIncludeControlPoints || CrossHardEdges || CrossMaterials)
                {
                    req.Add(new CGDataRequestMetaCGOptions(CrossHardEdges, CrossMaterials, CrossIncludeControlPoints, CrossExtendedUV));
                }

                var cross = InCross.GetData <CGShape>(req.ToArray());

                if (!path || !cross || path.Count == 0 || cross.Count == 0)
                {
                    OutVolume.ClearData();
                    OutVolumeHollow.ClearData();
                    return;
                }


                var vol       = CGVolume.Get(OutVolume.GetData <CGVolume>(), path, cross);
                var volHollow = (OutVolumeHollow.IsLinked) ? CGVolume.Get(OutVolumeHollow.GetData <CGVolume>(), path, cross) : null;

                PathSamples   = path.Count;
                CrossSamples  = cross.Count;
                CrossGroups   = cross.MaterialGroups.Count;
                CrossPosition = vol.Position[0];
                CrossRotation = Quaternion.LookRotation(vol.Direction[0], vol.Normal[0]);



                Vector3 baseScale = (ScaleUniform) ? new Vector3(ScaleX, ScaleX, 1) : new Vector3(ScaleX, ScaleY, 1);
                Vector3 scl       = baseScale;
                int     vtIdx     = 0;

                float[] scaleFArray = (ScaleReference == CGReferenceMode.Source) ? path.SourceF : path.F;

                Matrix4x4 mat;
                Matrix4x4 matHollow;

                Quaternion R;
                int        crossNormalMul  = (CrossReverseNormals) ? -1 : 1;
                int        hollowNormalMul = (HollowReverseNormals) ? -1 : 1;
                for (int sample = 0; sample < path.Count; sample++)
                {
                    R = Quaternion.LookRotation(path.Direction[sample], path.Normal[sample]);

                    getScaleInternal(scaleFArray[sample], baseScale, ref scl);
                    mat = Matrix4x4.TRS(path.Position[sample], R, scl);

                    if (volHollow == null)
                    {
                        for (int c = 0; c < cross.Count; c++)
                        {
                            vol.Vertex[vtIdx]         = mat.MultiplyPoint(cross.Position[c]);
                            vol.VertexNormal[vtIdx++] = R * cross.Normal[c] * crossNormalMul;
                        }
                    }
                    else
                    {
                        matHollow = Matrix4x4.TRS(path.Position[sample], R, scl * (1 - HollowInset));
                        for (int c = 0; c < cross.Count; c++)
                        {
                            vol.Vertex[vtIdx]             = mat.MultiplyPoint(cross.Position[c]);
                            vol.VertexNormal[vtIdx]       = R * cross.Normal[c];
                            volHollow.Vertex[vtIdx]       = matHollow.MultiplyPoint(cross.Position[c]);
                            volHollow.VertexNormal[vtIdx] = vol.VertexNormal[vtIdx++] * hollowNormalMul;
                        }
                    }
                }



                switch (CrossShiftMode)
                {
                case CrossShiftModeEnum.ByOrientation:
                    // shift CrossF to match Path Orientation
                    Vector2 hit;
                    float   frag;
                    for (int i = 0; i < cross.Count - 1; i++)
                    {
                        if (DTMath.RayLineSegmentIntersection(vol.Position[0], vol.VertexNormal[0], vol.Vertex[i], vol.Vertex[i + 1], out hit, out frag))
                        {
                            vol.CrossFShift = DTMath.SnapPrecision(vol.CrossF[i] + (vol.CrossF[i + 1] - vol.CrossF[i]) * frag, 2);
                            break;
                        }
                    }
                    if (vol.CrossClosed && DTMath.RayLineSegmentIntersection(vol.Position[0], vol.VertexNormal[0], vol.Vertex[cross.Count - 1], vol.Vertex[0], out hit, out frag))
                    {
                        vol.CrossFShift = DTMath.SnapPrecision(vol.CrossF[cross.Count - 1] + (vol.CrossF[0] - vol.CrossF[cross.Count - 1]) * frag, 2);
                    }
                    break;

                case CrossShiftModeEnum.Custom:
                    vol.CrossFShift = CrossShiftValue;
                    break;

                default:
                    vol.CrossFShift = 0;
                    break;
                }

                if (volHollow != null)
                {
                    volHollow.CrossFShift = vol.CrossFShift;
                }

                OutVolume.SetData(vol);
                OutVolumeHollow.SetData(volHollow);
            }
        }
        protected override void OnSceneGUI()
        {
            // Bounds
            if (CurvyGlobalManager.Gizmos.HasFlag(CurvySplineGizmos.Bounds))
            {
                DTHandles.PushHandlesColor(Color.gray);
                DTHandles.WireCubeCap(Target.Bounds.center, Target.Bounds.size);
                DTHandles.PopHandlesColor();
            }
            checkHotkeys();
            if (Target.Spline.RestrictTo2D && Tools.current == Tool.Move && !SceneView.currentDrawingSceneView.in2DMode)
            {
                Tools.hidden = true;
                Vector3 handlePos = (Tools.handlePosition != Target.transform.position) ? DTSelection.GetPosition() : Tools.handlePosition;
                Vector3 delta;
                EditorGUI.BeginChangeCheck();


                if (CurvyProject.Instance.UseTiny2DHandles)
                {
                    delta = DTHandles.TinyHandle2D(GUIUtility.GetControlID(GetHashCode(), FocusType.Passive), handlePos, Target.Spline.transform.rotation, 1) - handlePos;
                }
                else
                {
                    delta = DTHandles.PositionHandle2D(GUIUtility.GetControlID(GetHashCode(), FocusType.Passive), handlePos, Target.Spline.transform.rotation, 1) - handlePos;
                }

                if (EditorGUI.EndChangeCheck())
                {
                    foreach (var t in Selection.transforms)
                    {
                        Undo.ClearUndo(t);
                        Undo.RecordObject(t, "Move");
                        t.position += delta;
                    }
                }
            }
            else
            {
                Tools.hidden = false;
            }


            // Bezier-Handles
            if (Target.Spline.Interpolation == CurvyInterpolation.Bezier && !Target.AutoHandles)
            {
                #region --- Bezier Rotation Handling ---
                if (Tools.current == Tool.Rotate)
                {
                    Event e = Event.current;
                    if (e.shift && DTHandles.MouseOverSceneView)
                    {
                        Tools.hidden = true;
                        DTToolbarItem._StatusBar.Set("BezierRotate");
                        // This looks good, but then diff down below isn't working like intended:
                        //mBezierRot = Quaternion.LookRotation(Vector3.Cross(Target.HandleIn, Target.GetOrientationUpFast(0)), Target.GetOrientationUpFast(0));
                        Quaternion newRot = Handles.RotationHandle(mBezierRot, Target.transform.position);
                        if (newRot != mBezierRot)
                        {
                            Quaternion diff = Quaternion.Inverse(mBezierRot) * newRot;
                            mBezierRot = newRot;
                            var mode = CurvyProject.Instance.BezierMode | CurvyBezierModeEnum.Direction;
                            Undo.RecordObject(Target, "Rotate Handles");
                            Target.SetBezierHandleIn(diff * Target.HandleIn, Space.Self, mode);
                            Target.SetDirty();
                            EditorUtility.SetDirty(Target);
                        }
                    }
                    else
                    {
                        DTToolbarItem._StatusBar.Set("Hold <b>[Shift]</b> to rotate Handles", "BezierRotate");
                        Tools.hidden = false;
                    }
                }
                else
                {
                    DTToolbarItem._StatusBar.Set("BezierRotate");
                }
                #endregion

                #region --- Bezier Movement Handling ---
                //Belongs to Constraint Length:
                //Vector3 handleOut = Target.HandleOutPosition;
                //Vector3 handleIn = Target.HandleInPosition;

                EditorGUI.BeginChangeCheck();
                Vector3 pOut;
                Vector3 pIn;
                bool    chgOut = false;
                bool    chgIn  = false;
                if (Target.Spline.RestrictTo2D)
                {
                    Quaternion r = (Tools.pivotRotation == PivotRotation.Global) ? Target.Spline.transform.localRotation : Target.Spline.transform.rotation;
                    Handles.color = Color.yellow;
                    pIn           = Target.HandleInPosition;
                    pIn           = DTHandles.TinyHandle2D(GUIUtility.GetControlID(FocusType.Passive), pIn, r, CurvyGlobalManager.GizmoControlPointSize * 0.7f, Handles.CubeCap);
                    if (!CurvyProject.Instance.UseTiny2DHandles)
                    {
                        pIn = DTHandles.PositionHandle2D(GUIUtility.GetControlID(FocusType.Passive), pIn, r, 1);
                    }
                    chgIn         = Target.HandleInPosition != pIn;
                    Handles.color = Color.green;
                    pOut          = Target.HandleOutPosition;
                    pOut          = DTHandles.TinyHandle2D(GUIUtility.GetControlID(FocusType.Passive), pOut, r, CurvyGlobalManager.GizmoControlPointSize * 0.7f, Handles.CubeCap);
                    if (!CurvyProject.Instance.UseTiny2DHandles)
                    {
                        pOut = DTHandles.PositionHandle2D(GUIUtility.GetControlID(FocusType.Passive), pOut, r, 1);
                    }

                    chgOut = Target.HandleOutPosition != pOut;
                }
                else
                {
                    pIn   = Handles.PositionHandle(Target.HandleInPosition, Tools.handleRotation);
                    chgIn = Target.HandleInPosition != pIn;
                    DTHandles.PushHandlesColor(Color.yellow);
                    Handles.CubeCap(0, pIn, Quaternion.identity, HandleUtility.GetHandleSize(pIn) * CurvyGlobalManager.GizmoControlPointSize * 0.7f);
                    DTHandles.PopHandlesColor();
                    pOut   = Handles.PositionHandle(Target.HandleOutPosition, Tools.handleRotation);
                    chgOut = Target.HandleOutPosition != pOut;
                    DTHandles.PushHandlesColor(Color.green);
                    Handles.CubeCap(0, pOut, Quaternion.identity, HandleUtility.GetHandleSize(pOut) * CurvyGlobalManager.GizmoControlPointSize * 0.7f);
                    DTHandles.PopHandlesColor();
                }

                Handles.color = Color.yellow;
                Handles.DrawLine(pIn, Target.transform.position);
                Handles.color = Color.green;
                Handles.DrawLine(pOut, Target.transform.position);


                if (chgOut || chgIn)
                {
                    Undo.RecordObject(Target, "Move Handle");
                    if (chgOut)
                    {
                        Target.SetBezierHandleOut(pOut, Space.World, CurvyProject.Instance.BezierMode);
                        Target.HandleOut = DTMath.SnapPrecision(Target.HandleOut, 3);
                    }
                    else
                    {
                        Target.SetBezierHandleIn(pIn, Space.World, CurvyProject.Instance.BezierMode);
                        Target.HandleIn = DTMath.SnapPrecision(Target.HandleIn, 3);
                    }
                }

                if (EditorGUI.EndChangeCheck())
                {
                    EditorUtility.SetDirty(Target);
                    Target.SetDirty();

                    /*
                     * var lcons = CurvyProject.Instance.FindItem<TBCPLengthConstraint>();
                     * if (lcons.On && Target.Spline.Length > lcons.MaxSplineLength)
                     * {
                     *  Target.HandleOutPosition = handleOut;
                     *  Target.HandleInPosition = handleIn;
                     *  Target.SetDirty();
                     * }
                     */
                }
                #endregion
            }
            if (mConnectionEditor)
            {
                mConnectionEditor.OnSceneGUI();
            }
            // Snap Transform
            if (Target && DT._UseSnapValuePrecision)
            {
                Target.transform.localPosition    = DTMath.SnapPrecision(Target.transform.localPosition, 3);
                Target.transform.localEulerAngles = DTMath.SnapPrecision(Target.transform.localEulerAngles, 3);
                //Target.TTransform.FromTransform(Target.transform);
            }
        }
示例#15
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            base.OnGUI(position, property, label);


            minV = Attribute.MinValue;
            maxV = Attribute.MaxValue;

            if (!string.IsNullOrEmpty(Attribute.MinFieldOrPropertyName))
            {
                minV = GetMemberValue <float>(property, Attribute.MinFieldOrPropertyName);
            }

            if (!string.IsNullOrEmpty(Attribute.MaxFieldOrPropertyName))
            {
                maxV = GetMemberValue <float>(property, Attribute.MaxFieldOrPropertyName);
            }

            if (minV > maxV)
            {
                float temp = minV;
                minV = maxV;
                maxV = temp;
            }

            // GUI
            EditorGUI.BeginChangeCheck();
            if (Attribute.Slider)
            {
                switch (property.propertyType)
                {
                case SerializedPropertyType.Float:
                    EditorGUI.Slider(position, property, minV, maxV, label);
                    break;

                case SerializedPropertyType.Integer:
                    EditorGUI.IntSlider(position, property, (int)minV, (int)maxV, label);
                    break;
                }
            }
            else
            {
                EditorGUI.PropertyField(position, property, label);
            }

            if (EditorGUI.EndChangeCheck())
            {
                // Clamp
                switch (property.propertyType)
                {
                case SerializedPropertyType.Float:
                    if (DT._UseSnapValuePrecision && Attribute.Precision > -1)
                    {
                        property.floatValue = DTMath.SnapPrecision(property.floatValue, Attribute.Precision);
                    }
                    if (property.floatValue < minV || property.floatValue > maxV)
                    {
                        property.floatValue = Mathf.Clamp(property.floatValue, minV, maxV);
                    }
                    break;

                case SerializedPropertyType.Integer:
                    if (property.intValue < minV || property.intValue > maxV)
                    {
                        property.intValue = Mathf.Clamp(property.intValue, (int)minV, (int)maxV);
                    }
                    break;
                }
            }
            label.tooltip = "";
        }
示例#16
0
        protected CGData GetSplineData(CurvySpline spline, bool fullPath, CGDataRequestRasterization raster, CGDataRequestMetaCGOptions options)
        {
            if (spline == null || spline.Count == 0)
            {
                return(null);
            }
            List <ControlPointOption> optionsSegs = new List <ControlPointOption>();
            int   materialID = 0;
            float maxStep    = float.MaxValue;

            var data = (fullPath) ? new CGPath() : new CGShape();
            // calc start & end point (distance)
            float startDist;
            float endDist;

            getRange(spline, raster, out startDist, out endDist);

            float stepDist = (endDist - startDist) / (raster.Resolution - 1);

            data.Length = endDist - startDist;

            // initialize with start TF
            float tf      = spline.DistanceToTF(startDist);
            float startTF = tf;
            float endTF   = (endDist > spline.Length && spline.Closed) ? spline.DistanceToTF(endDist - spline.Length) + 1 : spline.DistanceToTF(endDist);

            // Set properties
            data.SourceIsManaged = IsManagedResource(spline);
            data.Closed          = spline.Closed;
            data.Seamless        = spline.Closed && raster.Length == 1;


            if (data.Length == 0)
            {
                return(data);
            }

            // Scan input spline and fetch a list of control points that provide special options (Hard Edge, MaterialID etc...)
            if (options)
            {
                optionsSegs = CGUtility.GetControlPointsWithOptions(options,
                                                                    spline,
                                                                    startDist,
                                                                    endDist,
                                                                    raster.Mode == CGDataRequestRasterization.ModeEnum.Optimized,
                                                                    out materialID,
                                                                    out maxStep);
            }

            // Setup vars
            List <SamplePointUData> extendedUVData = new List <SamplePointUData>();
            List <Vector3>          pos            = new List <Vector3>();
            List <float>            relF           = new List <float>();
            List <float>            sourceF        = new List <float>();
            List <Vector3>          tan            = new List <Vector3>();
            List <Vector3>          up             = new List <Vector3>();
            float      curDist = startDist;
            Vector3    curPos;
            float      curF;
            Vector3    curTan    = Vector3.zero;
            Vector3    curUp     = Vector3.zero;
            List <int> softEdges = new List <int>();



            int dead = 100000;

            raster.Resolution = Mathf.Max(raster.Resolution, 2);
            switch (raster.Mode)
            {
            case CGDataRequestRasterization.ModeEnum.Even:
                #region --- Even ---
                // we advance the spline using a fixed distance

                bool dupe = false;
                // we have at least one Material Group
                SamplePointsMaterialGroup grp = new SamplePointsMaterialGroup(materialID);
                // and at least one patch within that group
                SamplePointsPatch patch = new SamplePointsPatch(0);
                var clampMode           = (data.Closed) ? CurvyClamping.Loop : CurvyClamping.Clamp;

                while (curDist <= endDist && --dead > 0)
                {
                    tf     = spline.DistanceToTF(spline.ClampDistance(curDist, clampMode));
                    curPos = (UseCache) ? spline.InterpolateFast(tf) : spline.Interpolate(tf);
                    curF   = (curDist - startDist) / data.Length;//curDist / endDist;
                    if (Mathf.Approximately(1, curF))
                    {
                        curF = 1;
                    }

                    pos.Add(curPos);
                    relF.Add(curF);
                    sourceF.Add(curDist / spline.Length);
                    if (fullPath)     // add path values
                    {
                        curTan = (UseCache) ? spline.GetTangentFast(tf) : spline.GetTangent(tf, curPos);
                        curUp  = spline.GetOrientationUpFast(tf);
                        tan.Add(curTan);
                        up.Add(curUp);
                    }
                    if (dupe)     // HardEdge, IncludeCP, MaterialID changes etc. need an extra vertex
                    {
                        pos.Add(curPos);
                        relF.Add(curF);
                        sourceF.Add(curDist / spline.Length);
                        if (fullPath)
                        {
                            tan.Add(curTan);
                            up.Add(curUp);
                        }
                        dupe = false;
                    }
                    // Advance
                    curDist += stepDist;

                    // Check next Sample Point's options. If the next point would be past a CP with options
                    if (optionsSegs.Count > 0 && curDist >= optionsSegs[0].Distance)
                    {
                        if (optionsSegs[0].UVEdge || optionsSegs[0].UVShift)
                        {
                            extendedUVData.Add(new SamplePointUData(pos.Count, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                        }
                        // clamp point at CP and maybe duplicate the next sample point
                        curDist = optionsSegs[0].Distance;
                        dupe    = optionsSegs[0].HardEdge || optionsSegs[0].MaterialID != grp.MaterialID || (options.CheckExtendedUV && optionsSegs[0].UVEdge);
                        // end the current patch...
                        if (dupe)
                        {
                            patch.End = pos.Count;
                            grp.Patches.Add(patch);
                            // if MaterialID changes, we start a new MaterialGroup
                            if (grp.MaterialID != optionsSegs[0].MaterialID)
                            {
                                data.MaterialGroups.Add(grp);
                                grp = new SamplePointsMaterialGroup(optionsSegs[0].MaterialID);
                            }
                            // in any case we start a new patch
                            patch = new SamplePointsPatch(pos.Count + 1);
                            if (!optionsSegs[0].HardEdge)
                            {
                                softEdges.Add(pos.Count + 1);
                            }
                            // Extended UV
                            if (optionsSegs[0].UVEdge || optionsSegs[0].UVShift)
                            {
                                extendedUVData.Add(new SamplePointUData(pos.Count + 1, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                            }
                        }
                        // and remove the CP from the options
                        optionsSegs.RemoveAt(0);
                    }

                    // Ensure last sample point position is at the desired end distance
                    if (curDist > endDist && curF < 1)     // next loop curF will be 1
                    {
                        curDist = endDist;
                    }
                }
                if (dead <= 0)
                {
                    Debug.LogError("[Curvy] He's dead, Jim! Deadloop in SplineInputModuleBase.GetSplineData (Even)! Please send a bug report!");
                }
                // store the last open patch
                patch.End = pos.Count - 1;
                grp.Patches.Add(patch);
                // ExplicitU on last Vertex?
                //if (optionsSegs.Count > 0 && optionsSegs[0].UVShift)
                //    extendedUVData.Add(new SamplePointUData(pos.Count - 1, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                // if path is closed and no hard edges involved, we need to smooth first normal
                if (data.Closed && !spline[0].GetMetadata <MetaCGOptions>(true).HardEdge)
                {
                    softEdges.Add(0);
                }
                data.MaterialGroups.Add(grp);
                // fill data
                data.SourceF  = sourceF.ToArray();
                data.F        = relF.ToArray();
                data.Position = pos.ToArray();
                if (fullPath)
                {
                    ((CGPath)data).Direction = tan.ToArray();
                    data.Normal = up.ToArray();
                }
                #endregion
                break;

            case CGDataRequestRasterization.ModeEnum.Optimized:
                #region --- Optimized ---
                dupe = false;
                // we have at least one Material Group
                grp = new SamplePointsMaterialGroup(materialID);
                // and at least one patch within that group
                patch = new SamplePointsPatch(0);
                float stepSizeTF = stepDist / spline.Length;

                float maxAngle = raster.AngleThreshold;
                float stopAt;
                bool  atStopPoint;
                curPos = spline.Interpolate(tf);
                curTan = spline.GetTangent(tf, curPos);

                var addPoint = new System.Action <float>((float f) =>
                {
                    sourceF.Add(curDist / spline.Length);
                    pos.Add(curPos);
                    relF.Add((curDist - startDist) / data.Length);
                    if (fullPath)
                    {
                        tan.Add(curTan);
                        up.Add(spline.GetOrientationUpFast(f));
                    }
                });

                while (tf < endTF && dead-- > 0)
                {
                    addPoint(tf % 1);

                    // Advance
                    stopAt = (optionsSegs.Count > 0) ? optionsSegs[0].TF : endTF;

                    atStopPoint = spline.MoveByAngleExtINTERNAL(ref tf, Generator.MinDistance, maxStep, maxAngle, out curPos, out curTan, out stepDist, stopAt, data.Closed, stepSizeTF);
                    curDist    += stepDist;
                    if (Mathf.Approximately(tf, endTF) || tf > endTF)
                    {
                        curDist = endDist;
                        endTF   = (data.Closed) ? DTMath.Repeat(endTF, 1) : Mathf.Clamp01(endTF);
                        curPos  = spline.Interpolate(endTF);
                        if (fullPath)
                        {
                            curTan = spline.GetTangent(endTF, curPos);
                        }
                        addPoint(endTF);
                        break;
                    }
                    if (atStopPoint)
                    {
                        if (optionsSegs.Count > 0)
                        {
                            if (optionsSegs[0].UVEdge || optionsSegs[0].UVShift)
                            {
                                extendedUVData.Add(new SamplePointUData(pos.Count, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                            }
                            // clamp point at CP and maybe duplicate the next sample point
                            curDist = optionsSegs[0].Distance;
                            maxStep = (optionsSegs[0].MaxStepDistance);
                            dupe    = optionsSegs[0].HardEdge || optionsSegs[0].MaterialID != grp.MaterialID || (options.CheckExtendedUV && optionsSegs[0].UVEdge);
                            if (dupe)
                            {
                                // end the current patch...
                                patch.End = pos.Count;
                                grp.Patches.Add(patch);
                                // if MaterialID changes, we start a new MaterialGroup
                                if (grp.MaterialID != optionsSegs[0].MaterialID)
                                {
                                    data.MaterialGroups.Add(grp);
                                    grp = new SamplePointsMaterialGroup(optionsSegs[0].MaterialID);
                                }


                                // in any case we start a new patch
                                patch = new SamplePointsPatch(pos.Count + 1);
                                if (!optionsSegs[0].HardEdge)
                                {
                                    softEdges.Add(pos.Count + 1);
                                }
                                // Extended UV
                                if (optionsSegs[0].UVEdge || optionsSegs[0].UVShift)
                                {
                                    extendedUVData.Add(new SamplePointUData(pos.Count + 1, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                                }
                                addPoint(tf);
                            }
                            // and remove the CP from the options
                            optionsSegs.RemoveAt(0);
                        }
                        else
                        {
                            addPoint(tf);
                            break;
                        }
                    }
                }
                if (dead <= 0)
                {
                    Debug.LogError("[Curvy] He's dead, Jim! Deadloop in SplineInputModuleBase.GetSplineData (Optimized)! Please send a bug report!");
                }
                // store the last open patch
                patch.End = pos.Count - 1;
                grp.Patches.Add(patch);
                // ExplicitU on last Vertex?
                if (optionsSegs.Count > 0 && optionsSegs[0].UVShift)
                {
                    extendedUVData.Add(new SamplePointUData(pos.Count - 1, optionsSegs[0].UVEdge, optionsSegs[0].FirstU, optionsSegs[0].SecondU));
                }
                // if path is closed and no hard edges involved, we need to smooth first normal
                if (data.Closed && !spline[0].GetMetadata <MetaCGOptions>(true).HardEdge)
                {
                    softEdges.Add(0);
                }
                data.MaterialGroups.Add(grp);
                // fill data
                data.SourceF  = sourceF.ToArray();
                data.F        = relF.ToArray();
                data.Position = pos.ToArray();
                data.Bounds   = spline.Bounds;

                if (fullPath)
                {
                    ((CGPath)data).Direction = tan.ToArray();
                    data.Normal = up.ToArray();
                }
                #endregion
                break;
            }
            data.Map = (float[])data.F.Clone();
            if (!fullPath)
            {
                data.RecalculateNormals(softEdges);
                if (options && options.CheckExtendedUV)
                {
                    CalculateExtendedUV(spline, startTF, endTF, extendedUVData, data);
                }
            }
            return(data);
        }
示例#17
0
 float getUnrangedCross(float f)
 {
     return(DTMath.MapValue(-0.5f, 0.5f, f, CrossFrom, CrossTo));
 }
示例#18
0
 float getRangedCross(float f)
 {
     return(DTMath.MapValue(CrossFrom, CrossTo, f, -0.5f, 0.5f));
 }
示例#19
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            base.OnGUI(position, property, label);

            lBound = Attribute.Min;
            uBound = Attribute.Max;
            // Get maxV serialized
            var path = property.Path();

            path[path.Length - 1] = Attribute.MaxValueField;
            var pMaxV = property.serializedObject.FindProperty(string.Join(".", path));

            if (!string.IsNullOrEmpty(Attribute.MinBoundFieldOrPropertyName))
            {
                lBound = GetMemberValue <float>(property, Attribute.MinBoundFieldOrPropertyName);
            }

            if (!string.IsNullOrEmpty(Attribute.MaxBoundFieldOrPropertyName))
            {
                uBound = GetMemberValue <float>(property, Attribute.MaxBoundFieldOrPropertyName);
            }

            if (lBound > uBound)
            {
                float temp = lBound;
                lBound = uBound;
                uBound = temp;
            }

            float minV = 0;
            float maxV = 0;

            // GUI
            EditorGUI.BeginChangeCheck();


            switch (property.propertyType)
            {
            case SerializedPropertyType.Float:
                minV = property.floatValue;
                maxV = pMaxV.floatValue;
                EditorGUI.MinMaxSlider(label, position, ref minV, ref maxV, lBound, uBound);
                break;

            case SerializedPropertyType.Integer:
                minV = property.intValue;
                maxV = pMaxV.intValue;
                EditorGUI.MinMaxSlider(label, position, ref minV, ref maxV, lBound, uBound);
                break;
            }

            if (EditorGUI.EndChangeCheck())
            {
                // Clamp
                switch (property.propertyType)
                {
                case SerializedPropertyType.Float:
                    if (DT._UseSnapValuePrecision && Attribute.Precision > -1)
                    {
                        property.floatValue = Mathf.Max(lBound, DTMath.SnapPrecision(minV, Attribute.Precision));
                    }
                    pMaxV.floatValue = Mathf.Min(uBound, DTMath.SnapPrecision(maxV, Attribute.Precision));
                    break;

                case SerializedPropertyType.Integer:
                    property.intValue = (int)minV;
                    pMaxV.intValue    = (int)maxV;
                    break;
                }
            }
            label.tooltip = "";
        }