示例#1
0
        // see description of function by same name in Editing3dPos
        public void InteractiveHandleEdit(Axis axis, int mousex, int mousey)
        {
            Entity entity = selectionmodel.GetFirstSelectedEntity();

            if (entity == null)
            {
                return;
            }

            Vector3 ourpos = null;
            Rot     ourrot = null;

            if (camera.bRoamingCameraEnabled)
            {
                ourpos = camera.RoamingCameraPos;
                ourrot = camera.RoamingCameraRot;
            }
            else
            {
                Avatar ouravatar = MetaverseClient.GetInstance().myavatar;
                if (ouravatar != null)
                {
                    ourpos = ouravatar.pos;
                    ourrot = ouravatar.rot;
                }
                else
                {
                    return;
                }
            }

            // what is the scaling from screen pixels to world pixels, at the distance of the object from us
            // obviously this is only approximate for nearish objects, which is most objects...
            double fDistanceFromUsToObject = (entity.pos - ourpos).Det();
            double fScalingFromPosToScreen = graphics.GetScalingFrom3DToScreen(fDistanceFromUsToObject);

            // Create a 3d vector represeting our mouse drag, in avatar coordinates, in screen pixels
            Vector3 mousemovescreenaxes = new Vector3(0,
                                                      -(double)(mousex - editing3d.iDragStartX),
                                                      -(double)(mousey - editing3d.iDragStartY));

            // transform into a 3d vector, in avatar coordinates, in "world units"
            Vector3 mousemoveavaxes = mousemovescreenaxes * (1 / fScalingFromPosToScreen);

            // Get handleaxis in avatar axes:
            Vector3 handleaxisentityaxes = axis.ToVector();

            handleaxisentityaxes.x = Math.Abs(handleaxisentityaxes.x);
            handleaxisentityaxes.y = Math.Abs(handleaxisentityaxes.y);
            handleaxisentityaxes.z = Math.Abs(handleaxisentityaxes.z);
            Vector3 handleaxisworldaxes = handleaxisentityaxes * entity.rot.Inverse();
            Vector3 handleaxisavaxes    = handleaxisworldaxes * ourrot;

            // we project our handleaxis onto the screen, then project our mousemove onto this
            // to get mousemove2 (see function description for more info)
            Vector3 handleaxisprojectedtoscreen = new Vector3(0, handleaxisavaxes.y, handleaxisavaxes.z);
            Vector3 mousemove2 = handleaxisprojectedtoscreen.Unit() * Vector3.DotProduct(mousemoveavaxes, handleaxisprojectedtoscreen.Unit());

            // now we are going to find the ratio between our mousemovement size and how far we need to move along the handleaxis
            double entitymovetomousemoveratio = Vector3.DotProduct(handleaxisavaxes.Unit(), mousemove2.Unit());

            // This gives us the ratio between mouse move distance and entity move distance, now we can calculate the change in entity scale:

            if (Math.Abs(entitymovetomousemoveratio) < 0.05)    // prevent infinite scaling..
            {
                return;
            }
            Vector3 scalechange = (mousemove2.Det() / entitymovetomousemoveratio) * handleaxisentityaxes;
            Vector3 newscale    = null;

            if (axis.IsPositiveAxis)
            {
                newscale = editing3d.startscale + scalechange;
            }
            else
            {
                newscale = editing3d.startscale - scalechange;
            }
            newscale.x = Math.Max(0.05, newscale.x);
            newscale.y = Math.Max(0.05, newscale.y);
            newscale.z = Math.Max(0.05, newscale.z);

            Vector3 finalscalechange          = newscale - editing3d.startscale;
            Vector3 finalscalechangeworldaxes = finalscalechange * entity.rot.Inverse();

            if (axis.IsPositiveAxis)
            {
                entity.pos = editing3d.startpos + (finalscalechangeworldaxes) / 2;
            }
            else
            {
                entity.pos = editing3d.startpos - (finalscalechangeworldaxes) / 2;
            }

            // scale is defined in entity local axes, so no need to transform into world axes
            entity.scale = newscale;
            MetaverseClient.GetInstance().worldstorage.OnModifyEntity(entity);
        }
