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
E3dDragMethod(SdrDragView & _rView,const SdrMarkList & rMark,E3dDragConstraint eConstr,sal_Bool bFull)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
TakeSdrDragComment(XubString &) const140 void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const
141 {
142 }
143
144 /*************************************************************************
145 |*
146 |* Erstelle das Drahtgittermodel fuer alle Aktionen
147 |*
148 \************************************************************************/
149
BeginSdrDrag()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
EndSdrDrag(bool)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
CancelSdrDrag()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
MoveSdrDrag(const Point &)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
CreateOverlayGeometry(::sdr::overlay::OverlayManager & rOverlayManager)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
E3dDragRotate(SdrDragView & _rView,const SdrMarkList & rMark,E3dDragConstraint eConstr,sal_Bool bFull)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
MoveSdrDrag(const Point & rPnt)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
GetSdrDragPointer() const494 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
E3dDragMove(SdrDragView & _rView,const SdrMarkList & rMark,SdrHdlKind eDrgHdl,E3dDragConstraint eConstr,sal_Bool bFull)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
MoveSdrDrag(const Point & rPnt)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
GetSdrDragPointer() const781 Pointer E3dDragMove::GetSdrDragPointer() const
782 {
783 return Pointer(POINTER_MOVE);
784 }
785
786 // eof
787