xref: /trunk/main/svx/source/engine3d/dragmt3d.cxx (revision 1cd65da9)
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