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); } }
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)); }
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 }); }
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; } }
// 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)); }
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)); }
/// <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)); } }
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 = ""; }
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; } }
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; } }
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); } }
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 = ""; }
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); }
float getUnrangedCross(float f) { return(DTMath.MapValue(-0.5f, 0.5f, f, CrossFrom, CrossTo)); }
float getRangedCross(float f) { return(DTMath.MapValue(CrossFrom, CrossTo, f, -0.5f, 0.5f)); }
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 = ""; }