예제 #1
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with world-space translation plane
            Vector3f planeHit = translateFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, nTranslationPlaneNormal);
            int      e0       = (nTranslationPlaneNormal + 1) % 3;
            int      e1       = (nTranslationPlaneNormal + 2) % 3;

            // construct delta in world space and project into frame coordinates
            Vector3f delta = (planeHit - vInitialHitPos);

            delta *= TranslationScaleF();
            float dx = Vector3f.Dot(delta, translateFrameW.GetAxis(e0));
            float dy = Vector3f.Dot(delta, translateFrameW.GetAxis(e1));

            if (DeltaDistanceConstraintF != null)
            {
                dx = DeltaDistanceConstraintF(translateFrameL, e0, dx);
                dy = DeltaDistanceConstraintF(translateFrameL, e1, dy);
            }

            // construct new local frame translated along plane axes
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += dx * translateFrameL.GetAxis(e0) + dy * translateFrameL.GetAxis(e1);

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

            return(true);
        }
예제 #2
0
        public override bool BeginCapture(ITransformable target, Ray3f worldRay, UIRayHit hit)
        {
            // save local and world frames
            rotateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords);
            rotateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords);
            rotateAxisW  = rotateFrameW.GetAxis(nRotationAxis);

            // save angle of hitpos in 2D plane perp to rotateAxis, so we can find delta-angle later
            Vector3f vWorldHitPos = hit.hitPos;
            Vector3f dv           = vWorldHitPos - rotateFrameW.Origin;
            int      iX           = (nRotationAxis + 1) % 3;
            int      iY           = (nRotationAxis + 2) % 3;
            float    fX           = Vector3f.Dot(dv, rotateFrameW.GetAxis(iX));
            float    fY           = Vector3f.Dot(dv, rotateFrameW.GetAxis(iY));

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

            // construct plane we will ray-intersect with in UpdateCapture()
            raycastFrame = new Frame3f(vWorldHitPos, rotateAxisW);

            if (EnableSnapping)
            {
                enable_circle_indicator(true);
            }

            return(true);
        }
예제 #3
0
        public override bool UpdateCapture(ITransformable target, Ray worldRay)
        {
            // ray-hit with plane perpendicular to rotateAxisW
            Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.origin, worldRay.direction, 2);

            // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle
            Vector3f dv          = planeHit - 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);
            float    fDeltaAngle = (fNewAngle - fRotateStartAngle);

            // 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);

            return(true);
        }
예제 #4
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);
        }
예제 #5
0
 public Circle3d(Frame3f frame, double radius, int nNormalAxis = 1)
 {
     IsReversed = false;
     Center     = frame.Origin;
     Normal     = frame.GetAxis(nNormalAxis);
     PlaneX     = frame.GetAxis((nNormalAxis + 1) % 3);
     PlaneY     = frame.GetAxis((nNormalAxis + 2) % 3);
     Radius     = radius;
 }
예제 #6
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with plane that contains translation axis
            Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // figure out new T-value along axis, then our translation update is delta-t
            float fNewT   = Distance.ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit);
            float fDeltaT = (fNewT - fTranslateStartT);

            fDeltaT *= TranslationScaleF();
            if (DeltaDistanceConstraintF != null)
            {
                fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT);
            }

            // construct new frame translated along axis (in local space)
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis);

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

            return(true);
        }
예제 #7
0
        public override bool CheckVisibility(ref Frame3f curFrameW, ref Vector3d eyePosW)
        {
            Vector3d axis   = curFrameW.GetAxis(nRotationAxis);
            Vector3d eyevec = (eyePosW - curFrameW.Origin).Normalized;
            double   dot    = axis.Dot(eyevec);

            return(Math.Abs(dot) > VisibilityThresh);
        }
예제 #8
0
        public override bool CheckVisibility(ref Frame3f curFrameW, ref Vector3d eyePosW)
        {
            Vector3d axis   = curFrameW.GetAxis(nTranslationAxis);
            Vector3d eyevec = (eyePosW - curFrameW.Origin).Normalized;
            double   dot    = axis.Dot(eyevec);

            return(CosVisibilityRange.Contains(dot));
        }