示例#2
0
        double GetRotationAngleForEntityAndMouse(Vector3 EntityVector3, Rot EntityRot, Axis axis, int mousex, int mousey)
        {
            double fRotationAngle = 0;

            bool bRotAngleGot = false;

            Vector3 OurPos;
            Rot     OurRot;

            if (camera.bRoamingCameraEnabled)
            {
                OurPos = camera.RoamingCameraPos;
                OurRot = camera.RoamingCameraRot;
            }
            else
            {
                Avatar ouravatar = MetaverseClient.GetInstance().myavatar;
                if (ouravatar != null)
                {
                    OurPos = ouravatar.pos;
                    OurRot = ouravatar.rot;
                }
                else
                {
                    return(0);
                }
            }
            Rot rInverseOurRot = OurRot.Inverse();

            double fDistanceFromUsToEntity = (EntityVector3 - OurPos).Det();
            double fScalingFromPosToScreen = graphics.GetScalingFrom3DToScreen(fDistanceFromUsToEntity);

            Vector3 ScreenEntityPos = graphics.GetScreenPos(OurPos, OurRot, EntityVector3);
            Vector3 ScreenMousePos  = new Vector3(
                0,
                RendererFactory.GetInstance().WindowWidth - mousex,
                RendererFactory.GetInstance().WindowHeight - mousey);

            // mousepoint is a point on the mouseray into the screen, with x = entity.pos.x
            Vector3 ScreenVectorEntityToMousePoint       = ScreenMousePos - ScreenEntityPos;
            Vector3 VectorEntityToMousePointObserverAxes = ScreenVectorEntityToMousePoint * (1.0f / fScalingFromPosToScreen);

            //Test.Debug(  " screenobjectpos: " + ScreenEntityPos + " screenmousepos: " + ScreenMousePos + " objecttomouse: " + ScreenVectorEntityToMouse ); // Test.Debug

            Vector3 RotationAxisEntityAxes = axis.ToVector();
            Rot     rInverseEntityRot      = EntityRot.Inverse();

            Vector3 RotationAxisWorldAxes = RotationAxisEntityAxes * rInverseEntityRot;
            //    Test.Debug(  " RotationAxisWorldAxes " + RotationAxisWorldAxes ); // Test.Debug

            Vector3 RotationAxisObserverAxes = RotationAxisWorldAxes * OurRot;

            RotationAxisObserverAxes.Normalize();

            double DistanceOfRotationPlaneFromOrigin = 0; // Lets move right up to the object
            // we're going to imagine a ray from the MousePoint going down the XAXIS, away from us
            // we'll intersect this ray with the rotation plane to get the point on the rotation plane
            // where we can consider the mouse to be.
            double fVectorDotRotationAxisObserverAxesWithXAxis = Vector3.DotProduct(RotationAxisObserverAxes, mvMath.XAxis);

            if (Math.Abs(fVectorDotRotationAxisObserverAxesWithXAxis) > 0.0005)
            {
                double fDistanceFromMousePointToRotationPlane = (DistanceOfRotationPlaneFromOrigin -
                                                                 Vector3.DotProduct(RotationAxisObserverAxes, VectorEntityToMousePointObserverAxes))
                                                                / fVectorDotRotationAxisObserverAxesWithXAxis;
                //  Test.Debug(  " fDistanceFromMousePointToRotationPlane " + fDistanceFromMousePointToRotationPlane ); // Test.Debug

                Vector3 VectorMouseClickOnRotationPlaneObserverAxes = new Vector3(
                    fDistanceFromMousePointToRotationPlane,
                    VectorEntityToMousePointObserverAxes.y,
                    VectorEntityToMousePointObserverAxes.z);
                //    Test.Debug(  " VectorMouseClickOnRotationPlaneObserverAxes " + VectorMouseClickOnRotationPlaneObserverAxes ); // Test.Debug
                // We'll rotate this vector into object axes

                Vector3 VectorMouseClickOnRotationPlaneWorldAxes  = VectorMouseClickOnRotationPlaneObserverAxes * rInverseOurRot;
                Vector3 VectorMouseClickOnRotationPlaneEntityAxes = VectorMouseClickOnRotationPlaneWorldAxes * EntityRot;
                //     Test.Debug(  " VectorMouseClickOnRotationPlaneEntityAxes " + VectorMouseClickOnRotationPlaneEntityAxes ); // Test.Debug

                // now we work out rotation angle
                double fDistanceOfPointFromOrigin;
                if (axis.IsXAxis)
                {
                    fDistanceOfPointFromOrigin = Math.Sqrt(VectorMouseClickOnRotationPlaneEntityAxes.z * VectorMouseClickOnRotationPlaneEntityAxes.z
                                                           + VectorMouseClickOnRotationPlaneEntityAxes.y * VectorMouseClickOnRotationPlaneEntityAxes.y);
                    //         Test.Debug(  "Z axis distnace of point from origin: " + fDistanceOfPointFromOrigin ); // Test.Debug

                    if (Math.Abs(fDistanceOfPointFromOrigin) > 0.0005)
                    {
                        fRotationAngle = -Math.Asin(VectorMouseClickOnRotationPlaneEntityAxes.y / fDistanceOfPointFromOrigin);
                        if (VectorMouseClickOnRotationPlaneEntityAxes.z < 0)
                        {
                            fRotationAngle = mvMath.Pi - fRotationAngle;
                        }
                        //             Test.Debug(  "************RotANGLE: " + fRotationAngle ); // Test.Debug
                        bRotAngleGot = true;
                    }
                }
                else if (axis.IsYAxis)
                {
                    fDistanceOfPointFromOrigin = Math.Sqrt(VectorMouseClickOnRotationPlaneEntityAxes.z * VectorMouseClickOnRotationPlaneEntityAxes.z
                                                           + VectorMouseClickOnRotationPlaneEntityAxes.x * VectorMouseClickOnRotationPlaneEntityAxes.x);
                    //         Test.Debug(  "Z axis distnace of point from origin: " + fDistanceOfPointFromOrigin ); // Test.Debug

                    if (Math.Abs(fDistanceOfPointFromOrigin) > 0.0005)
                    {
                        fRotationAngle = Math.Asin(VectorMouseClickOnRotationPlaneEntityAxes.x / fDistanceOfPointFromOrigin);
                        if (VectorMouseClickOnRotationPlaneEntityAxes.z < 0)
                        {
                            fRotationAngle = mvMath.Pi - fRotationAngle;
                        }
                        //             Test.Debug(  "************RotANGLE: " + fRotationAngle ); // Test.Debug
                        bRotAngleGot = true;
                    }
                }
                else
                {
                    fDistanceOfPointFromOrigin = Math.Sqrt(VectorMouseClickOnRotationPlaneEntityAxes.x * VectorMouseClickOnRotationPlaneEntityAxes.x
                                                           + VectorMouseClickOnRotationPlaneEntityAxes.y * VectorMouseClickOnRotationPlaneEntityAxes.y);
                    //         Test.Debug(  "Z axis distnace of point from origin: " + fDistanceOfPointFromOrigin ); // Test.Debug

                    if (Math.Abs(fDistanceOfPointFromOrigin) > 0.0005)
                    {
                        fRotationAngle = Math.Asin(VectorMouseClickOnRotationPlaneEntityAxes.y / fDistanceOfPointFromOrigin);
                        if (VectorMouseClickOnRotationPlaneEntityAxes.x < 0)
                        {
                            fRotationAngle = mvMath.Pi - fRotationAngle;
                        }
                        //             Test.Debug(  "************RotANGLE: " + fRotationAngle ); // Test.Debug
                        bRotAngleGot = true;
                    }
                }
            }

            if (bRotAngleGot)
            {
                //fRotationAngle = fRotAngle;
                return(fRotationAngle);
            }
            else
            {
                return(0);
            }
        }