public void InteractiveFreeEdit(int x, int y) { 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; } } Rot rInverseOurRot = OurRot.Inverse(); double HalfWinWidth = RendererFactory.GetInstance().WindowWidth / 2; double HalfWinHeight = RendererFactory.GetInstance().WindowHeight / 2; double zRoll = (x - editing3d.iDragStartX) / HalfWinWidth; double yRoll = -(y - editing3d.iDragStartY) / HalfWinHeight; double amount = Math.Sqrt((double)((editing3d.iDragStartX - x) * (editing3d.iDragStartX - x) + (editing3d.iDragStartY - y) * (editing3d.iDragStartY - y))) * mvMath.Pi2 / HalfWinHeight; Vector3 ArcBallAxis = new Vector3(0, yRoll, zRoll); Rot ArcBallRot = mvMath.AxisAngle2Rot(ArcBallAxis, amount); Rot rTransposedToAv = rInverseOurRot * editing3d.startrot; Rot rRotated = ArcBallRot * rTransposedToAv; Rot rNewRot = OurRot * rRotated; selectionmodel.GetFirstSelectedEntity().rot = rNewRot; MetaverseClient.GetInstance().worldstorage.OnModifyEntity(selectionmodel.GetFirstSelectedEntity()); }
public void DrawEditBarsToOpenGL(Vector3 camerapos) { if (bShowEditBars) { Entity entity = selectionmodel.GetFirstSelectedEntity(); if (entity == null) { return; } IGraphicsHelper graphics = GraphicsHelperFactory.GetInstance(); graphics.PushMatrix(); if (entity.Parent == null) { //entity.DrawSelected(); } else { (entity.Parent as EntityGroup).ApplyTransforms(); } graphics.Translate(entity.pos); graphics.Rotate(entity.rot); // Vector3[] FaceCentreOffsets = new Vector3[6]; double distance = (entity.pos - camerapos).Det(); Vector3 ScaleToUse = entity.scale; switch (editbartype) { case EditBarType.Pos: editing3dpos.DrawEditHandles(ScaleToUse, distance); //editing3dscale.DrawEditHandles(ScaleToUse, distance); break; case EditBarType.Scale: editing3dscale.DrawEditHandles(ScaleToUse, distance); break; case EditBarType.Rot: editing3drot.DrawEditHandles(ScaleToUse); break; } graphics.PopMatrix(); } }
// 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); }