예제 #9
0
        void update_position(AnyRayHit hit)
        {
            int nNormalAxis = 1;
            int nUpAxis     = 2;

            // as we drag object we will align Y with hit surface normal, but
            // we also want to constrain rotation so it is stable. Hence, we are
            // going to use world or local frame of target object to stabilize
            // rotation around normal.
            Frame3f hitF       = TargetScene.SceneFrame;
            Vector3 targetAxis = hitF.GetAxis(1);

            if (hit.hitSO is SceneObject)
            {
                hitF = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
            }
            bool bUseLocal =
                (TargetScene.Context.TransformManager.ActiveFrameType == FrameType.LocalFrame);

            if (bUseLocal && hit.hitSO is SceneObject)
            {
                hitF       = (hit.hitSO as SceneObject).GetLocalFrame(CoordSpace.WorldCoords);
                targetAxis = hitF.GetAxis(1);
            }
            // if normal is parallel to target, this would become unstable, so use another axis
            if (Vector3.Dot(targetAxis, hit.hitNormal) > 0.99f)
            {
                targetAxis = hitF.GetAxis(0);
            }

            if (lastHitObject == null || hit.hitSO != lastHitObject)
            {
                lastHitF = new Frame3f(hit.hitPos, hit.hitNormal, nNormalAxis);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            else
            {
                lastHitF.Origin = hit.hitPos;
                lastHitF.AlignAxis(nNormalAxis, hit.hitNormal);
                lastHitF.ConstrainedAlignAxis(nUpAxis, targetAxis, lastHitF.GetAxis(nNormalAxis));
            }
            lastHitObject = hit.hitSO;
        }
예제 #10
0
        public void BeginDraw_Ray(Ray3f ray, AnyRayHit rayHit, int nStep)
        {
            CreateNewPrimitive();

            Vector3f hitPos = rayHit.hitPos;

            // try snap points
            SnapResult snap = Snaps.FindHitSnapPoint(ray);

            if (snap != null)
            {
                Frame3f snapF = scene.ToWorldFrame(snap.FrameS);
                hitPos = snapF.Origin;
            }

            Frame3f sceneW = scene.SceneFrame;

            if (rayHit.hitSO == null)
            {
                primStartW        = sceneW;
                primStartW.Origin = hitPos;
            }
            else
            {
                if (scene.Context.TransformManager.ActiveFrameType == FrameType.WorldFrame)
                {
                    primStartW        = sceneW;
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PivotSO)
                {
                    primStartW        = (rayHit.hitSO as PivotSO).GetLocalFrame(CoordSpace.WorldCoords);
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PrimitiveSO)
                {
                    // align with object frame as much as possible, given that we still want
                    //  to use hit normal...
                    Frame3f objFrame  = (rayHit.hitSO as PrimitiveSO).GetLocalFrame(CoordSpace.WorldCoords);
                    int     nBestAxis = MathUtil.MostParallelAxis(objFrame, rayHit.hitNormal);
                    int     nPerp     = (nBestAxis + 1) % 3;
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(0, objFrame.GetAxis(nPerp), primStartW.Y);
                }
                else
                {
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(1, sceneW.Y, primStartW.Y);
                }
            }
            primitive.Frame = primStartW;
            primStartS      = scene.ToSceneFrame(primStartW);
        }
예제 #11
0
        public static void test_normals()
        {
            // check that frames are ok
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            foreach (int tid in mesh.TriangleIndices())
            {
                Vector3f n = (Vector3f)mesh.GetTriNormal(tid);
                for (int j = 0; j < 3; ++j)
                {
                    Frame3f f = mesh.GetTriFrame(tid, j);
                    if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef)
                    {
                        throw new Exception("argh");
                    }
                    Vector3f fn = f.Z;
                    if (fn.Dot(n) < 0.99)
                    {
                        throw new Exception("shit");
                    }
                }
            }

            MeshNormals.QuickCompute(mesh);

            foreach (int vid in mesh.VertexIndices())
            {
                Vector3f n = mesh.GetVertexNormal(vid);
                for (int j = 1; j <= 2; ++j)
                {
                    Frame3f  f  = mesh.GetVertexFrame(vid, (j == 1) ? true : false);
                    Vector3f fn = f.GetAxis(j);
                    if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef ||
                        Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef)
                    {
                        throw new Exception("argh");
                    }
                    if (fn.Dot(n) < 0.99)
                    {
                        throw new Exception("shit2");
                    }
                }
            }
        }
예제 #12
0
        public bool Compute()
        {
            DMesh3 copy = new DMesh3(Mesh);

            //Frame3f PlaneO = SceneTransforms.SceneToObject(TargetSO, PlaneS);
            Vector3f PlaneNormal = Plane.GetAxis(nPlaneAxis);

            MeshPlaneCut cut = new MeshPlaneCut(copy, Plane.Origin, PlaneNormal);

            cut.Cut();

            Loops = new DCurve3[cut.CutLoops.Count];
            for (int li = 0; li < cut.CutLoops.Count; ++li)
            {
                EdgeLoop edgeloop = cut.CutLoops[li];
                DCurve3  loop     = MeshUtil.ExtractLoopV(copy, edgeloop.Vertices);

                // [TODO] collapse degenerate points...

                if (NormalOffset > 0)
                {
                    for (int i = 0; i < loop.VertexCount; ++i)
                    {
                        Vector3f n = Vector3f.Zero;
                        if (copy.HasVertexNormals)
                        {
                            n = (Vector3f)copy.GetVertexNormal(edgeloop.Vertices[i]);
                        }
                        else
                        {
                            n = (Vector3f)MeshNormals.QuickCompute(Mesh, edgeloop.Vertices[i]);
                        }

                        n -= n.Dot(PlaneNormal) * PlaneNormal;
                        n.Normalize();
                        loop[i] += NormalOffset * (Vector3d)n;
                    }
                }

                Loops[li] = loop;
            }

            return(Loops.Length > 0);
        }
