예제 #1
0
        protected virtual void update_value(double newValue, bool bSendEvent)
        {
            double prev = current_value;

            current_value = newValue;

            snapped_value = current_value;

            if (TickSnapMode != TickSnapModes.NoSnapping && TickCount > 0)
            {
                if (TickSnapMode == TickSnapModes.AlwaysSnapToNearest)
                {
                    double fTickSpan = 1.0 / (TickCount - 1);
                    double fSnapped  = Snapping.SnapToIncrement(snapped_value, fTickSpan);
                    fSnapped      = MathUtil.Clamp(fSnapped, 0, 1);
                    snapped_value = fSnapped;
                }
                else
                {
                    double fTickSpan = 1.0 / (TickCount - 1);
                    double fSnapped  = Snapping.SnapToIncrement(snapped_value, fTickSpan);
                    if (Math.Abs(fSnapped - snapped_value) < TickSnapThreshold)
                    {
                        snapped_value = fSnapped;
                    }
                }
            }

            update_handle_position();

            if (bSendEvent)
            {
                FUtil.SafeSendEvent(OnValueChanged, this, prev, snapped_value);
            }
        }
예제 #2
0
        protected virtual void update_value(double newValue, bool bSendEvent)
        {
            double prev = current_value;

            current_value = newValue;

            snapped_value = current_value;

            if (EnableSnapToTicks && TickCount > 0)
            {
                double fTickSpan = 1.0 / (TickCount - 1);
                double fSnapped  = Snapping.SnapToIncrement(snapped_value, fTickSpan);
                fSnapped = MathUtil.Clamp(fSnapped, 0, 1);
                // [RMS] only snap when close enough to tick?
                //double fSnapT = fTickSpan * 0.25;
                //if (Math.Abs(fSnapped - snapped_value) < fSnapT)
                snapped_value = fSnapped;
            }

            update_handle_position();

            if (bSendEvent)
            {
                FUtil.SafeSendEvent(OnValueChanged, this, prev, snapped_value);
            }
        }
예제 #3
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with plane perpendicular to rotateAxisW
            Vector3f planeHitW = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle
            Vector3f dv = planeHitW - rotateFrameW.Origin;
            int      iX = (nRotationAxis + 1) % 3;
            int      iY = (nRotationAxis + 2) % 3;
            float    fX = Vector3.Dot(dv, rotateFrameW.GetAxis(iX));
            float    fY = Vector3.Dot(dv, rotateFrameW.GetAxis(iY));

            float fNewAngle = (float)Math.Atan2(fY, fX);

            if (AbsoluteAngleConstraintF != null)
            {
                fNewAngle = AbsoluteAngleConstraintF(rotateFrameL, nRotationAxis, fNewAngle);
            }

            float fDeltaAngle = (fNewAngle - fRotateStartAngle);

            if (DeltaAngleConstraintF != null)
            {
                fDeltaAngle = DeltaAngleConstraintF(rotateFrameL, nRotationAxis, fDeltaAngle);
            }


            bool on_snap = false;

            if (EnableSnapping)
            {
                double dist = (planeHitW - rotateFrameW.Origin).Length;
                on_snap = Math.Abs(dist - gizmoRadiusW) < gizmoRadiusW * 0.15f;
                if (on_snap)
                {
                    fDeltaAngle = (float)Snapping.SnapToIncrement(fDeltaAngle, SnapIncrementDeg * MathUtil.Deg2Radf);
                }
                enable_snap_indicator(true);
                update_snap_indicator(-fDeltaAngle, on_snap);
            }

            // construct new frame for target that is rotated around axis
            Vector3f    rotateAxisL = rotateFrameL.GetAxis(nRotationAxis);
            Quaternionf q           = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL);
            Frame3f     newFrame    = rotateFrameL;

            newFrame.Rotation = q * newFrame.Rotation;                          // order matters here!

            // update target
            target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords);

            if (EnableSnapping)
            {
                update_circle_indicator(on_snap);
            }

            return(true);
        }
