| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include <dragmt3d.hxx> |
| #include <tools/shl.hxx> |
| #include <svx/svdpagv.hxx> |
| #include <svx/dialmgr.hxx> |
| #include <svx/svddrgmt.hxx> |
| #include <svx/svdtrans.hxx> |
| #include <svx/obj3d.hxx> |
| #include <svx/polysc3d.hxx> |
| #include <svx/e3dundo.hxx> |
| #include <svx/dialogs.hrc> |
| #include <svx/sdr/overlay/overlaypolypolygon.hxx> |
| #include <svx/sdr/overlay/overlaymanager.hxx> |
| #include <basegfx/polygon/b2dpolypolygontools.hxx> |
| #include <svx/sdr/contact/viewcontactofe3dscene.hxx> |
| #include <drawinglayer/geometry/viewinformation3d.hxx> |
| #include <svx/e3dsceneupdater.hxx> |
| |
| TYPEINIT1(E3dDragMethod, SdrDragMethod); |
| |
| /************************************************************************* |
| |* |
| |* Konstruktor aller 3D-DragMethoden |
| |* |
| \************************************************************************/ |
| |
| E3dDragMethod::E3dDragMethod ( |
| SdrDragView &_rView, |
| const SdrMarkList& rMark, |
| E3dDragConstraint eConstr, |
| sal_Bool bFull) |
| : SdrDragMethod(_rView), |
| meConstraint(eConstr), |
| mbMoveFull(bFull), |
| mbMovedAtAll(sal_False) |
| { |
| // Fuer alle in der selektion befindlichen 3D-Objekte |
| // eine Unit anlegen |
| const long nCnt(rMark.GetMarkCount()); |
| static bool bDoInvalidate(false); |
| long nObjs(0); |
| |
| if(mbMoveFull) |
| { |
| // for non-visible 3D objects fallback to wireframe interaction |
| bool bInvisibleObjects(false); |
| |
| for(nObjs = 0;!bInvisibleObjects && nObjs < nCnt;nObjs++) |
| { |
| E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); |
| |
| if(pE3dObj) |
| { |
| if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle()) |
| { |
| bInvisibleObjects = true; |
| } |
| } |
| } |
| |
| if(bInvisibleObjects) |
| { |
| mbMoveFull = false; |
| } |
| } |
| |
| for(nObjs = 0;nObjs < nCnt;nObjs++) |
| { |
| E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); |
| |
| if(pE3dObj) |
| { |
| // fill new interaction unit |
| E3dDragMethodUnit aNewUnit; |
| aNewUnit.mp3DObj = pE3dObj; |
| |
| // get transformations |
| aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform(); |
| |
| if(pE3dObj->GetParentObj()) |
| { |
| // get transform between object and world, normally scene transform |
| aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform(); |
| aNewUnit.maInvDisplayTransform.invert(); |
| } |
| |
| // SnapRects der beteiligten Objekte invalidieren, um eine |
| // Neuberechnung beim Setzen der Marker zu erzwingen |
| if(bDoInvalidate) |
| { |
| pE3dObj->SetRectsDirty(); |
| } |
| |
| if(!mbMoveFull) |
| { |
| // create wireframe visualisation for parent coordinate system |
| aNewUnit.maWireframePoly.clear(); |
| aNewUnit.maWireframePoly = pE3dObj->CreateWireframe(); |
| aNewUnit.maWireframePoly.transform(aNewUnit.maTransform); |
| } |
| |
| // FullBound ermitteln |
| maFullBound.Union(pE3dObj->GetSnapRect()); |
| |
| // Unit einfuegen |
| maGrp.push_back(aNewUnit); |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| \************************************************************************/ |
| |
| void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const |
| { |
| } |
| |
| /************************************************************************* |
| |* |
| |* Erstelle das Drahtgittermodel fuer alle Aktionen |
| |* |
| \************************************************************************/ |
| |
| bool E3dDragMethod::BeginSdrDrag() |
| { |
| if(E3DDRAG_CONSTR_Z == meConstraint) |
| { |
| const sal_uInt32 nCnt(maGrp.size()); |
| DragStat().Ref1() = maFullBound.Center(); |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1()); |
| rCandidate.mnLastAngle = 0; |
| } |
| } |
| else |
| { |
| maLastPos = DragStat().GetStart(); |
| } |
| |
| if(!mbMoveFull) |
| { |
| Show(); |
| } |
| |
| return sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* Schluss |
| |* |
| \************************************************************************/ |
| |
| bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/) |
| { |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| if(!mbMoveFull) |
| { |
| // WireFrame ausblenden |
| Hide(); |
| } |
| |
| // Alle Transformationen anwenden und UnDo's anlegen |
| if(mbMovedAtAll) |
| { |
| const bool bUndo = getSdrDragView().IsUndoEnabled(); |
| if( bUndo ) |
| getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE)); |
| sal_uInt32 nOb(0); |
| |
| for(nOb=0;nOb<nCnt;nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); |
| rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); |
| if( bUndo ) |
| { |
| getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(), |
| rCandidate.mp3DObj, rCandidate.maInitTransform, |
| rCandidate.maTransform)); |
| } |
| } |
| if( bUndo ) |
| getSdrDragView().EndUndo(); |
| } |
| |
| return sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* Abbruch |
| |* |
| \************************************************************************/ |
| |
| void E3dDragMethod::CancelSdrDrag() |
| { |
| if(mbMoveFull) |
| { |
| if(mbMovedAtAll) |
| { |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| // Transformation restaurieren |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); |
| rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform); |
| } |
| } |
| } |
| else |
| { |
| // WireFrame ausblenden |
| Hide(); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* Gemeinsames MoveSdrDrag() |
| |* |
| \************************************************************************/ |
| |
| void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/) |
| { |
| mbMovedAtAll = true; |
| } |
| |
| /************************************************************************* |
| |* |
| |* Zeichne das Drahtgittermodel |
| |* |
| \************************************************************************/ |
| |
| // for migration from XOR to overlay |
| void E3dDragMethod::CreateOverlayGeometry(::sdr::overlay::OverlayManager& rOverlayManager) |
| { |
| const sal_uInt32 nCnt(maGrp.size()); |
| basegfx::B2DPolyPolygon aResult; |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| SdrPageView* pPV = getSdrDragView().GetSdrPageView(); |
| |
| if(pPV && pPV->HasMarkedObjPageView()) |
| { |
| const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly); |
| const sal_uInt32 nPlyCnt(aCandidate.count()); |
| |
| if(nPlyCnt) |
| { |
| const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); |
| const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); |
| const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation()); |
| const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform); |
| |
| // transform to relative scene coordinates |
| basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform)); |
| |
| // transform to 2D view coordinates |
| aPolyPolygon.transform(rVCScene.getObjectTransformation()); |
| |
| aResult.append(aPolyPolygon); |
| } |
| } |
| } |
| |
| if(aResult.count()) |
| { |
| ::sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled( |
| aResult); |
| rOverlayManager.add(*pNew); |
| addToOverlayObjectList(*pNew); |
| } |
| } |
| |
| /************************************************************************* |
| |
| E3dDragRotate |
| |
| *************************************************************************/ |
| |
| TYPEINIT1(E3dDragRotate, E3dDragMethod); |
| |
| E3dDragRotate::E3dDragRotate(SdrDragView &_rView, |
| const SdrMarkList& rMark, |
| E3dDragConstraint eConstr, |
| sal_Bool bFull) |
| : E3dDragMethod(_rView, rMark, eConstr, bFull) |
| { |
| // Zentrum aller selektierten Objekte in Augkoordinaten holen |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| if(nCnt) |
| { |
| const E3dScene *pScene = maGrp[0].mp3DObj->GetScene(); |
| |
| if(pScene) |
| { |
| const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); |
| const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter(); |
| const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform); |
| |
| aObjCenter = aTransform * aObjCenter; |
| maGlobalCenter += aObjCenter; |
| } |
| |
| // Teilen durch Anzahl |
| if(nCnt > 1) |
| { |
| maGlobalCenter /= (double)nCnt; |
| } |
| |
| // get rotate center and transform to 3D eye coordinates |
| basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y()); |
| |
| // from world to relative scene using inverse getObjectTransformation() |
| basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation()); |
| aInverseObjectTransform.invert(); |
| aRotCenter2D = aInverseObjectTransform * aRotCenter2D; |
| |
| // from 3D view to 3D eye |
| basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0); |
| basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); |
| aInverseViewToEye.invert(); |
| aRotCenter3D = aInverseViewToEye * aRotCenter3D; |
| |
| // X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus |
| // Rotationspunkt im Raum benutzen |
| maGlobalCenter.setX(aRotCenter3D.getX()); |
| maGlobalCenter.setY(aRotCenter3D.getY()); |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* Das Objekt wird bewegt, bestimme die Winkel |
| |* |
| \************************************************************************/ |
| |
| void E3dDragRotate::MoveSdrDrag(const Point& rPnt) |
| { |
| // call parent |
| E3dDragMethod::MoveSdrDrag(rPnt); |
| |
| if(DragStat().CheckMinMoved(rPnt)) |
| { |
| // Modifier holen |
| sal_uInt16 nModifier = 0; |
| if(getSdrDragView().ISA(E3dView)) |
| { |
| const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); |
| nModifier = rLastMouse.GetModifier(); |
| } |
| |
| // Alle Objekte rotieren |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| // Rotationswinkel bestimmen |
| double fWAngle, fHAngle; |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| |
| if(E3DDRAG_CONSTR_Z == meConstraint) |
| { |
| fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) - |
| rCandidate.mnStartAngle) - rCandidate.mnLastAngle; |
| rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle; |
| fWAngle /= 100.0; |
| fHAngle = 0.0; |
| } |
| else |
| { |
| fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X()) |
| / (double)maFullBound.GetWidth(); |
| fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y()) |
| / (double)maFullBound.GetHeight(); |
| } |
| long nSnap = 0; |
| |
| if(!getSdrDragView().IsRotateAllowed(sal_False)) |
| nSnap = 90; |
| |
| if(nSnap != 0) |
| { |
| fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap); |
| fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap); |
| } |
| |
| // nach radiant |
| fWAngle *= F_PI180; |
| fHAngle *= F_PI180; |
| |
| // Transformation bestimmen |
| basegfx::B3DHomMatrix aRotMat; |
| if(E3DDRAG_CONSTR_Y & meConstraint) |
| { |
| if(nModifier & KEY_MOD2) |
| aRotMat.rotate(0.0, 0.0, fWAngle); |
| else |
| aRotMat.rotate(0.0, fWAngle, 0.0); |
| } |
| else if(E3DDRAG_CONSTR_Z & meConstraint) |
| { |
| if(nModifier & KEY_MOD2) |
| aRotMat.rotate(0.0, fWAngle, 0.0); |
| else |
| aRotMat.rotate(0.0, 0.0, fWAngle); |
| } |
| if(E3DDRAG_CONSTR_X & meConstraint) |
| { |
| aRotMat.rotate(fHAngle, 0.0, 0.0); |
| } |
| |
| // Transformation in Eye-Koordinaten, dort rotieren |
| // und zurueck |
| const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); |
| const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); |
| basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); |
| aInverseOrientation.invert(); |
| |
| basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform); |
| aTransMat *= aViewInfo3D.getOrientation(); |
| aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ()); |
| aTransMat *= aRotMat; |
| aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ()); |
| aTransMat *= aInverseOrientation; |
| aTransMat *= rCandidate.maInvDisplayTransform; |
| |
| // ...und anwenden |
| rCandidate.maTransform *= aTransMat; |
| |
| if(mbMoveFull) |
| { |
| E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); |
| rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); |
| } |
| else |
| { |
| Hide(); |
| rCandidate.maWireframePoly.transform(aTransMat); |
| Show(); |
| } |
| } |
| maLastPos = rPnt; |
| DragStat().NextMove(rPnt); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| \************************************************************************/ |
| |
| Pointer E3dDragRotate::GetSdrDragPointer() const |
| { |
| return Pointer(POINTER_ROTATE); |
| } |
| |
| /************************************************************************* |
| |* |
| |* E3dDragMove |
| |* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen |
| |* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod |
| |* nicht verwendet. |
| |* |
| \************************************************************************/ |
| |
| TYPEINIT1(E3dDragMove, E3dDragMethod); |
| |
| E3dDragMove::E3dDragMove(SdrDragView &_rView, |
| const SdrMarkList& rMark, |
| SdrHdlKind eDrgHdl, |
| E3dDragConstraint eConstr, |
| sal_Bool bFull) |
| : E3dDragMethod(_rView, rMark, eConstr, bFull), |
| meWhatDragHdl(eDrgHdl) |
| { |
| switch(meWhatDragHdl) |
| { |
| case HDL_LEFT: |
| maScaleFixPos = maFullBound.RightCenter(); |
| break; |
| case HDL_RIGHT: |
| maScaleFixPos = maFullBound.LeftCenter(); |
| break; |
| case HDL_UPPER: |
| maScaleFixPos = maFullBound.BottomCenter(); |
| break; |
| case HDL_LOWER: |
| maScaleFixPos = maFullBound.TopCenter(); |
| break; |
| case HDL_UPLFT: |
| maScaleFixPos = maFullBound.BottomRight(); |
| break; |
| case HDL_UPRGT: |
| maScaleFixPos = maFullBound.BottomLeft(); |
| break; |
| case HDL_LWLFT: |
| maScaleFixPos = maFullBound.TopRight(); |
| break; |
| case HDL_LWRGT: |
| maScaleFixPos = maFullBound.TopLeft(); |
| break; |
| default: |
| // Bewegen des Objektes, HDL_MOVE |
| break; |
| } |
| |
| // Override wenn IsResizeAtCenter() |
| if(getSdrDragView().IsResizeAtCenter()) |
| { |
| meWhatDragHdl = HDL_USER; |
| maScaleFixPos = maFullBound.Center(); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* Das Objekt wird bewegt, bestimme die Translation |
| |* |
| \************************************************************************/ |
| |
| void E3dDragMove::MoveSdrDrag(const Point& rPnt) |
| { |
| // call parent |
| E3dDragMethod::MoveSdrDrag(rPnt); |
| |
| if(DragStat().CheckMinMoved(rPnt)) |
| { |
| if(HDL_MOVE == meWhatDragHdl) |
| { |
| // Translation |
| // Bewegungsvektor bestimmen |
| basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0); |
| basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0); |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| // Modifier holen |
| sal_uInt16 nModifier(0); |
| |
| if(getSdrDragView().ISA(E3dView)) |
| { |
| const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); |
| nModifier = rLastMouse.GetModifier(); |
| } |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); |
| const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); |
| |
| // move coor from 2d world to 3d Eye |
| basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y())); |
| basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0); |
| basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); |
| |
| aInverseSceneTransform.invert(); |
| aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D; |
| aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D; |
| |
| basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5); |
| basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5); |
| basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); |
| aInverseViewToEye.invert(); |
| |
| aMoveHead3D = aInverseViewToEye * aMoveHead3D; |
| aMoveTail3D = aInverseViewToEye * aMoveTail3D; |
| |
| // eventually switch movement from XY to XZ plane |
| if(nModifier & KEY_MOD2) |
| { |
| double fZwi = aMoveHead3D.getY(); |
| aMoveHead3D.setY(aMoveHead3D.getZ()); |
| aMoveHead3D.setZ(fZwi); |
| |
| fZwi = aMoveTail3D.getY(); |
| aMoveTail3D.setY(aMoveTail3D.getZ()); |
| aMoveTail3D.setZ(fZwi); |
| } |
| |
| // Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten |
| basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); |
| aInverseOrientation.invert(); |
| basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation); |
| |
| aMoveHead3D = aCompleteTrans * aMoveHead3D; |
| aMoveTail3D = aCompleteTrans* aMoveTail3D; |
| |
| // build transformation |
| basegfx::B3DHomMatrix aTransMat; |
| basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D); |
| aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ()); |
| |
| // ...and apply |
| rCandidate.maTransform *= aTransMat; |
| |
| if(mbMoveFull) |
| { |
| E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); |
| rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); |
| } |
| else |
| { |
| Hide(); |
| rCandidate.maWireframePoly.transform(aTransMat); |
| Show(); |
| } |
| } |
| } |
| else |
| { |
| // Skalierung |
| // Skalierungsvektor bestimmen |
| Point aStartPos = DragStat().GetStart(); |
| const sal_uInt32 nCnt(maGrp.size()); |
| |
| for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) |
| { |
| E3dDragMethodUnit& rCandidate = maGrp[nOb]; |
| const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter()); |
| |
| // transform from 2D world view to 3D eye |
| const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); |
| const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); |
| |
| basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y())); |
| basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y())); |
| basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y())); |
| basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); |
| |
| aInverseSceneTransform.invert(); |
| aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D; |
| aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D; |
| aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D; |
| |
| basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ()); |
| basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ()); |
| basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ()); |
| basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); |
| |
| aInverseViewToEye.invert(); |
| basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D); |
| basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D); |
| basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D); |
| |
| // constraints? |
| switch(meWhatDragHdl) |
| { |
| case HDL_LEFT: |
| case HDL_RIGHT: |
| // constrain to auf X -> Y equal |
| aScNext.setY(aScFixPos.getY()); |
| break; |
| case HDL_UPPER: |
| case HDL_LOWER: |
| // constrain to auf Y -> X equal |
| aScNext.setX(aScFixPos.getX()); |
| break; |
| default: |
| break; |
| } |
| |
| // get scale vector in eye coordinates |
| basegfx::B3DPoint aScaleVec(aScStart - aScFixPos); |
| aScaleVec.setZ(1.0); |
| |
| if(aScaleVec.getX() != 0.0) |
| { |
| aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX()); |
| } |
| else |
| { |
| aScaleVec.setX(1.0); |
| } |
| |
| if(aScaleVec.getY() != 0.0) |
| { |
| aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY()); |
| } |
| else |
| { |
| aScaleVec.setY(1.0); |
| } |
| |
| // SHIFT-key used? |
| if(getSdrDragView().IsOrtho()) |
| { |
| if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY())) |
| { |
| // X is biggest |
| aScaleVec.setY(aScaleVec.getX()); |
| } |
| else |
| { |
| // Y is biggest |
| aScaleVec.setX(aScaleVec.getY()); |
| } |
| } |
| |
| // build transformation |
| basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); |
| aInverseOrientation.invert(); |
| |
| basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform; |
| aNewTrans *= rCandidate.maDisplayTransform; |
| aNewTrans *= aViewInfo3D.getOrientation(); |
| aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ()); |
| aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ()); |
| aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ()); |
| aNewTrans *= aInverseOrientation; |
| aNewTrans *= rCandidate.maInvDisplayTransform; |
| |
| // ...und anwenden |
| rCandidate.maTransform = aNewTrans; |
| |
| if(mbMoveFull) |
| { |
| E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); |
| rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); |
| } |
| else |
| { |
| Hide(); |
| rCandidate.maWireframePoly.clear(); |
| rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe(); |
| rCandidate.maWireframePoly.transform(rCandidate.maTransform); |
| Show(); |
| } |
| } |
| } |
| maLastPos = rPnt; |
| DragStat().NextMove(rPnt); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| \************************************************************************/ |
| |
| Pointer E3dDragMove::GetSdrDragPointer() const |
| { |
| return Pointer(POINTER_MOVE); |
| } |
| |
| // eof |