예제 #13
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // ray-hit with world-space translation plane
            Vector3f planeHit = cameraFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2);

            // construct delta in world space and project into frame coordinates
            Vector3f delta = (planeHit - vInitialHitPos);

            delta *= ScaleMultiplierF();
            //float dx = Vector3f.Dot(delta, cameraFrameW.GetAxis(0));
            float dy          = Vector3f.Dot(delta, cameraFrameW.GetAxis(1));
            float scaleDelta  = 1.0f + dy;
            float scaleFactor = Mathf.Clamp(scaleDelta, 0.1f, 1000.0f);

            // update target
            target.SetLocalScale(startScale * scaleFactor);

            return(true);
        }
예제 #14
0
        public bool BeginCapture(MMDModel target, HitResult hit)
        {
            // save local and world frames
            translateFrameL = target.GetGameObjectFrame(CoordSpace.ObjectCoords);
            translateFrameW = target.GetGameObjectFrame(CoordSpace.WorldCoords);
            translateAxisW  = translateFrameW.GetAxis(nTranslationAxis);

            // save t-value of closest point on translation axis, so we can find delta-t
            Vector3 vWorldHitPos = hit.HitPosition;

            fTranslateStartT = ClosestPointOnLineT(
                translateFrameW.Origin, translateAxisW, vWorldHitPos);

            // construct plane we will ray-intersect with in UpdateCapture()
            Vector3 makeUp       = Vector3.Cross(Platform.Program.Camera.Forward, translateAxisW).GetNormalized( );
            Vector3 vPlaneNormal = Vector3.Cross(makeUp, translateAxisW).GetNormalized( );

            raycastFrame = new Frame3f(vWorldHitPos, vPlaneNormal);

            return(true);
        }
        float fTranslateStartT;                 // start T-value along translateAxisW

        public override bool BeginCapture(ITransformable target, Ray3f worldRay, UIRayHit hit)
        {
            // save local and world frames
            translateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords);
            translateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords);
            translateAxisW  = translateFrameW.GetAxis(nTranslationAxis);

            // save t-value of closest point on translation axis, so we can find delta-t
            Vector3f vWorldHitPos = hit.hitPos;

            fTranslateStartT = Distance.ClosestPointOnLineT(
                translateFrameW.Origin, translateAxisW, vWorldHitPos);

            // construct plane we will ray-intersect with in UpdateCapture()
            Vector3f makeUp       = Vector3f.Cross(Camera.main.transform.forward, translateAxisW).Normalized;
            Vector3f vPlaneNormal = Vector3f.Cross(makeUp, translateAxisW).Normalized;

            raycastFrame = new Frame3f(vWorldHitPos, vPlaneNormal);

            return(true);
        }
예제 #16
0
        public bool UpdateCapture(MMDModel target, RayWrap worldRay)
        {
            int normalAxis = 2;

            if (nTranslationAxis == 2)
            {
                normalAxis = 1;
            }
            // ray-hit with plane that contains translation axis
            var planeHitOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis);

            if (!planeHitOpt.HasValue)
            {
                return(false);
            }
            Vector3 planeHit = planeHitOpt.Value;

            // figure out new T-value along axis, then our translation update is delta-t
            float fNewT   = ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit);
            float fDeltaT = (fNewT - fTranslateStartT);

            fDeltaT *= TranslationScaleF( );
            if (DeltaDistanceConstraintF != null)
            {
                fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT);
            }

            // construct new frame translated along axis (in local space)
            Frame3f newFrame = translateFrameL;

            newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis);

            // update target
            //target.SetLocalFrame (newFrame, CoordSpace.ObjectCoords);
            target.Position = newFrame.Origin;
            return(true);
        }
예제 #17
0
 public Cylinder3d(Frame3f frame, double radius, double height, int nNormalAxis = 1)
 {
     Axis   = new Line3d(frame.Origin, frame.GetAxis(nNormalAxis));
     Radius = radius;
     Height = height;
 }
예제 #18
0
        public bool UpdateCapture(MMDModel target, RayWrap worldRay)
        {
            int normalAxis = 2;

            if (nRotationAxis == 2)
            {
                normalAxis = 1;
            }

            // ray-hit with plane perpendicular to rotateAxisW
            var planeHitWOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis);

            if (!planeHitWOpt.HasValue)
            {
                return(false);
            }
            var planeHitW = planeHitWOpt.Value;

            // 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));

            Util.DebugWrite("dv " + dv.ToString( ));
            Util.DebugWrite("planeHitW " + planeHitW.ToString( ));
            Util.DebugWrite("rotateFrameW " + rotateFrameW.Origin.ToString( ));

            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);

            Util.DebugWrite("fDeltaAngle " + fDeltaAngle);

            fDeltaAngle *= 0.03f;

            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);
            }

            // 軸を中心に回るターゲットのための新しいフレームを作る
            Vector3f   rotateAxisL = rotateFrameL.GetAxis(nRotationAxis);
            Quaternion q           = Quaternion.RotationAxis(rotateAxisL, fDeltaAngle.Deg());
            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);
        }