예제 #4
0
        void Update()
        {
            if (Context == null)
            {
                return;
            }

            // [TODO] need to consider camera distane here?


            Frame3f sceneFrameW = Context.Scene.SceneFrame;

            if (sceneFrameW.EpsilonEqual(lastSceneFrameW, 0.001f))
            {
                return;
            }
            lastSceneFrameW = sceneFrameW;

            if (AdjustShadowDistance)
            {
                // use vertical height of light to figure out appropriate shadow distance.
                // distance changes if we scale scene, and if we don't do this, shadow
                // map res gets very blurry.
                Vector3f thisW   = lights[0].transform.position;
                float    fHeight =
                    Vector3f.Dot((thisW - sceneFrameW.Origin), sceneFrameW.Y);
                float fShadowDist = fHeight * 1.5f;

                // lights need to be in-range
                if (fShadowDist < LightDistance)
                {
                    fShadowDist = LightDistance * 1.5f;
                }

                // need to be a multiple of eye distance
                float fEyeDist = sceneFrameW.Origin.Distance(Camera.main.transform.position);
                fShadowDist = Mathf.Max(fShadowDist, 1.5f * fEyeDist);

                int nShadowDist = (int)Snapping.SnapToIncrement(fShadowDist, 50);

                if (cur_shadow_dist != nShadowDist)
                {
                    QualitySettings.shadowDistance = nShadowDist;
                    cur_shadow_dist = nShadowDist;
                }
            }
        }
예제 #5
0
        /// <summary>
        /// shoot parallel set of 2D rays at input polygon, and find portions
        /// of rays that are inside the polygon (we call these "spans"). These
        /// are inserted into the polygon, resulting in a non-manifold 2D graph.
        /// </summary>
        protected DGraph2 ComputeSpanGraph(GeneralPolygon2d poly)
        {
            double   angleRad = AngleDeg * MathUtil.Deg2Rad;
            Vector2d dir      = new Vector2d(Math.Cos(angleRad), Math.Sin(angleRad));

            // compute projection span along axis
            Vector2d   axis         = dir.Perp;
            Interval1d axisInterval = Interval1d.Empty;
            Interval1d dirInterval  = Interval1d.Empty;

            foreach (Vector2d v in poly.Outer.Vertices)
            {
                dirInterval.Contain(v.Dot(dir));
                axisInterval.Contain(v.Dot(axis));
            }
            // [TODO] also check holes? or assume they are contained? should be
            //  classified as outside by winding check anyway...

            // construct interval we will step along to shoot parallel rays
            dirInterval.a -= 10 * ToolWidth;
            dirInterval.b += 10 * ToolWidth;
            double extent = dirInterval.Length;

            // nudge in a very tiny amount so that if poly is a rectangle, first
            // line is not directly on boundary
            axisInterval.a += ToolWidth * 0.01;
            axisInterval.b -= ToolWidth * 0.01;
            axisInterval.a -= PathShift;
            if (axisInterval.b < axisInterval.a)
            {
                return(null);     // [RMS] is this right? I guess so. interval is too small to fill?
            }
            // If we are doing a dense fill, we want to pack as tightly as possible.
            // But if we are doing a sparse fill, then we want layers to stack.
            // So in that case, snap the interval to increments of the spacing
            //  (does this work?)
            bool bIsSparse = (PathSpacing > ToolWidth * 2);

            if (bIsSparse)
            {
                // snap axisInterval.a to grid so that layers are aligned
                double snapped_a = Snapping.SnapToIncrement(axisInterval.a, PathSpacing);
                if (snapped_a > axisInterval.a)
                {
                    snapped_a -= PathSpacing;
                }
                axisInterval.a = snapped_a;
            }

            Vector2d startCorner = axisInterval.a * axis + dirInterval.a * dir;
            double   range       = axisInterval.Length;
            int      N           = (int)(range / PathSpacing) + 1;

            // nudge spacing so that we exactly fill the available space
            double use_spacing = PathSpacing;

            if (bIsSparse == false && AdjustSpacingToMaximizeFill)
            {
                int nn = (int)(range / use_spacing);
                use_spacing = range / (double)nn;
                N           = (int)(range / use_spacing) + 1;
            }

            DGraph2 graph = new DGraph2();

            graph.AppendPolygon(poly);
            GraphSplitter2d splitter = new GraphSplitter2d(graph);

            splitter.InsideTestF = poly.Contains;

            // insert sequential rays
            for (int ti = 0; ti <= N; ++ti)
            {
                Vector2d o   = startCorner + (double)ti * use_spacing * axis;
                Line2d   ray = new Line2d(o, dir);
                splitter.InsertLine(ray, ti);
            }

            return(graph);
        }