1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include <dragmt3d.hxx> 32 #include <tools/shl.hxx> 33 #include <svx/svdpagv.hxx> 34 #include <svx/dialmgr.hxx> 35 #include <svx/svddrgmt.hxx> 36 #include <svx/svdtrans.hxx> 37 #include <svx/obj3d.hxx> 38 #include <svx/polysc3d.hxx> 39 #include <svx/e3dundo.hxx> 40 #include <svx/dialogs.hrc> 41 #include <svx/sdr/overlay/overlaypolypolygon.hxx> 42 #include <svx/sdr/overlay/overlaymanager.hxx> 43 #include <basegfx/polygon/b2dpolypolygontools.hxx> 44 #include <svx/sdr/contact/viewcontactofe3dscene.hxx> 45 #include <drawinglayer/geometry/viewinformation3d.hxx> 46 #include <svx/e3dsceneupdater.hxx> 47 48 TYPEINIT1(E3dDragMethod, SdrDragMethod); 49 50 /************************************************************************* 51 |* 52 |* Konstruktor aller 3D-DragMethoden 53 |* 54 \************************************************************************/ 55 56 E3dDragMethod::E3dDragMethod ( 57 SdrDragView &_rView, 58 const SdrMarkList& rMark, 59 E3dDragConstraint eConstr, 60 sal_Bool bFull) 61 : SdrDragMethod(_rView), 62 meConstraint(eConstr), 63 mbMoveFull(bFull), 64 mbMovedAtAll(sal_False) 65 { 66 // Fuer alle in der selektion befindlichen 3D-Objekte 67 // eine Unit anlegen 68 const long nCnt(rMark.GetMarkCount()); 69 static bool bDoInvalidate(false); 70 long nObjs(0); 71 72 if(mbMoveFull) 73 { 74 // for non-visible 3D objects fallback to wireframe interaction 75 bool bInvisibleObjects(false); 76 77 for(nObjs = 0;!bInvisibleObjects && nObjs < nCnt;nObjs++) 78 { 79 E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); 80 81 if(pE3dObj) 82 { 83 if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle()) 84 { 85 bInvisibleObjects = true; 86 } 87 } 88 } 89 90 if(bInvisibleObjects) 91 { 92 mbMoveFull = false; 93 } 94 } 95 96 for(nObjs = 0;nObjs < nCnt;nObjs++) 97 { 98 E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj()); 99 100 if(pE3dObj) 101 { 102 // fill new interaction unit 103 E3dDragMethodUnit aNewUnit; 104 aNewUnit.mp3DObj = pE3dObj; 105 106 // get transformations 107 aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform(); 108 109 if(pE3dObj->GetParentObj()) 110 { 111 // get transform between object and world, normally scene transform 112 aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform(); 113 aNewUnit.maInvDisplayTransform.invert(); 114 } 115 116 // SnapRects der beteiligten Objekte invalidieren, um eine 117 // Neuberechnung beim Setzen der Marker zu erzwingen 118 if(bDoInvalidate) 119 { 120 pE3dObj->SetRectsDirty(); 121 } 122 123 if(!mbMoveFull) 124 { 125 // create wireframe visualisation for parent coordinate system 126 aNewUnit.maWireframePoly.clear(); 127 aNewUnit.maWireframePoly = pE3dObj->CreateWireframe(); 128 aNewUnit.maWireframePoly.transform(aNewUnit.maTransform); 129 } 130 131 // FullBound ermitteln 132 maFullBound.Union(pE3dObj->GetSnapRect()); 133 134 // Unit einfuegen 135 maGrp.push_back(aNewUnit); 136 } 137 } 138 } 139 140 /************************************************************************* 141 |* 142 \************************************************************************/ 143 144 void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const 145 { 146 } 147 148 /************************************************************************* 149 |* 150 |* Erstelle das Drahtgittermodel fuer alle Aktionen 151 |* 152 \************************************************************************/ 153 154 bool E3dDragMethod::BeginSdrDrag() 155 { 156 if(E3DDRAG_CONSTR_Z == meConstraint) 157 { 158 const sal_uInt32 nCnt(maGrp.size()); 159 DragStat().Ref1() = maFullBound.Center(); 160 161 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 162 { 163 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 164 rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1()); 165 rCandidate.mnLastAngle = 0; 166 } 167 } 168 else 169 { 170 maLastPos = DragStat().GetStart(); 171 } 172 173 if(!mbMoveFull) 174 { 175 Show(); 176 } 177 178 return sal_True; 179 } 180 181 /************************************************************************* 182 |* 183 |* Schluss 184 |* 185 \************************************************************************/ 186 187 bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/) 188 { 189 const sal_uInt32 nCnt(maGrp.size()); 190 191 if(!mbMoveFull) 192 { 193 // WireFrame ausblenden 194 Hide(); 195 } 196 197 // Alle Transformationen anwenden und UnDo's anlegen 198 if(mbMovedAtAll) 199 { 200 const bool bUndo = getSdrDragView().IsUndoEnabled(); 201 if( bUndo ) 202 getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE)); 203 sal_uInt32 nOb(0); 204 205 for(nOb=0;nOb<nCnt;nOb++) 206 { 207 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 208 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 209 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 210 if( bUndo ) 211 { 212 getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(), 213 rCandidate.mp3DObj, rCandidate.maInitTransform, 214 rCandidate.maTransform)); 215 } 216 } 217 if( bUndo ) 218 getSdrDragView().EndUndo(); 219 } 220 221 return sal_True; 222 } 223 224 /************************************************************************* 225 |* 226 |* Abbruch 227 |* 228 \************************************************************************/ 229 230 void E3dDragMethod::CancelSdrDrag() 231 { 232 if(mbMoveFull) 233 { 234 if(mbMovedAtAll) 235 { 236 const sal_uInt32 nCnt(maGrp.size()); 237 238 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 239 { 240 // Transformation restaurieren 241 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 242 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 243 rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform); 244 } 245 } 246 } 247 else 248 { 249 // WireFrame ausblenden 250 Hide(); 251 } 252 } 253 254 /************************************************************************* 255 |* 256 |* Gemeinsames MoveSdrDrag() 257 |* 258 \************************************************************************/ 259 260 void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/) 261 { 262 mbMovedAtAll = true; 263 } 264 265 /************************************************************************* 266 |* 267 |* Zeichne das Drahtgittermodel 268 |* 269 \************************************************************************/ 270 271 // for migration from XOR to overlay 272 void E3dDragMethod::CreateOverlayGeometry(::sdr::overlay::OverlayManager& rOverlayManager) 273 { 274 const sal_uInt32 nCnt(maGrp.size()); 275 basegfx::B2DPolyPolygon aResult; 276 277 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 278 { 279 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 280 SdrPageView* pPV = getSdrDragView().GetSdrPageView(); 281 282 if(pPV && pPV->HasMarkedObjPageView()) 283 { 284 const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly); 285 const sal_uInt32 nPlyCnt(aCandidate.count()); 286 287 if(nPlyCnt) 288 { 289 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 290 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 291 const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation()); 292 const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform); 293 294 // transform to relative scene coordinates 295 basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform)); 296 297 // transform to 2D view coordinates 298 aPolyPolygon.transform(rVCScene.getObjectTransformation()); 299 300 aResult.append(aPolyPolygon); 301 } 302 } 303 } 304 305 if(aResult.count()) 306 { 307 ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aResult); 308 rOverlayManager.add(*pNew); 309 addToOverlayObjectList(*pNew); 310 } 311 } 312 313 /************************************************************************* 314 315 E3dDragRotate 316 317 *************************************************************************/ 318 319 TYPEINIT1(E3dDragRotate, E3dDragMethod); 320 321 E3dDragRotate::E3dDragRotate(SdrDragView &_rView, 322 const SdrMarkList& rMark, 323 E3dDragConstraint eConstr, 324 sal_Bool bFull) 325 : E3dDragMethod(_rView, rMark, eConstr, bFull) 326 { 327 // Zentrum aller selektierten Objekte in Augkoordinaten holen 328 const sal_uInt32 nCnt(maGrp.size()); 329 330 if(nCnt) 331 { 332 const E3dScene *pScene = maGrp[0].mp3DObj->GetScene(); 333 334 if(pScene) 335 { 336 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); 337 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 338 339 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 340 { 341 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 342 basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter(); 343 const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform); 344 345 aObjCenter = aTransform * aObjCenter; 346 maGlobalCenter += aObjCenter; 347 } 348 349 // Teilen durch Anzahl 350 if(nCnt > 1) 351 { 352 maGlobalCenter /= (double)nCnt; 353 } 354 355 // get rotate center and transform to 3D eye coordinates 356 basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y()); 357 358 // from world to relative scene using inverse getObjectTransformation() 359 basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation()); 360 aInverseObjectTransform.invert(); 361 aRotCenter2D = aInverseObjectTransform * aRotCenter2D; 362 363 // from 3D view to 3D eye 364 basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0); 365 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 366 aInverseViewToEye.invert(); 367 aRotCenter3D = aInverseViewToEye * aRotCenter3D; 368 369 // X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus 370 // Rotationspunkt im Raum benutzen 371 maGlobalCenter.setX(aRotCenter3D.getX()); 372 maGlobalCenter.setY(aRotCenter3D.getY()); 373 } 374 } 375 } 376 377 /************************************************************************* 378 |* 379 |* Das Objekt wird bewegt, bestimme die Winkel 380 |* 381 \************************************************************************/ 382 383 void E3dDragRotate::MoveSdrDrag(const Point& rPnt) 384 { 385 // call parent 386 E3dDragMethod::MoveSdrDrag(rPnt); 387 388 if(DragStat().CheckMinMoved(rPnt)) 389 { 390 // Modifier holen 391 sal_uInt16 nModifier = 0; 392 if(getSdrDragView().ISA(E3dView)) 393 { 394 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); 395 nModifier = rLastMouse.GetModifier(); 396 } 397 398 // Alle Objekte rotieren 399 const sal_uInt32 nCnt(maGrp.size()); 400 401 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 402 { 403 // Rotationswinkel bestimmen 404 double fWAngle, fHAngle; 405 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 406 407 if(E3DDRAG_CONSTR_Z == meConstraint) 408 { 409 fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) - 410 rCandidate.mnStartAngle) - rCandidate.mnLastAngle; 411 rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle; 412 fWAngle /= 100.0; 413 fHAngle = 0.0; 414 } 415 else 416 { 417 fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X()) 418 / (double)maFullBound.GetWidth(); 419 fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y()) 420 / (double)maFullBound.GetHeight(); 421 } 422 long nSnap = 0; 423 424 if(!getSdrDragView().IsRotateAllowed(sal_False)) 425 nSnap = 90; 426 427 if(nSnap != 0) 428 { 429 fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap); 430 fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap); 431 } 432 433 // nach radiant 434 fWAngle *= F_PI180; 435 fHAngle *= F_PI180; 436 437 // Transformation bestimmen 438 basegfx::B3DHomMatrix aRotMat; 439 if(E3DDRAG_CONSTR_Y & meConstraint) 440 { 441 if(nModifier & KEY_MOD2) 442 aRotMat.rotate(0.0, 0.0, fWAngle); 443 else 444 aRotMat.rotate(0.0, fWAngle, 0.0); 445 } 446 else if(E3DDRAG_CONSTR_Z & meConstraint) 447 { 448 if(nModifier & KEY_MOD2) 449 aRotMat.rotate(0.0, fWAngle, 0.0); 450 else 451 aRotMat.rotate(0.0, 0.0, fWAngle); 452 } 453 if(E3DDRAG_CONSTR_X & meConstraint) 454 { 455 aRotMat.rotate(fHAngle, 0.0, 0.0); 456 } 457 458 // Transformation in Eye-Koordinaten, dort rotieren 459 // und zurueck 460 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 461 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 462 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 463 aInverseOrientation.invert(); 464 465 basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform); 466 aTransMat *= aViewInfo3D.getOrientation(); 467 aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ()); 468 aTransMat *= aRotMat; 469 aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ()); 470 aTransMat *= aInverseOrientation; 471 aTransMat *= rCandidate.maInvDisplayTransform; 472 473 // ...und anwenden 474 rCandidate.maTransform *= aTransMat; 475 476 if(mbMoveFull) 477 { 478 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 479 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 480 } 481 else 482 { 483 Hide(); 484 rCandidate.maWireframePoly.transform(aTransMat); 485 Show(); 486 } 487 } 488 maLastPos = rPnt; 489 DragStat().NextMove(rPnt); 490 } 491 } 492 493 /************************************************************************* 494 |* 495 \************************************************************************/ 496 497 Pointer E3dDragRotate::GetSdrDragPointer() const 498 { 499 return Pointer(POINTER_ROTATE); 500 } 501 502 /************************************************************************* 503 |* 504 |* E3dDragMove 505 |* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen 506 |* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod 507 |* nicht verwendet. 508 |* 509 \************************************************************************/ 510 511 TYPEINIT1(E3dDragMove, E3dDragMethod); 512 513 E3dDragMove::E3dDragMove(SdrDragView &_rView, 514 const SdrMarkList& rMark, 515 SdrHdlKind eDrgHdl, 516 E3dDragConstraint eConstr, 517 sal_Bool bFull) 518 : E3dDragMethod(_rView, rMark, eConstr, bFull), 519 meWhatDragHdl(eDrgHdl) 520 { 521 switch(meWhatDragHdl) 522 { 523 case HDL_LEFT: 524 maScaleFixPos = maFullBound.RightCenter(); 525 break; 526 case HDL_RIGHT: 527 maScaleFixPos = maFullBound.LeftCenter(); 528 break; 529 case HDL_UPPER: 530 maScaleFixPos = maFullBound.BottomCenter(); 531 break; 532 case HDL_LOWER: 533 maScaleFixPos = maFullBound.TopCenter(); 534 break; 535 case HDL_UPLFT: 536 maScaleFixPos = maFullBound.BottomRight(); 537 break; 538 case HDL_UPRGT: 539 maScaleFixPos = maFullBound.BottomLeft(); 540 break; 541 case HDL_LWLFT: 542 maScaleFixPos = maFullBound.TopRight(); 543 break; 544 case HDL_LWRGT: 545 maScaleFixPos = maFullBound.TopLeft(); 546 break; 547 default: 548 // Bewegen des Objektes, HDL_MOVE 549 break; 550 } 551 552 // Override wenn IsResizeAtCenter() 553 if(getSdrDragView().IsResizeAtCenter()) 554 { 555 meWhatDragHdl = HDL_USER; 556 maScaleFixPos = maFullBound.Center(); 557 } 558 } 559 560 /************************************************************************* 561 |* 562 |* Das Objekt wird bewegt, bestimme die Translation 563 |* 564 \************************************************************************/ 565 566 void E3dDragMove::MoveSdrDrag(const Point& rPnt) 567 { 568 // call parent 569 E3dDragMethod::MoveSdrDrag(rPnt); 570 571 if(DragStat().CheckMinMoved(rPnt)) 572 { 573 if(HDL_MOVE == meWhatDragHdl) 574 { 575 // Translation 576 // Bewegungsvektor bestimmen 577 basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0); 578 basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0); 579 const sal_uInt32 nCnt(maGrp.size()); 580 581 // Modifier holen 582 sal_uInt16 nModifier(0); 583 584 if(getSdrDragView().ISA(E3dView)) 585 { 586 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); 587 nModifier = rLastMouse.GetModifier(); 588 } 589 590 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 591 { 592 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 593 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 594 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 595 596 // move coor from 2d world to 3d Eye 597 basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y())); 598 basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0); 599 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); 600 601 aInverseSceneTransform.invert(); 602 aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D; 603 aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D; 604 605 basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5); 606 basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5); 607 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 608 aInverseViewToEye.invert(); 609 610 aMoveHead3D = aInverseViewToEye * aMoveHead3D; 611 aMoveTail3D = aInverseViewToEye * aMoveTail3D; 612 613 // eventually switch movement from XY to XZ plane 614 if(nModifier & KEY_MOD2) 615 { 616 double fZwi = aMoveHead3D.getY(); 617 aMoveHead3D.setY(aMoveHead3D.getZ()); 618 aMoveHead3D.setZ(fZwi); 619 620 fZwi = aMoveTail3D.getY(); 621 aMoveTail3D.setY(aMoveTail3D.getZ()); 622 aMoveTail3D.setZ(fZwi); 623 } 624 625 // Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten 626 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 627 aInverseOrientation.invert(); 628 basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation); 629 630 aMoveHead3D = aCompleteTrans * aMoveHead3D; 631 aMoveTail3D = aCompleteTrans* aMoveTail3D; 632 633 // build transformation 634 basegfx::B3DHomMatrix aTransMat; 635 basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D); 636 aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ()); 637 638 // ...and apply 639 rCandidate.maTransform *= aTransMat; 640 641 if(mbMoveFull) 642 { 643 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 644 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 645 } 646 else 647 { 648 Hide(); 649 rCandidate.maWireframePoly.transform(aTransMat); 650 Show(); 651 } 652 } 653 } 654 else 655 { 656 // Skalierung 657 // Skalierungsvektor bestimmen 658 Point aStartPos = DragStat().GetStart(); 659 const sal_uInt32 nCnt(maGrp.size()); 660 661 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 662 { 663 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 664 const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter()); 665 666 // transform from 2D world view to 3D eye 667 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 668 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 669 670 basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y())); 671 basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y())); 672 basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y())); 673 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); 674 675 aInverseSceneTransform.invert(); 676 aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D; 677 aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D; 678 aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D; 679 680 basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ()); 681 basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ()); 682 basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ()); 683 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 684 685 aInverseViewToEye.invert(); 686 basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D); 687 basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D); 688 basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D); 689 690 // constraints? 691 switch(meWhatDragHdl) 692 { 693 case HDL_LEFT: 694 case HDL_RIGHT: 695 // constrain to auf X -> Y equal 696 aScNext.setY(aScFixPos.getY()); 697 break; 698 case HDL_UPPER: 699 case HDL_LOWER: 700 // constrain to auf Y -> X equal 701 aScNext.setX(aScFixPos.getX()); 702 break; 703 default: 704 break; 705 } 706 707 // get scale vector in eye coordinates 708 basegfx::B3DPoint aScaleVec(aScStart - aScFixPos); 709 aScaleVec.setZ(1.0); 710 711 if(aScaleVec.getX() != 0.0) 712 { 713 aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX()); 714 } 715 else 716 { 717 aScaleVec.setX(1.0); 718 } 719 720 if(aScaleVec.getY() != 0.0) 721 { 722 aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY()); 723 } 724 else 725 { 726 aScaleVec.setY(1.0); 727 } 728 729 // SHIFT-key used? 730 if(getSdrDragView().IsOrtho()) 731 { 732 if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY())) 733 { 734 // X is biggest 735 aScaleVec.setY(aScaleVec.getX()); 736 } 737 else 738 { 739 // Y is biggest 740 aScaleVec.setX(aScaleVec.getY()); 741 } 742 } 743 744 // build transformation 745 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 746 aInverseOrientation.invert(); 747 748 basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform; 749 aNewTrans *= rCandidate.maDisplayTransform; 750 aNewTrans *= aViewInfo3D.getOrientation(); 751 aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ()); 752 aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ()); 753 aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ()); 754 aNewTrans *= aInverseOrientation; 755 aNewTrans *= rCandidate.maInvDisplayTransform; 756 757 // ...und anwenden 758 rCandidate.maTransform = aNewTrans; 759 760 if(mbMoveFull) 761 { 762 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 763 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 764 } 765 else 766 { 767 Hide(); 768 rCandidate.maWireframePoly.clear(); 769 rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe(); 770 rCandidate.maWireframePoly.transform(rCandidate.maTransform); 771 Show(); 772 } 773 } 774 } 775 maLastPos = rPnt; 776 DragStat().NextMove(rPnt); 777 } 778 } 779 780 /************************************************************************* 781 |* 782 \************************************************************************/ 783 784 Pointer E3dDragMove::GetSdrDragPointer() const 785 { 786 return Pointer(POINTER_MOVE); 787 } 788 789 // eof 790