merge the formfield patch from ooo-build
[ooovba.git] / svx / source / engine3d / dragmt3d.cxx
blob7bbf9c6ca994f084856ec21669d2c8ae82d712de
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dragmt3d.cxx,v $
10 * $Revision: 1.12.18.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <dragmt3d.hxx>
35 #include <tools/shl.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <svx/dialmgr.hxx>
38 #include <svx/svddrgmt.hxx>
39 #include <svx/svdtrans.hxx>
40 #include <svx/obj3d.hxx>
41 #include <svx/polysc3d.hxx>
42 #include <svx/e3dundo.hxx>
43 #include <svx/dialogs.hrc>
44 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
45 #include <svx/sdr/overlay/overlaymanager.hxx>
46 #include <basegfx/polygon/b2dpolypolygontools.hxx>
47 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
48 #include <drawinglayer/geometry/viewinformation3d.hxx>
49 #include <svx/e3dsceneupdater.hxx>
51 TYPEINIT1(E3dDragMethod, SdrDragMethod);
53 /*************************************************************************
55 |* Konstruktor aller 3D-DragMethoden
57 \************************************************************************/
59 E3dDragMethod::E3dDragMethod (
60 SdrDragView &_rView,
61 const SdrMarkList& rMark,
62 E3dDragConstraint eConstr,
63 BOOL bFull)
64 : SdrDragMethod(_rView),
65 meConstraint(eConstr),
66 mbMoveFull(bFull),
67 mbMovedAtAll(FALSE)
69 // Fuer alle in der selektion befindlichen 3D-Objekte
70 // eine Unit anlegen
71 const long nCnt(rMark.GetMarkCount());
72 static bool bDoInvalidate(false);
74 for(long nObjs = 0;nObjs < nCnt;nObjs++)
76 E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj());
78 if(pE3dObj)
80 // fill new interaction unit
81 E3dDragMethodUnit aNewUnit;
82 aNewUnit.mp3DObj = pE3dObj;
84 // get transformations
85 aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform();
87 if(pE3dObj->GetParentObj())
89 // get transform between object and world, normally scene transform
90 aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform();
91 aNewUnit.maInvDisplayTransform.invert();
94 // SnapRects der beteiligten Objekte invalidieren, um eine
95 // Neuberechnung beim Setzen der Marker zu erzwingen
96 if(bDoInvalidate)
98 pE3dObj->SetRectsDirty();
101 if(!mbMoveFull)
103 // create wireframe visualisation for parent coordinate system
104 aNewUnit.maWireframePoly.clear();
105 aNewUnit.maWireframePoly = pE3dObj->CreateWireframe();
106 aNewUnit.maWireframePoly.transform(aNewUnit.maTransform);
109 // FullBound ermitteln
110 maFullBound.Union(pE3dObj->GetSnapRect());
112 // Unit einfuegen
113 maGrp.push_back(aNewUnit);
118 /*************************************************************************
120 \************************************************************************/
122 void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const
126 /*************************************************************************
128 |* Erstelle das Drahtgittermodel fuer alle Aktionen
130 \************************************************************************/
132 bool E3dDragMethod::BeginSdrDrag()
134 if(E3DDRAG_CONSTR_Z == meConstraint)
136 const sal_uInt32 nCnt(maGrp.size());
137 DragStat().Ref1() = maFullBound.Center();
139 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
141 E3dDragMethodUnit& rCandidate = maGrp[nOb];
142 rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1());
143 rCandidate.mnLastAngle = 0;
146 else
148 maLastPos = DragStat().GetStart();
151 if(!mbMoveFull)
153 Show();
156 return TRUE;
159 /*************************************************************************
161 |* Schluss
163 \************************************************************************/
165 bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/)
167 const sal_uInt32 nCnt(maGrp.size());
169 if(!mbMoveFull)
171 // WireFrame ausblenden
172 Hide();
175 // Alle Transformationen anwenden und UnDo's anlegen
176 if(mbMovedAtAll)
178 const bool bUndo = getSdrDragView().IsUndoEnabled();
179 if( bUndo )
180 getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE));
181 sal_uInt32 nOb(0);
183 for(nOb=0;nOb<nCnt;nOb++)
185 E3dDragMethodUnit& rCandidate = maGrp[nOb];
186 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
187 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
188 if( bUndo )
190 getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(),
191 rCandidate.mp3DObj, rCandidate.maInitTransform,
192 rCandidate.maTransform));
195 if( bUndo )
196 getSdrDragView().EndUndo();
199 return TRUE;
202 /*************************************************************************
204 |* Abbruch
206 \************************************************************************/
208 void E3dDragMethod::CancelSdrDrag()
210 if(mbMoveFull)
212 if(mbMovedAtAll)
214 const sal_uInt32 nCnt(maGrp.size());
216 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
218 // Transformation restaurieren
219 E3dDragMethodUnit& rCandidate = maGrp[nOb];
220 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
221 rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform);
225 else
227 // WireFrame ausblenden
228 Hide();
232 /*************************************************************************
234 |* Gemeinsames MoveSdrDrag()
236 \************************************************************************/
238 void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/)
240 mbMovedAtAll = true;
243 /*************************************************************************
245 |* Zeichne das Drahtgittermodel
247 \************************************************************************/
249 // for migration from XOR to overlay
250 void E3dDragMethod::CreateOverlayGeometry(::sdr::overlay::OverlayManager& rOverlayManager)
252 const sal_uInt32 nCnt(maGrp.size());
253 basegfx::B2DPolyPolygon aResult;
255 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
257 E3dDragMethodUnit& rCandidate = maGrp[nOb];
258 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
260 if(pPV && pPV->HasMarkedObjPageView())
262 const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly);
263 const sal_uInt32 nPlyCnt(aCandidate.count());
265 if(nPlyCnt)
267 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
268 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
269 const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation());
270 const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform);
272 // transform to relative scene coordinates
273 basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform));
275 // transform to 2D view coordinates
276 aPolyPolygon.transform(rVCScene.getObjectTransformation());
278 aResult.append(aPolyPolygon);
283 if(aResult.count())
285 ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aResult);
286 rOverlayManager.add(*pNew);
287 addToOverlayObjectList(*pNew);
291 /*************************************************************************
293 E3dDragRotate
295 *************************************************************************/
297 TYPEINIT1(E3dDragRotate, E3dDragMethod);
299 E3dDragRotate::E3dDragRotate(SdrDragView &_rView,
300 const SdrMarkList& rMark,
301 E3dDragConstraint eConstr,
302 BOOL bFull)
303 : E3dDragMethod(_rView, rMark, eConstr, bFull)
305 // Zentrum aller selektierten Objekte in Augkoordinaten holen
306 const sal_uInt32 nCnt(maGrp.size());
308 if(nCnt)
310 const E3dScene *pScene = maGrp[0].mp3DObj->GetScene();
312 if(pScene)
314 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
315 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
317 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
319 E3dDragMethodUnit& rCandidate = maGrp[nOb];
320 basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter();
321 const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform);
323 aObjCenter = aTransform * aObjCenter;
324 maGlobalCenter += aObjCenter;
327 // Teilen durch Anzahl
328 if(nCnt > 1)
330 maGlobalCenter /= (double)nCnt;
333 // get rotate center and transform to 3D eye coordinates
334 basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y());
336 // from world to relative scene using inverse getObjectTransformation()
337 basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation());
338 aInverseObjectTransform.invert();
339 aRotCenter2D = aInverseObjectTransform * aRotCenter2D;
341 // from 3D view to 3D eye
342 basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0);
343 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
344 aInverseViewToEye.invert();
345 aRotCenter3D = aInverseViewToEye * aRotCenter3D;
347 // X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus
348 // Rotationspunkt im Raum benutzen
349 maGlobalCenter.setX(aRotCenter3D.getX());
350 maGlobalCenter.setY(aRotCenter3D.getY());
355 /*************************************************************************
357 |* Das Objekt wird bewegt, bestimme die Winkel
359 \************************************************************************/
361 void E3dDragRotate::MoveSdrDrag(const Point& rPnt)
363 // call parent
364 E3dDragMethod::MoveSdrDrag(rPnt);
366 if(DragStat().CheckMinMoved(rPnt))
368 // Modifier holen
369 sal_uInt16 nModifier = 0;
370 if(getSdrDragView().ISA(E3dView))
372 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent();
373 nModifier = rLastMouse.GetModifier();
376 // Alle Objekte rotieren
377 const sal_uInt32 nCnt(maGrp.size());
379 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
381 // Rotationswinkel bestimmen
382 double fWAngle, fHAngle;
383 E3dDragMethodUnit& rCandidate = maGrp[nOb];
385 if(E3DDRAG_CONSTR_Z == meConstraint)
387 fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) -
388 rCandidate.mnStartAngle) - rCandidate.mnLastAngle;
389 rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle;
390 fWAngle /= 100.0;
391 fHAngle = 0.0;
393 else
395 fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X())
396 / (double)maFullBound.GetWidth();
397 fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y())
398 / (double)maFullBound.GetHeight();
400 long nSnap = 0;
402 if(!getSdrDragView().IsRotateAllowed(FALSE))
403 nSnap = 90;
405 if(nSnap != 0)
407 fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap);
408 fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap);
411 // nach radiant
412 fWAngle *= F_PI180;
413 fHAngle *= F_PI180;
415 // Transformation bestimmen
416 basegfx::B3DHomMatrix aRotMat;
417 if(E3DDRAG_CONSTR_Y & meConstraint)
419 if(nModifier & KEY_MOD2)
420 aRotMat.rotate(0.0, 0.0, fWAngle);
421 else
422 aRotMat.rotate(0.0, fWAngle, 0.0);
424 else if(E3DDRAG_CONSTR_Z & meConstraint)
426 if(nModifier & KEY_MOD2)
427 aRotMat.rotate(0.0, fWAngle, 0.0);
428 else
429 aRotMat.rotate(0.0, 0.0, fWAngle);
431 if(E3DDRAG_CONSTR_X & meConstraint)
433 aRotMat.rotate(fHAngle, 0.0, 0.0);
436 // Transformation in Eye-Koordinaten, dort rotieren
437 // und zurueck
438 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
439 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
440 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
441 aInverseOrientation.invert();
443 basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform);
444 aTransMat *= aViewInfo3D.getOrientation();
445 aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ());
446 aTransMat *= aRotMat;
447 aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ());
448 aTransMat *= aInverseOrientation;
449 aTransMat *= rCandidate.maInvDisplayTransform;
451 // ...und anwenden
452 rCandidate.maTransform *= aTransMat;
454 if(mbMoveFull)
456 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
457 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
459 else
461 Hide();
462 rCandidate.maWireframePoly.transform(aTransMat);
463 Show();
466 maLastPos = rPnt;
467 DragStat().NextMove(rPnt);
471 /*************************************************************************
473 \************************************************************************/
475 Pointer E3dDragRotate::GetSdrDragPointer() const
477 return Pointer(POINTER_ROTATE);
480 /*************************************************************************
482 |* E3dDragMove
483 |* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen
484 |* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod
485 |* nicht verwendet.
487 \************************************************************************/
489 TYPEINIT1(E3dDragMove, E3dDragMethod);
491 E3dDragMove::E3dDragMove(SdrDragView &_rView,
492 const SdrMarkList& rMark,
493 SdrHdlKind eDrgHdl,
494 E3dDragConstraint eConstr,
495 BOOL bFull)
496 : E3dDragMethod(_rView, rMark, eConstr, bFull),
497 meWhatDragHdl(eDrgHdl)
499 switch(meWhatDragHdl)
501 case HDL_LEFT:
502 maScaleFixPos = maFullBound.RightCenter();
503 break;
504 case HDL_RIGHT:
505 maScaleFixPos = maFullBound.LeftCenter();
506 break;
507 case HDL_UPPER:
508 maScaleFixPos = maFullBound.BottomCenter();
509 break;
510 case HDL_LOWER:
511 maScaleFixPos = maFullBound.TopCenter();
512 break;
513 case HDL_UPLFT:
514 maScaleFixPos = maFullBound.BottomRight();
515 break;
516 case HDL_UPRGT:
517 maScaleFixPos = maFullBound.BottomLeft();
518 break;
519 case HDL_LWLFT:
520 maScaleFixPos = maFullBound.TopRight();
521 break;
522 case HDL_LWRGT:
523 maScaleFixPos = maFullBound.TopLeft();
524 break;
525 default:
526 // Bewegen des Objektes, HDL_MOVE
527 break;
530 // Override wenn IsResizeAtCenter()
531 if(getSdrDragView().IsResizeAtCenter())
533 meWhatDragHdl = HDL_USER;
534 maScaleFixPos = maFullBound.Center();
538 /*************************************************************************
540 |* Das Objekt wird bewegt, bestimme die Translation
542 \************************************************************************/
544 void E3dDragMove::MoveSdrDrag(const Point& rPnt)
546 // call parent
547 E3dDragMethod::MoveSdrDrag(rPnt);
549 if(DragStat().CheckMinMoved(rPnt))
551 if(HDL_MOVE == meWhatDragHdl)
553 // Translation
554 // Bewegungsvektor bestimmen
555 basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0);
556 basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0);
557 const sal_uInt32 nCnt(maGrp.size());
559 // Modifier holen
560 sal_uInt16 nModifier(0);
562 if(getSdrDragView().ISA(E3dView))
564 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent();
565 nModifier = rLastMouse.GetModifier();
568 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
570 E3dDragMethodUnit& rCandidate = maGrp[nOb];
571 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
572 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
574 // move coor from 2d world to 3d Eye
575 basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()));
576 basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0);
577 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
579 aInverseSceneTransform.invert();
580 aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D;
581 aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D;
583 basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5);
584 basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5);
585 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
586 aInverseViewToEye.invert();
588 aMoveHead3D = aInverseViewToEye * aMoveHead3D;
589 aMoveTail3D = aInverseViewToEye * aMoveTail3D;
591 // eventually switch movement from XY to XZ plane
592 if(nModifier & KEY_MOD2)
594 double fZwi = aMoveHead3D.getY();
595 aMoveHead3D.setY(aMoveHead3D.getZ());
596 aMoveHead3D.setZ(fZwi);
598 fZwi = aMoveTail3D.getY();
599 aMoveTail3D.setY(aMoveTail3D.getZ());
600 aMoveTail3D.setZ(fZwi);
603 // Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten
604 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
605 aInverseOrientation.invert();
606 basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation);
608 aMoveHead3D = aCompleteTrans * aMoveHead3D;
609 aMoveTail3D = aCompleteTrans* aMoveTail3D;
611 // build transformation
612 basegfx::B3DHomMatrix aTransMat;
613 basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D);
614 aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ());
616 // ...and apply
617 rCandidate.maTransform *= aTransMat;
619 if(mbMoveFull)
621 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
622 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
624 else
626 Hide();
627 rCandidate.maWireframePoly.transform(aTransMat);
628 Show();
632 else
634 // Skalierung
635 // Skalierungsvektor bestimmen
636 Point aStartPos = DragStat().GetStart();
637 const sal_uInt32 nCnt(maGrp.size());
639 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
641 E3dDragMethodUnit& rCandidate = maGrp[nOb];
642 const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter());
644 // transform from 2D world view to 3D eye
645 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
646 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
648 basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y()));
649 basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y()));
650 basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y()));
651 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
653 aInverseSceneTransform.invert();
654 aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D;
655 aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D;
656 aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D;
658 basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ());
659 basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ());
660 basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ());
661 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
663 aInverseViewToEye.invert();
664 basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D);
665 basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D);
666 basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D);
668 // constraints?
669 switch(meWhatDragHdl)
671 case HDL_LEFT:
672 case HDL_RIGHT:
673 // constrain to auf X -> Y equal
674 aScNext.setY(aScFixPos.getY());
675 break;
676 case HDL_UPPER:
677 case HDL_LOWER:
678 // constrain to auf Y -> X equal
679 aScNext.setX(aScFixPos.getX());
680 break;
681 default:
682 break;
685 // get scale vector in eye coordinates
686 basegfx::B3DPoint aScaleVec(aScStart - aScFixPos);
687 aScaleVec.setZ(1.0);
689 if(aScaleVec.getX() != 0.0)
691 aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX());
693 else
695 aScaleVec.setX(1.0);
698 if(aScaleVec.getY() != 0.0)
700 aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY());
702 else
704 aScaleVec.setY(1.0);
707 // SHIFT-key used?
708 if(getSdrDragView().IsOrtho())
710 if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY()))
712 // X is biggest
713 aScaleVec.setY(aScaleVec.getX());
715 else
717 // Y is biggest
718 aScaleVec.setX(aScaleVec.getY());
722 // build transformation
723 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
724 aInverseOrientation.invert();
726 basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform;
727 aNewTrans *= rCandidate.maDisplayTransform;
728 aNewTrans *= aViewInfo3D.getOrientation();
729 aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ());
730 aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ());
731 aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ());
732 aNewTrans *= aInverseOrientation;
733 aNewTrans *= rCandidate.maInvDisplayTransform;
735 // ...und anwenden
736 rCandidate.maTransform = aNewTrans;
738 if(mbMoveFull)
740 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
741 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
743 else
745 Hide();
746 rCandidate.maWireframePoly.clear();
747 rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe();
748 rCandidate.maWireframePoly.transform(rCandidate.maTransform);
749 Show();
753 maLastPos = rPnt;
754 DragStat().NextMove(rPnt);
758 /*************************************************************************
760 \************************************************************************/
762 Pointer E3dDragMove::GetSdrDragPointer() const
764 return Pointer(POINTER_MOVE);
767 // eof