public void InitiateHandleEdit( int mousex, int mousey, Axis axis ) { editing3d.EditingPreliminaries(); Entity entity = selectionmodel.GetFirstSelectedEntity(); if( entity != null ) { editing3d.iDragStartX = mousex; editing3d.iDragStartY = mousey; editing3d.startscale = entity.scale; editing3d.startpos = entity.pos; //DEBUG( "initializing editing3d.startscale " << editing3d.startscale ); // DEBUG editing3d.currentaxis = axis; editing3d.currentedittype = Editing3d.EditType.ScaleHandle; } }
public void InitiateHandleEdit( int mousex, int mousey, Axis axistype ) { editing3d.EditingPreliminaries(); Entity entity = selectionmodel.GetFirstSelectedEntity(); if( entity == null ) { return; } editing3d.iDragStartX = mousex; editing3d.iDragStartY = mousey; editing3d.startpos = entity.pos; Test.Debug( "initializing startpos " + editing3d.startpos ); // Test.Debug editing3d.currentaxis = axistype; editing3d.currentedittype = Editing3d.EditType.PosHandle; }
void DrawSingleEditHandle( Vector3 entityscale, Vector3 handlescale, Axis handleaxis ) { graphics.PushMatrix(); graphics.SetMaterialColor( editing3d.GetEditHandleColor( handleaxis ) ); RendererFactory.GetPicker3dModel().AddHitTarget( new HitTargetEditHandle( new Axis( handleaxis ) ) ); double fTranslateAmount = ( handleaxis.GetAxisComponentIgnoreAxisDirection( entityscale ) + handleaxis.GetAxisComponentIgnoreAxisDirection( handlescale ) ) / 2; graphics.Translate( fTranslateAmount * handleaxis.ToVector() ); graphics.Scale( handlescale ); graphics.Rotate( handleaxis.ToRot() ); graphics.Rotate( 90, 0, 1, 0 ); graphics.DrawCone(); RendererFactory.GetPicker3dModel().EndHitTarget(); graphics.PopMatrix(); }
// When the movement of the mouse is perpendicular to the selected axis, there are two cases to consider: // - the selected axis is in the plane of the screen -> there should be no resulting movement // - the selected axis is normal to the screen -> the movement should be infinite // // Let's call the entity's selected axis in world axes "handleaxis" // Let's call the mouse move vector, in world axes "mousemove" // So, first we need to project handleaxis onto the screen, and project mousemove onto the unit vector of this, // This gives us a mouse vector, mousemove2 that is immune to the first case above (" - the selected axis is in the plane of the screen -> there should be no resulting movement") // // Now, we project unit(handleaxis) onto unit(mousemove2) // This will give a number <= 1. // We will divide |mousemove2| by this value to get the distance that our entity moves along its axis // Now it is easy to get the position change by multiplying this quantity by unit(handleaxis) // // Note that most of the above was in avatar axes (not entity axes or world axes) // public void InteractiveHandleEdit( Axis axis, int mousex, int mousey ) { Entity entity = selectionmodel.GetFirstSelectedEntity(); if( entity == null ) { return; } 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; } } // 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(); 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 how far the entity moves: Vector3 entitymoveworldaxes = new Vector3(); if( Math.Abs( entitymovetomousemoveratio ) > 0.05 ) // forbid infinite moves... { entitymoveworldaxes = ( mousemove2.Det() / entitymovetomousemoveratio ) * handleaxisworldaxes.Unit(); } entity.pos = editing3d.startpos + entitymoveworldaxes; //Test.Debug( "pobjectpos: " + entity.pos ); // Test.Debug MetaverseClient.GetInstance().worldstorage.OnModifyEntity(entity); }
public Axis( Axis orig ) { bPositiveAxis = orig.bPositiveAxis; axisindex = orig.axisindex; }