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::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled( 304 aResult); 305 rOverlayManager.add(*pNew); 306 addToOverlayObjectList(*pNew); 307 } 308 } 309 310 /************************************************************************* 311 312 E3dDragRotate 313 314 *************************************************************************/ 315 316 TYPEINIT1(E3dDragRotate, E3dDragMethod); 317 318 E3dDragRotate::E3dDragRotate(SdrDragView &_rView, 319 const SdrMarkList& rMark, 320 E3dDragConstraint eConstr, 321 sal_Bool bFull) 322 : E3dDragMethod(_rView, rMark, eConstr, bFull) 323 { 324 // Zentrum aller selektierten Objekte in Augkoordinaten holen 325 const sal_uInt32 nCnt(maGrp.size()); 326 327 if(nCnt) 328 { 329 const E3dScene *pScene = maGrp[0].mp3DObj->GetScene(); 330 331 if(pScene) 332 { 333 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact()); 334 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 335 336 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 337 { 338 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 339 basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter(); 340 const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform); 341 342 aObjCenter = aTransform * aObjCenter; 343 maGlobalCenter += aObjCenter; 344 } 345 346 // Teilen durch Anzahl 347 if(nCnt > 1) 348 { 349 maGlobalCenter /= (double)nCnt; 350 } 351 352 // get rotate center and transform to 3D eye coordinates 353 basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y()); 354 355 // from world to relative scene using inverse getObjectTransformation() 356 basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation()); 357 aInverseObjectTransform.invert(); 358 aRotCenter2D = aInverseObjectTransform * aRotCenter2D; 359 360 // from 3D view to 3D eye 361 basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0); 362 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 363 aInverseViewToEye.invert(); 364 aRotCenter3D = aInverseViewToEye * aRotCenter3D; 365 366 // X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus 367 // Rotationspunkt im Raum benutzen 368 maGlobalCenter.setX(aRotCenter3D.getX()); 369 maGlobalCenter.setY(aRotCenter3D.getY()); 370 } 371 } 372 } 373 374 /************************************************************************* 375 |* 376 |* Das Objekt wird bewegt, bestimme die Winkel 377 |* 378 \************************************************************************/ 379 380 void E3dDragRotate::MoveSdrDrag(const Point& rPnt) 381 { 382 // call parent 383 E3dDragMethod::MoveSdrDrag(rPnt); 384 385 if(DragStat().CheckMinMoved(rPnt)) 386 { 387 // Modifier holen 388 sal_uInt16 nModifier = 0; 389 if(getSdrDragView().ISA(E3dView)) 390 { 391 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); 392 nModifier = rLastMouse.GetModifier(); 393 } 394 395 // Alle Objekte rotieren 396 const sal_uInt32 nCnt(maGrp.size()); 397 398 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 399 { 400 // Rotationswinkel bestimmen 401 double fWAngle, fHAngle; 402 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 403 404 if(E3DDRAG_CONSTR_Z == meConstraint) 405 { 406 fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) - 407 rCandidate.mnStartAngle) - rCandidate.mnLastAngle; 408 rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle; 409 fWAngle /= 100.0; 410 fHAngle = 0.0; 411 } 412 else 413 { 414 fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X()) 415 / (double)maFullBound.GetWidth(); 416 fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y()) 417 / (double)maFullBound.GetHeight(); 418 } 419 long nSnap = 0; 420 421 if(!getSdrDragView().IsRotateAllowed(sal_False)) 422 nSnap = 90; 423 424 if(nSnap != 0) 425 { 426 fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap); 427 fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap); 428 } 429 430 // nach radiant 431 fWAngle *= F_PI180; 432 fHAngle *= F_PI180; 433 434 // Transformation bestimmen 435 basegfx::B3DHomMatrix aRotMat; 436 if(E3DDRAG_CONSTR_Y & meConstraint) 437 { 438 if(nModifier & KEY_MOD2) 439 aRotMat.rotate(0.0, 0.0, fWAngle); 440 else 441 aRotMat.rotate(0.0, fWAngle, 0.0); 442 } 443 else if(E3DDRAG_CONSTR_Z & meConstraint) 444 { 445 if(nModifier & KEY_MOD2) 446 aRotMat.rotate(0.0, fWAngle, 0.0); 447 else 448 aRotMat.rotate(0.0, 0.0, fWAngle); 449 } 450 if(E3DDRAG_CONSTR_X & meConstraint) 451 { 452 aRotMat.rotate(fHAngle, 0.0, 0.0); 453 } 454 455 // Transformation in Eye-Koordinaten, dort rotieren 456 // und zurueck 457 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 458 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 459 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 460 aInverseOrientation.invert(); 461 462 basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform); 463 aTransMat *= aViewInfo3D.getOrientation(); 464 aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ()); 465 aTransMat *= aRotMat; 466 aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ()); 467 aTransMat *= aInverseOrientation; 468 aTransMat *= rCandidate.maInvDisplayTransform; 469 470 // ...und anwenden 471 rCandidate.maTransform *= aTransMat; 472 473 if(mbMoveFull) 474 { 475 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 476 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 477 } 478 else 479 { 480 Hide(); 481 rCandidate.maWireframePoly.transform(aTransMat); 482 Show(); 483 } 484 } 485 maLastPos = rPnt; 486 DragStat().NextMove(rPnt); 487 } 488 } 489 490 /************************************************************************* 491 |* 492 \************************************************************************/ 493 494 Pointer E3dDragRotate::GetSdrDragPointer() const 495 { 496 return Pointer(POINTER_ROTATE); 497 } 498 499 /************************************************************************* 500 |* 501 |* E3dDragMove 502 |* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen 503 |* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod 504 |* nicht verwendet. 505 |* 506 \************************************************************************/ 507 508 TYPEINIT1(E3dDragMove, E3dDragMethod); 509 510 E3dDragMove::E3dDragMove(SdrDragView &_rView, 511 const SdrMarkList& rMark, 512 SdrHdlKind eDrgHdl, 513 E3dDragConstraint eConstr, 514 sal_Bool bFull) 515 : E3dDragMethod(_rView, rMark, eConstr, bFull), 516 meWhatDragHdl(eDrgHdl) 517 { 518 switch(meWhatDragHdl) 519 { 520 case HDL_LEFT: 521 maScaleFixPos = maFullBound.RightCenter(); 522 break; 523 case HDL_RIGHT: 524 maScaleFixPos = maFullBound.LeftCenter(); 525 break; 526 case HDL_UPPER: 527 maScaleFixPos = maFullBound.BottomCenter(); 528 break; 529 case HDL_LOWER: 530 maScaleFixPos = maFullBound.TopCenter(); 531 break; 532 case HDL_UPLFT: 533 maScaleFixPos = maFullBound.BottomRight(); 534 break; 535 case HDL_UPRGT: 536 maScaleFixPos = maFullBound.BottomLeft(); 537 break; 538 case HDL_LWLFT: 539 maScaleFixPos = maFullBound.TopRight(); 540 break; 541 case HDL_LWRGT: 542 maScaleFixPos = maFullBound.TopLeft(); 543 break; 544 default: 545 // Bewegen des Objektes, HDL_MOVE 546 break; 547 } 548 549 // Override wenn IsResizeAtCenter() 550 if(getSdrDragView().IsResizeAtCenter()) 551 { 552 meWhatDragHdl = HDL_USER; 553 maScaleFixPos = maFullBound.Center(); 554 } 555 } 556 557 /************************************************************************* 558 |* 559 |* Das Objekt wird bewegt, bestimme die Translation 560 |* 561 \************************************************************************/ 562 563 void E3dDragMove::MoveSdrDrag(const Point& rPnt) 564 { 565 // call parent 566 E3dDragMethod::MoveSdrDrag(rPnt); 567 568 if(DragStat().CheckMinMoved(rPnt)) 569 { 570 if(HDL_MOVE == meWhatDragHdl) 571 { 572 // Translation 573 // Bewegungsvektor bestimmen 574 basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0); 575 basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0); 576 const sal_uInt32 nCnt(maGrp.size()); 577 578 // Modifier holen 579 sal_uInt16 nModifier(0); 580 581 if(getSdrDragView().ISA(E3dView)) 582 { 583 const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent(); 584 nModifier = rLastMouse.GetModifier(); 585 } 586 587 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 588 { 589 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 590 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 591 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 592 593 // move coor from 2d world to 3d Eye 594 basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y())); 595 basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0); 596 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); 597 598 aInverseSceneTransform.invert(); 599 aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D; 600 aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D; 601 602 basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5); 603 basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5); 604 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 605 aInverseViewToEye.invert(); 606 607 aMoveHead3D = aInverseViewToEye * aMoveHead3D; 608 aMoveTail3D = aInverseViewToEye * aMoveTail3D; 609 610 // eventually switch movement from XY to XZ plane 611 if(nModifier & KEY_MOD2) 612 { 613 double fZwi = aMoveHead3D.getY(); 614 aMoveHead3D.setY(aMoveHead3D.getZ()); 615 aMoveHead3D.setZ(fZwi); 616 617 fZwi = aMoveTail3D.getY(); 618 aMoveTail3D.setY(aMoveTail3D.getZ()); 619 aMoveTail3D.setZ(fZwi); 620 } 621 622 // Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten 623 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 624 aInverseOrientation.invert(); 625 basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation); 626 627 aMoveHead3D = aCompleteTrans * aMoveHead3D; 628 aMoveTail3D = aCompleteTrans* aMoveTail3D; 629 630 // build transformation 631 basegfx::B3DHomMatrix aTransMat; 632 basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D); 633 aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ()); 634 635 // ...and apply 636 rCandidate.maTransform *= aTransMat; 637 638 if(mbMoveFull) 639 { 640 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 641 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 642 } 643 else 644 { 645 Hide(); 646 rCandidate.maWireframePoly.transform(aTransMat); 647 Show(); 648 } 649 } 650 } 651 else 652 { 653 // Skalierung 654 // Skalierungsvektor bestimmen 655 Point aStartPos = DragStat().GetStart(); 656 const sal_uInt32 nCnt(maGrp.size()); 657 658 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++) 659 { 660 E3dDragMethodUnit& rCandidate = maGrp[nOb]; 661 const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter()); 662 663 // transform from 2D world view to 3D eye 664 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact()); 665 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D()); 666 667 basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y())); 668 basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y())); 669 basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y())); 670 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation()); 671 672 aInverseSceneTransform.invert(); 673 aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D; 674 aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D; 675 aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D; 676 677 basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ()); 678 basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ()); 679 basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ()); 680 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection()); 681 682 aInverseViewToEye.invert(); 683 basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D); 684 basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D); 685 basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D); 686 687 // constraints? 688 switch(meWhatDragHdl) 689 { 690 case HDL_LEFT: 691 case HDL_RIGHT: 692 // constrain to auf X -> Y equal 693 aScNext.setY(aScFixPos.getY()); 694 break; 695 case HDL_UPPER: 696 case HDL_LOWER: 697 // constrain to auf Y -> X equal 698 aScNext.setX(aScFixPos.getX()); 699 break; 700 default: 701 break; 702 } 703 704 // get scale vector in eye coordinates 705 basegfx::B3DPoint aScaleVec(aScStart - aScFixPos); 706 aScaleVec.setZ(1.0); 707 708 if(aScaleVec.getX() != 0.0) 709 { 710 aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX()); 711 } 712 else 713 { 714 aScaleVec.setX(1.0); 715 } 716 717 if(aScaleVec.getY() != 0.0) 718 { 719 aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY()); 720 } 721 else 722 { 723 aScaleVec.setY(1.0); 724 } 725 726 // SHIFT-key used? 727 if(getSdrDragView().IsOrtho()) 728 { 729 if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY())) 730 { 731 // X is biggest 732 aScaleVec.setY(aScaleVec.getX()); 733 } 734 else 735 { 736 // Y is biggest 737 aScaleVec.setX(aScaleVec.getY()); 738 } 739 } 740 741 // build transformation 742 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation()); 743 aInverseOrientation.invert(); 744 745 basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform; 746 aNewTrans *= rCandidate.maDisplayTransform; 747 aNewTrans *= aViewInfo3D.getOrientation(); 748 aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ()); 749 aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ()); 750 aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ()); 751 aNewTrans *= aInverseOrientation; 752 aNewTrans *= rCandidate.maInvDisplayTransform; 753 754 // ...und anwenden 755 rCandidate.maTransform = aNewTrans; 756 757 if(mbMoveFull) 758 { 759 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj); 760 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform); 761 } 762 else 763 { 764 Hide(); 765 rCandidate.maWireframePoly.clear(); 766 rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe(); 767 rCandidate.maWireframePoly.transform(rCandidate.maTransform); 768 Show(); 769 } 770 } 771 } 772 maLastPos = rPnt; 773 DragStat().NextMove(rPnt); 774 } 775 } 776 777 /************************************************************************* 778 |* 779 \************************************************************************/ 780 781 Pointer E3dDragMove::GetSdrDragPointer() const 782 { 783 return Pointer(POINTER_MOVE); 784 } 785 786 // eof 787