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