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