2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* $RCSfile: dragmt3d.cxx,v $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2006-07-25 11:51:14 +00:00
|
|
|
* $Revision: 1.7 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2006-07-25 11:51:14 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2006-07-25 12:51:14 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:37:46 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
// MIB 6.11.97: Die Reihenfolge der Includes mag verwundern, aber in dieser
|
|
|
|
// Reihenfolge geht das durch den SCO GCC, in anderen nicht. Also bitte nicht
|
|
|
|
// an der Reihenfolge drehen, wenn es nicht noetig ist. Das gleiche gilt
|
|
|
|
// natuerlich auch fuer das hinzufuegen von Includes. Danke.
|
|
|
|
|
|
|
|
#ifndef _SHL_HXX //autogen
|
|
|
|
#include <tools/shl.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVDPAGV_HXX //autogen
|
|
|
|
#include "svdpagv.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_DIALMGR_HXX //autogen
|
|
|
|
#include <dialmgr.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _XOUTX_HXX //autogen
|
|
|
|
#include <xoutx.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVDDRGMT_HXX //autogen
|
|
|
|
#include <svddrgmt.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVDTRANS_HXX
|
|
|
|
#include "svdtrans.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _POLY3D_HXX
|
|
|
|
#include "poly3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_MATRIX3D_HXX
|
|
|
|
#include "matrix3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_OBJ3D_HXX
|
|
|
|
#include "obj3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_POLYSC3D_HXX
|
|
|
|
#include "polysc3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_UNDO_HXX
|
|
|
|
#include "e3dundo.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_DRAGMT3D_HXX
|
|
|
|
#include "dragmt3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_DIALOGS_HRC
|
|
|
|
#include "dialogs.hrc"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TYPEINIT1(E3dDragMethod, SdrDragMethod);
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Parameter fuer Interaktion eines 3D-Objektes
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
SV_IMPL_PTRARR(E3dDragMethodUnitGroup, E3dDragMethodUnit*);
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Timing-Qualitaeten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
#define E3D_GOOD_TIME Time(0,0)
|
|
|
|
#define E3D_BAD_TIME Time(0,0,1)
|
|
|
|
#define E3D_WANTED_TIME Time(0,0,0,25)
|
|
|
|
#define E3D_WAITTIME_TIL_REDRAW (5)
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Konstruktor aller 3D-DragMethoden
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
E3dDragMethod::E3dDragMethod (
|
2006-06-19 14:44:35 +00:00
|
|
|
SdrDragView &_rView,
|
2000-09-18 16:07:07 +00:00
|
|
|
const SdrMarkList& rMark,
|
2004-11-03 09:38:11 +00:00
|
|
|
//BFS01E3dDragDetail eDetail,
|
2000-09-18 16:07:07 +00:00
|
|
|
E3dDragConstraint eConstr,
|
|
|
|
BOOL bFull)
|
2006-06-19 14:44:35 +00:00
|
|
|
: SdrDragMethod(_rView),
|
2000-09-18 16:07:07 +00:00
|
|
|
eConstraint(eConstr),
|
2004-11-03 09:38:11 +00:00
|
|
|
//BFS01eDragDetail(eDetail),
|
2000-09-18 16:07:07 +00:00
|
|
|
bMoveFull(bFull),
|
|
|
|
bMovedAtAll(FALSE)
|
|
|
|
{
|
|
|
|
// Fuer alle in der selektion befindlichen 3D-Objekte
|
|
|
|
// eine Unit anlegen
|
|
|
|
long nCnt = rMark.GetMarkCount();
|
|
|
|
for(long nObjs = 0;nObjs < nCnt;nObjs++)
|
|
|
|
{
|
2006-07-25 11:51:14 +00:00
|
|
|
SdrObject *pObj = rMark.GetMark(nObjs)->GetMarkedSdrObj();
|
2000-09-18 16:07:07 +00:00
|
|
|
if(pObj && pObj->ISA(E3dObject))
|
|
|
|
{
|
|
|
|
E3dObject* p3DObj = (E3dObject*)pObj;
|
|
|
|
E3dDragMethodUnit* pNewUnit = new E3dDragMethodUnit;
|
|
|
|
DBG_ASSERT(pNewUnit, "AW: Kein Speicher");
|
|
|
|
|
|
|
|
// Neue Unit einrichten
|
|
|
|
pNewUnit->p3DObj = p3DObj;
|
|
|
|
|
|
|
|
// Transformationen holen
|
|
|
|
pNewUnit->aInitTransform = pNewUnit->aTransform = p3DObj->GetTransform();
|
|
|
|
if(p3DObj->GetParentObj())
|
|
|
|
pNewUnit->aDisplayTransform = p3DObj->GetParentObj()->GetFullTransform();
|
|
|
|
pNewUnit->aInvDisplayTransform = pNewUnit->aDisplayTransform;
|
|
|
|
pNewUnit->aInvDisplayTransform.Invert();
|
|
|
|
|
|
|
|
// SnapRects der beteiligten Objekte invalidieren, um eine
|
|
|
|
// Neuberechnung beim Setzen der Marker zu erzwingen
|
|
|
|
p3DObj->SetRectsDirty();
|
|
|
|
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
// Timings merken
|
|
|
|
pNewUnit->nOrigQuality = p3DObj->GetScene()->GetDisplayQuality();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Drahtgitterdarstellung fuer Parent-Koodinaten erzeugen
|
|
|
|
pNewUnit->aWireframePoly.SetPointCount(0);
|
2004-11-03 09:38:11 +00:00
|
|
|
p3DObj->CreateWireframe(pNewUnit->aWireframePoly, NULL /*BFS01, eDragDetail*/);
|
2000-09-18 16:07:07 +00:00
|
|
|
pNewUnit->aWireframePoly.Transform(pNewUnit->aTransform);
|
|
|
|
}
|
|
|
|
|
|
|
|
// FullBound ermitteln
|
|
|
|
aFullBound.Union(p3DObj->GetSnapRect());
|
|
|
|
|
|
|
|
// Unit einfuegen
|
|
|
|
aGrp.Insert((const E3dDragMethodUnit*&)pNewUnit, aGrp.Count());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Link auf den Timer setzen
|
|
|
|
aCallbackTimer.SetTimeoutHdl( LINK( this, E3dDragMethod, TimerInterruptHdl) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
IMPL_LINK(E3dDragMethod, TimerInterruptHdl, void*, EMPTYARG)
|
|
|
|
{
|
|
|
|
// Alle beteiligten Szenen neu zeichnen
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
E3dScene* pScene = NULL;
|
|
|
|
UINT32 nNewTime(0);
|
|
|
|
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
if(aGrp[nOb]->p3DObj->GetScene() != pScene)
|
|
|
|
{
|
|
|
|
pScene = aGrp[nOb]->p3DObj->GetScene();
|
|
|
|
INT32 nOldQual = pScene->GetDisplayQuality();
|
|
|
|
if(nOldQual != 255)
|
|
|
|
{
|
|
|
|
if(nOldQual == 0)
|
|
|
|
nOldQual = 30;
|
|
|
|
else if(nOldQual <= 64)
|
|
|
|
nOldQual = 64;
|
|
|
|
else
|
|
|
|
nOldQual = 255;
|
|
|
|
|
|
|
|
pScene->SetDisplayQuality((UINT8)nOldQual);
|
2003-11-24 15:35:33 +00:00
|
|
|
pScene->SetChanged();
|
|
|
|
pScene->BroadcastObjectChange();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if(nOldQual != 255)
|
|
|
|
{
|
|
|
|
Time aLast = pScene->GetLastPaintTime();
|
|
|
|
if(nOldQual == 30)
|
|
|
|
nNewTime = aLast.GetTime() * (50 * E3D_WAITTIME_TIL_REDRAW);
|
|
|
|
else
|
|
|
|
nNewTime = aLast.GetTime() * (200 * E3D_WAITTIME_TIL_REDRAW);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(nNewTime)
|
|
|
|
{
|
|
|
|
// Timer reset
|
|
|
|
aCallbackTimer.SetTimeout(nNewTime);
|
|
|
|
aCallbackTimer.Start();
|
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
void E3dDragMethod::TakeComment(XubString& /*rStr*/) const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Erstelle das Drahtgittermodel fuer alle Aktionen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
FASTBOOL E3dDragMethod::Beg()
|
|
|
|
{
|
|
|
|
if(eConstraint == E3DDRAG_CONSTR_Z)
|
|
|
|
{
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
DragStat().Ref1() = aFullBound.Center();
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
aGrp[nOb]->nStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1());
|
|
|
|
aGrp[nOb]->nLastAngle = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aLastPos = DragStat().GetStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!bMoveFull)
|
|
|
|
{
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Schluss
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
FASTBOOL E3dDragMethod::End(FASTBOOL /*bCopy*/)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
// Timer stoppen
|
|
|
|
aCallbackTimer.Stop();
|
|
|
|
|
|
|
|
if(bMovedAtAll)
|
|
|
|
{
|
|
|
|
// Original-Qualitaet restaurieren
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->SetDisplayQuality(aGrp[nOb]->nOrigQuality);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// WireFrame ausblenden
|
|
|
|
Hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Alle Transformationen anwenden und UnDo's anlegen
|
|
|
|
if(bMovedAtAll)
|
|
|
|
{
|
|
|
|
rView.BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE));
|
|
|
|
UINT16 nOb;
|
|
|
|
for(nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
aGrp[nOb]->p3DObj->SetTransform(aGrp[nOb]->aTransform);
|
|
|
|
rView.AddUndo(new E3dRotateUndoAction(aGrp[nOb]->p3DObj->GetModel(),
|
|
|
|
aGrp[nOb]->p3DObj, aGrp[nOb]->aInitTransform,
|
|
|
|
aGrp[nOb]->aTransform));
|
|
|
|
}
|
|
|
|
rView.EndUndo();
|
|
|
|
|
|
|
|
// An allen beteiligten Szenen SnapRect neu setzen und
|
|
|
|
// BoundVolume der Kamera neu bestimmen, da sich die Geometrie
|
|
|
|
// tatsaechlich geaendert haben kann
|
|
|
|
E3dScene* pScene = NULL;
|
|
|
|
for(nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
if(aGrp[nOb]->p3DObj->GetScene() != pScene)
|
|
|
|
{
|
|
|
|
pScene = aGrp[nOb]->p3DObj->GetScene();
|
|
|
|
pScene->CorrectSceneDimensions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Abbruch
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dDragMethod::Brk()
|
|
|
|
{
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
// Timer stoppen
|
|
|
|
aCallbackTimer.Stop();
|
|
|
|
|
|
|
|
if(bMovedAtAll)
|
|
|
|
{
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
// Transformation restaurieren
|
|
|
|
aGrp[nOb]->p3DObj->SetTransform(aGrp[nOb]->aInitTransform);
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->FitSnapRectToBoundVol();
|
|
|
|
|
|
|
|
// Original-Qualitaet restaurieren
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->SetDisplayQuality(aGrp[nOb]->nOrigQuality);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// WireFrame ausblenden
|
|
|
|
Hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Gemeinsames Mov()
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
void E3dDragMethod::Mov(const Point& /*rPnt*/)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
bMovedAtAll = TRUE;
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
UINT32 nNewTime = 0L;
|
|
|
|
|
|
|
|
// Darstellungsqualitaet bestimmen
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
E3dScene* pScene = aGrp[nOb]->p3DObj->GetScene();
|
|
|
|
if(pScene)
|
|
|
|
{
|
|
|
|
Time aLast = pScene->GetLastPaintTime();
|
|
|
|
if(aLast.GetTime())
|
|
|
|
{
|
|
|
|
INT32 nActQual = pScene->GetDisplayQuality();
|
|
|
|
|
|
|
|
// nur weiter ueberlegen, wenn die Qualitaet ueber null liegt
|
|
|
|
if(nActQual)
|
|
|
|
{
|
|
|
|
INT32 nNewQual = nActQual + (E3D_WANTED_TIME.GetTime() - aLast.GetTime());
|
|
|
|
if(nNewQual < 0L)
|
|
|
|
nNewQual = 0L;
|
|
|
|
if(nNewQual > 255L)
|
|
|
|
nNewQual = 255L;
|
|
|
|
pScene->SetDisplayQuality((UINT8)nNewQual);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UINT32 nTime = aLast.GetTime() * (25 * E3D_WAITTIME_TIL_REDRAW);
|
|
|
|
nNewTime = (nTime > nNewTime) ? nTime : nNewTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Timer reset
|
|
|
|
aCallbackTimer.SetTimeout(nNewTime);
|
|
|
|
aCallbackTimer.Start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Zeichne das Drahtgittermodel
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
void E3dDragMethod::DrawXor(XOutputDevice& rXOut, FASTBOOL /*bFull*/) const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
UINT16 nPVCnt = rView.GetPageViewCount();
|
|
|
|
XPolygon aLine(2);
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
B3dCamera& rCameraSet = aGrp[nOb]->p3DObj->GetScene()->GetCameraSet();
|
|
|
|
for (UINT16 a=0;a<nPVCnt;a++)
|
|
|
|
{
|
|
|
|
SdrPageView* pPV = rView.GetPageViewPvNum(a);
|
2004-07-12 13:35:11 +00:00
|
|
|
if(pPV->HasMarkedObjPageView())
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
rXOut.SetOffset(pPV->GetOffset());
|
|
|
|
UINT16 nPntCnt = aGrp[nOb]->aWireframePoly.GetPointCount();
|
|
|
|
if(nPntCnt > 1)
|
|
|
|
{
|
|
|
|
for(UINT16 b=0;b < nPntCnt;b += 2)
|
|
|
|
{
|
|
|
|
Vector3D aPnt1 = aGrp[nOb]->aDisplayTransform * aGrp[nOb]->aWireframePoly[b];
|
|
|
|
aPnt1 = rCameraSet.WorldToViewCoor(aPnt1);
|
|
|
|
aLine[0].X() = (long)(aPnt1.X() + 0.5);
|
|
|
|
aLine[0].Y() = (long)(aPnt1.Y() + 0.5);
|
|
|
|
|
|
|
|
Vector3D aPnt2 = aGrp[nOb]->aDisplayTransform * aGrp[nOb]->aWireframePoly[b+1];
|
|
|
|
aPnt2 = rCameraSet.WorldToViewCoor(aPnt2);
|
|
|
|
aLine[1].X() = (long)(aPnt2.X() + 0.5);
|
|
|
|
aLine[1].Y() = (long)(aPnt2.Y() + 0.5);
|
|
|
|
|
|
|
|
rXOut.DrawXPolyLine(aLine);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|
|
|
|
E3dDragRotate
|
|
|
|
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
TYPEINIT1(E3dDragRotate, E3dDragMethod);
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
E3dDragRotate::E3dDragRotate(SdrDragView &_rView,
|
2000-09-18 16:07:07 +00:00
|
|
|
const SdrMarkList& rMark,
|
2004-11-03 09:38:11 +00:00
|
|
|
//BFS01E3dDragDetail eDetail,
|
2000-09-18 16:07:07 +00:00
|
|
|
E3dDragConstraint eConstr,
|
|
|
|
BOOL bFull)
|
2006-06-19 14:44:35 +00:00
|
|
|
: E3dDragMethod(_rView, rMark/*BFS01, eDetail*/, eConstr, bFull)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Zentrum aller selektierten Objekte in Augkoordinaten holen
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
E3dScene *pScene = NULL;
|
|
|
|
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
Vector3D aObjCenter = aGrp[nOb]->p3DObj->GetCenter();
|
|
|
|
B3dCamera& rCameraSet = aGrp[nOb]->p3DObj->GetScene()->GetCameraSet();
|
|
|
|
aObjCenter *= aGrp[nOb]->aInitTransform;
|
|
|
|
aObjCenter *= aGrp[nOb]->aDisplayTransform;
|
|
|
|
aObjCenter = rCameraSet.WorldToEyeCoor(aObjCenter);
|
|
|
|
aGlobalCenter += aObjCenter;
|
|
|
|
|
|
|
|
if(aGrp[nOb]->p3DObj->ISA(E3dScene))
|
|
|
|
pScene = (E3dScene*)aGrp[nOb]->p3DObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Teilen durch Anzahl
|
|
|
|
if(nCnt > 1)
|
|
|
|
aGlobalCenter /= (double)nCnt;
|
|
|
|
|
|
|
|
// Gruppe schon gesetzt? Sonst gruppe irgendeines Objektes
|
|
|
|
// (erstes) holen
|
|
|
|
if(!pScene && nCnt)
|
|
|
|
{
|
|
|
|
if(aGrp[0]->p3DObj)
|
|
|
|
pScene = aGrp[0]->p3DObj->GetScene();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pScene)
|
|
|
|
{
|
|
|
|
// 2D-Koordinaten des Controls Rotationszentrum holen
|
|
|
|
Point aRotCenter2D = Ref1();
|
|
|
|
|
|
|
|
// In Augkoordinaten transformieren
|
|
|
|
Vector3D aRotCenter(aRotCenter2D.X(), aRotCenter2D.Y(), 0.0);
|
|
|
|
aRotCenter = pScene->GetCameraSet().ViewToEyeCoor(aRotCenter);
|
|
|
|
|
|
|
|
// X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus
|
|
|
|
// Rotationspunkt im Raum benutzen
|
|
|
|
aGlobalCenter.X() = aRotCenter.X();
|
|
|
|
aGlobalCenter.Y() = aRotCenter.Y();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Das Objekt wird bewegt, bestimme die Winkel
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dDragRotate::Mov(const Point& rPnt)
|
|
|
|
{
|
|
|
|
// call parent
|
|
|
|
E3dDragMethod::Mov(rPnt);
|
|
|
|
|
|
|
|
if(DragStat().CheckMinMoved(rPnt))
|
|
|
|
{
|
|
|
|
// Modifier holen
|
|
|
|
UINT16 nModifier = 0;
|
|
|
|
if(rView.ISA(E3dView))
|
|
|
|
{
|
|
|
|
const MouseEvent& rLastMouse = ((E3dView&)rView).GetMouseEvent();
|
|
|
|
nModifier = rLastMouse.GetModifier();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Alle Objekte rotieren
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
// Rotationswinkel bestimmen
|
|
|
|
double fWAngle, fHAngle;
|
|
|
|
|
|
|
|
if(eConstraint == E3DDRAG_CONSTR_Z)
|
|
|
|
{
|
|
|
|
fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) -
|
|
|
|
aGrp[nOb]->nStartAngle) - aGrp[nOb]->nLastAngle;
|
|
|
|
aGrp[nOb]->nLastAngle = (long)fWAngle + aGrp[nOb]->nLastAngle;
|
|
|
|
fWAngle /= 100.0;
|
|
|
|
fHAngle = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fWAngle = 90.0 * (double)(rPnt.X() - aLastPos.X())
|
|
|
|
/ (double)aFullBound.GetWidth();
|
|
|
|
fHAngle = 90.0 * (double)(rPnt.Y() - aLastPos.Y())
|
|
|
|
/ (double)aFullBound.GetHeight();
|
|
|
|
}
|
|
|
|
long nSnap = 0;
|
|
|
|
|
|
|
|
if(!rView.IsRotateAllowed(FALSE))
|
|
|
|
nSnap = 90;
|
|
|
|
|
|
|
|
if(nSnap != 0)
|
|
|
|
{
|
|
|
|
fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap);
|
|
|
|
fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap);
|
|
|
|
}
|
|
|
|
|
|
|
|
// nach radiant
|
|
|
|
fWAngle *= F_PI180;
|
|
|
|
fHAngle *= F_PI180;
|
|
|
|
|
|
|
|
// Transformation bestimmen
|
|
|
|
Matrix4D aRotMat;
|
|
|
|
if(eConstraint & E3DDRAG_CONSTR_Y)
|
|
|
|
{
|
|
|
|
if(nModifier & KEY_MOD2)
|
|
|
|
aRotMat.RotateZ(fWAngle);
|
|
|
|
else
|
|
|
|
aRotMat.RotateY(fWAngle);
|
|
|
|
}
|
|
|
|
else if(eConstraint & E3DDRAG_CONSTR_Z)
|
|
|
|
{
|
|
|
|
if(nModifier & KEY_MOD2)
|
|
|
|
aRotMat.RotateY(fWAngle);
|
|
|
|
else
|
|
|
|
aRotMat.RotateZ(fWAngle);
|
|
|
|
}
|
|
|
|
if(eConstraint & E3DDRAG_CONSTR_X)
|
|
|
|
{
|
|
|
|
aRotMat.RotateX(fHAngle);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Transformation in Eye-Koordinaten, dort rotieren
|
|
|
|
// und zurueck
|
|
|
|
B3dCamera& rCameraSet = aGrp[nOb]->p3DObj->GetScene()->GetCameraSet();
|
|
|
|
Matrix4D aTransMat = aGrp[nOb]->aDisplayTransform;
|
|
|
|
aTransMat *= rCameraSet.GetOrientation();
|
|
|
|
aTransMat.Translate(-aGlobalCenter);
|
|
|
|
aTransMat *= aRotMat;
|
|
|
|
aTransMat.Translate(aGlobalCenter);
|
|
|
|
aTransMat *= rCameraSet.GetInvOrientation();
|
|
|
|
aTransMat *= aGrp[nOb]->aInvDisplayTransform;
|
|
|
|
|
|
|
|
// ...und anwenden
|
|
|
|
aGrp[nOb]->aTransform *= aTransMat;
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
aGrp[nOb]->p3DObj->NbcSetTransform(aGrp[nOb]->aTransform);
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->FitSnapRectToBoundVol();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Hide();
|
|
|
|
aGrp[nOb]->aWireframePoly.Transform(aTransMat);
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aLastPos = rPnt;
|
|
|
|
DragStat().NextMove(rPnt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
Pointer E3dDragRotate::GetPointer() const
|
|
|
|
{
|
|
|
|
return Pointer(POINTER_ROTATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* E3dDragMove
|
|
|
|
|* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen
|
|
|
|
|* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod
|
|
|
|
|* nicht verwendet.
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
TYPEINIT1(E3dDragMove, E3dDragMethod);
|
|
|
|
|
2006-06-19 14:44:35 +00:00
|
|
|
E3dDragMove::E3dDragMove(SdrDragView &_rView,
|
2000-09-18 16:07:07 +00:00
|
|
|
const SdrMarkList& rMark,
|
2004-11-03 09:38:11 +00:00
|
|
|
//BFS01E3dDragDetail eDetail,
|
2000-09-18 16:07:07 +00:00
|
|
|
SdrHdlKind eDrgHdl,
|
|
|
|
E3dDragConstraint eConstr,
|
|
|
|
BOOL bFull)
|
2006-06-19 14:44:35 +00:00
|
|
|
: E3dDragMethod(_rView, rMark, /*BFS01eDetail,*/ eConstr, bFull),
|
2000-09-18 16:07:07 +00:00
|
|
|
eWhatDragHdl(eDrgHdl)
|
|
|
|
{
|
|
|
|
switch(eWhatDragHdl)
|
|
|
|
{
|
|
|
|
case HDL_LEFT:
|
|
|
|
aScaleFixPos = aFullBound.RightCenter();
|
|
|
|
break;
|
|
|
|
case HDL_RIGHT:
|
|
|
|
aScaleFixPos = aFullBound.LeftCenter();
|
|
|
|
break;
|
|
|
|
case HDL_UPPER:
|
|
|
|
aScaleFixPos = aFullBound.BottomCenter();
|
|
|
|
break;
|
|
|
|
case HDL_LOWER:
|
|
|
|
aScaleFixPos = aFullBound.TopCenter();
|
|
|
|
break;
|
|
|
|
case HDL_UPLFT:
|
|
|
|
aScaleFixPos = aFullBound.BottomRight();
|
|
|
|
break;
|
|
|
|
case HDL_UPRGT:
|
|
|
|
aScaleFixPos = aFullBound.BottomLeft();
|
|
|
|
break;
|
|
|
|
case HDL_LWLFT:
|
|
|
|
aScaleFixPos = aFullBound.TopRight();
|
|
|
|
break;
|
|
|
|
case HDL_LWRGT:
|
|
|
|
aScaleFixPos = aFullBound.TopLeft();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// Bewegen des Objektes, HDL_MOVE
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override wenn IsResizeAtCenter()
|
|
|
|
if(rView.IsResizeAtCenter())
|
|
|
|
{
|
|
|
|
eWhatDragHdl = HDL_USER;
|
|
|
|
aScaleFixPos = aFullBound.Center();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Das Objekt wird bewegt, bestimme die Translation
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dDragMove::Mov(const Point& rPnt)
|
|
|
|
{
|
|
|
|
// call parent
|
|
|
|
E3dDragMethod::Mov(rPnt);
|
|
|
|
|
|
|
|
if(DragStat().CheckMinMoved(rPnt))
|
|
|
|
{
|
|
|
|
if(eWhatDragHdl == HDL_MOVE)
|
|
|
|
{
|
|
|
|
// Translation
|
|
|
|
// Bewegungsvektor bestimmen
|
|
|
|
Vector3D aGlobalMoveHead((double)(rPnt.X() - aLastPos.X()),
|
|
|
|
(double)(rPnt.Y() - aLastPos.Y()), 32768.0);
|
|
|
|
Vector3D aGlobalMoveTail(0.0, 0.0, 32768.0);
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
|
|
|
|
// Modifier holen
|
|
|
|
UINT16 nModifier = 0;
|
|
|
|
if(rView.ISA(E3dView))
|
|
|
|
{
|
|
|
|
const MouseEvent& rLastMouse = ((E3dView&)rView).GetMouseEvent();
|
|
|
|
nModifier = rLastMouse.GetModifier();
|
|
|
|
}
|
|
|
|
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
B3dCamera& rCameraSet = aGrp[nOb]->p3DObj->GetScene()->GetCameraSet();
|
|
|
|
|
|
|
|
// Bewegungsvektor von View-Koordinaten nach Aug-Koordinaten
|
|
|
|
Vector3D aMoveHead = rCameraSet.ViewToEyeCoor(aGlobalMoveHead);
|
|
|
|
Vector3D aMoveTail = rCameraSet.ViewToEyeCoor(aGlobalMoveTail);
|
|
|
|
|
|
|
|
// Eventuell Bewegung von XY-Ebene auf XZ-Ebene umschalten
|
|
|
|
if(nModifier & KEY_MOD2)
|
|
|
|
{
|
|
|
|
double fZwi = aMoveHead.Y();
|
|
|
|
aMoveHead.Y() = aMoveHead.Z();
|
|
|
|
aMoveHead.Z() = fZwi;
|
|
|
|
|
|
|
|
fZwi = aMoveTail.Y();
|
|
|
|
aMoveTail.Y() = aMoveTail.Z();
|
|
|
|
aMoveTail.Z() = fZwi;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten
|
|
|
|
aMoveHead = rCameraSet.EyeToWorldCoor(aMoveHead);
|
|
|
|
aMoveHead *= aGrp[nOb]->aInvDisplayTransform;
|
|
|
|
aMoveTail = rCameraSet.EyeToWorldCoor(aMoveTail);
|
|
|
|
aMoveTail *= aGrp[nOb]->aInvDisplayTransform;
|
|
|
|
|
|
|
|
// Transformation bestimmen
|
|
|
|
Matrix4D aTransMat;
|
|
|
|
aTransMat.Translate(aMoveHead - aMoveTail);
|
|
|
|
|
|
|
|
// ...und anwenden
|
|
|
|
aGrp[nOb]->aTransform *= aTransMat;
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
aGrp[nOb]->p3DObj->NbcSetTransform(aGrp[nOb]->aTransform);
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->FitSnapRectToBoundVol();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Hide();
|
|
|
|
aGrp[nOb]->aWireframePoly.Transform(aTransMat);
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Skalierung
|
|
|
|
// Skalierungsvektor bestimmen
|
|
|
|
Point aStartPos = DragStat().GetStart();
|
|
|
|
Vector3D aGlobalScaleStart((double)(aStartPos.X()), (double)(aStartPos.Y()), 32768.0);
|
|
|
|
Vector3D aGlobalScaleNext((double)(rPnt.X()), (double)(rPnt.Y()), 32768.0);
|
|
|
|
Vector3D aGlobalScaleFixPos((double)(aScaleFixPos.X()), (double)(aScaleFixPos.Y()), 32768.0);
|
|
|
|
UINT16 nCnt = aGrp.Count();
|
|
|
|
|
|
|
|
for(UINT16 nOb=0;nOb<nCnt;nOb++)
|
|
|
|
{
|
|
|
|
B3dCamera& rCameraSet = aGrp[nOb]->p3DObj->GetScene()->GetCameraSet();
|
|
|
|
Vector3D aObjectCenter = aGrp[nOb]->p3DObj->GetCenter();
|
|
|
|
aGlobalScaleStart.Z() = aObjectCenter.Z();
|
|
|
|
aGlobalScaleNext.Z() = aObjectCenter.Z();
|
|
|
|
aGlobalScaleFixPos.Z() = aObjectCenter.Z();
|
|
|
|
|
|
|
|
// Skalierungsvektor von View-Koordinaten nach Aug-Koordinaten
|
|
|
|
Vector3D aScStart = rCameraSet.ViewToEyeCoor(aGlobalScaleStart);
|
|
|
|
Vector3D aScNext = rCameraSet.ViewToEyeCoor(aGlobalScaleNext);
|
|
|
|
Vector3D aScFixPos = rCameraSet.ViewToEyeCoor(aGlobalScaleFixPos);
|
|
|
|
|
|
|
|
// Einschraenkungen?
|
|
|
|
switch(eWhatDragHdl)
|
|
|
|
{
|
|
|
|
case HDL_LEFT:
|
|
|
|
case HDL_RIGHT:
|
|
|
|
// Einschraenken auf X -> Y gleichsetzen
|
|
|
|
aScNext.Y() = aScFixPos.Y();
|
|
|
|
break;
|
|
|
|
case HDL_UPPER:
|
|
|
|
case HDL_LOWER:
|
|
|
|
// Einschraenken auf Y -> X gleichsetzen
|
|
|
|
aScNext.X() = aScFixPos.X();
|
|
|
|
break;
|
2006-06-19 14:44:35 +00:00
|
|
|
default:
|
|
|
|
break;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ScaleVector in Augkoordinaten bestimmen
|
|
|
|
Vector3D aScaleVec = aScStart - aScFixPos;
|
|
|
|
aScaleVec.Z() = 1.0;
|
|
|
|
|
|
|
|
if(aScaleVec.X() != 0.0)
|
|
|
|
aScaleVec.X() = (aScNext.X() - aScFixPos.X()) / aScaleVec.X();
|
|
|
|
else
|
|
|
|
aScaleVec.X() = 1.0;
|
|
|
|
|
|
|
|
if(aScaleVec.Y() != 0.0)
|
|
|
|
aScaleVec.Y() = (aScNext.Y() - aScFixPos.Y()) / aScaleVec.Y();
|
|
|
|
else
|
|
|
|
aScaleVec.Y() = 1.0;
|
|
|
|
|
|
|
|
// Mit SHIFT-Taste?
|
|
|
|
if(rView.IsOrtho())
|
|
|
|
{
|
|
|
|
if(fabs(aScaleVec.X()) > fabs(aScaleVec.Y()))
|
|
|
|
{
|
|
|
|
// X ist am groessten
|
|
|
|
aScaleVec.Y() = aScaleVec.X();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Y ist am groessten
|
|
|
|
aScaleVec.X() = aScaleVec.Y();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Transformation bestimmen
|
|
|
|
Matrix4D aNewTrans = aGrp[nOb]->aInitTransform;
|
|
|
|
aNewTrans *= aGrp[nOb]->aDisplayTransform;
|
|
|
|
aNewTrans *= rCameraSet.GetOrientation();
|
|
|
|
aNewTrans.Translate(-aScFixPos);
|
|
|
|
aNewTrans.Scale(aScaleVec);
|
|
|
|
aNewTrans.Translate(aScFixPos);
|
|
|
|
aNewTrans *= rCameraSet.GetInvOrientation();
|
|
|
|
aNewTrans *= aGrp[nOb]->aInvDisplayTransform;
|
|
|
|
|
|
|
|
// ...und anwenden
|
|
|
|
aGrp[nOb]->aTransform = aNewTrans;
|
|
|
|
if(bMoveFull)
|
|
|
|
{
|
|
|
|
aGrp[nOb]->p3DObj->NbcSetTransform(aGrp[nOb]->aTransform);
|
|
|
|
aGrp[nOb]->p3DObj->GetScene()->FitSnapRectToBoundVol();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Hide();
|
|
|
|
aGrp[nOb]->aWireframePoly.SetPointCount(0);
|
2004-11-03 09:38:11 +00:00
|
|
|
aGrp[nOb]->p3DObj->CreateWireframe(aGrp[nOb]->aWireframePoly, NULL/*BFS01, eDragDetail*/);
|
2000-09-18 16:07:07 +00:00
|
|
|
aGrp[nOb]->aWireframePoly.Transform(aGrp[nOb]->aTransform);
|
|
|
|
Show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aLastPos = rPnt;
|
|
|
|
DragStat().NextMove(rPnt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
Pointer E3dDragMove::GetPointer() const
|
|
|
|
{
|
|
|
|
return Pointer(POINTER_MOVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|