2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-08 21:42:33 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:42:33 +00:00
|
|
|
* $RCSfile: scene3d.cxx,v $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2007-05-10 13:47:20 +00:00
|
|
|
* $Revision: 1.30 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2007-05-10 13:47:20 +00:00
|
|
|
* last change: $Author: kz $ $Date: 2007-05-10 14:47:20 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-08 21:42:33 +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:42:33 +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:42:33 +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:42:33 +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:42:33 +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
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-17 03:58:39 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_svx.hxx"
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
#include "svdstr.hrc"
|
|
|
|
#include "svdglob.hxx"
|
|
|
|
|
|
|
|
#ifndef _SVDITER_HXX
|
|
|
|
#include "svditer.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined( UNX ) || defined( ICC )
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_GLOBL3D_HXX
|
|
|
|
#include "globl3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVDPAGE_HXX
|
|
|
|
#include "svdpage.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SFXSTYLE_HXX
|
|
|
|
#include <svtools/style.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_SCENE3D_HXX
|
|
|
|
#include "scene3d.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _E3D_UNDO_HXX
|
|
|
|
#include "e3dundo.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _B3D_BASE3D_HXX
|
|
|
|
#include <goodies/base3d.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVDTRANS_HXX
|
|
|
|
#include "svdtrans.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_SVXIDS_HRC
|
|
|
|
#include "svxids.hrc"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_COLRITEM_HXX
|
|
|
|
#include "colritem.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVXE3DITEM_HXX
|
|
|
|
#include "e3ditem.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_XLNTRIT_HXX
|
|
|
|
#include "xlntrit.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SVX_XFLTRIT_HXX
|
|
|
|
#include "xfltrit.hxx"
|
|
|
|
#endif
|
|
|
|
|
2000-10-30 10:00:01 +00:00
|
|
|
#ifndef _SVX3DITEMS_HXX
|
|
|
|
#include "svx3ditems.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SFX_WHITER_HXX
|
|
|
|
#include <svtools/whiter.hxx>
|
|
|
|
#endif
|
|
|
|
|
2001-06-26 13:04:27 +00:00
|
|
|
#ifndef _SVX_XFLFTRIT_HXX
|
|
|
|
#include "xflftrit.hxx"
|
|
|
|
#endif
|
|
|
|
|
2003-11-24 15:37:52 +00:00
|
|
|
#ifndef _SDR_PROPERTIES_E3DSCENEPROPERTIES_HXX
|
|
|
|
#include <svx/sdr/properties/e3dsceneproperties.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// #110094#
|
|
|
|
#ifndef _SDR_CONTACT_VIEWCONTACTOFE3DSCENE_HXX
|
|
|
|
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
|
|
|
|
#endif
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
#ifndef _SVDDRAG_HXX //autogen
|
|
|
|
#include "svddrag.hxx"
|
|
|
|
#endif
|
|
|
|
|
2004-02-26 16:46:08 +00:00
|
|
|
// for ::std::sort
|
|
|
|
#include <algorithm>
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
|
|
|
|
|
2004-02-26 16:46:08 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// #110988#
|
|
|
|
|
|
|
|
class ImpRemap3DDepth
|
|
|
|
{
|
|
|
|
sal_uInt32 mnOrdNum;
|
|
|
|
double mfMinimalDepth;
|
|
|
|
|
|
|
|
// bitfield
|
|
|
|
unsigned mbIsScene : 1;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth);
|
|
|
|
ImpRemap3DDepth(sal_uInt32 nOrdNum);
|
|
|
|
~ImpRemap3DDepth();
|
|
|
|
|
|
|
|
// for ::std::sort
|
|
|
|
bool operator<(const ImpRemap3DDepth& rComp) const;
|
|
|
|
|
|
|
|
sal_uInt32 GetOrdNum() const { return mnOrdNum; }
|
|
|
|
sal_Bool IsScene() const { return mbIsScene; }
|
|
|
|
};
|
|
|
|
|
|
|
|
ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum, double fMinimalDepth)
|
|
|
|
: mnOrdNum(nOrdNum),
|
|
|
|
mfMinimalDepth(fMinimalDepth),
|
|
|
|
mbIsScene(sal_False)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ImpRemap3DDepth::ImpRemap3DDepth(sal_uInt32 nOrdNum)
|
|
|
|
: mnOrdNum(nOrdNum),
|
|
|
|
mbIsScene(sal_True)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ImpRemap3DDepth::~ImpRemap3DDepth()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ImpRemap3DDepth::operator<(const ImpRemap3DDepth& rComp) const
|
|
|
|
{
|
|
|
|
if(IsScene())
|
|
|
|
{
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(rComp.IsScene())
|
|
|
|
{
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return mfMinimalDepth < rComp.mfMinimalDepth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// typedefs for a vector of ImpRemap3DDepths
|
|
|
|
typedef ::std::vector< ImpRemap3DDepth > ImpRemap3DDepthVector;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// #110988#
|
|
|
|
|
|
|
|
class Imp3DDepthRemapper
|
|
|
|
{
|
|
|
|
ImpRemap3DDepthVector maVector;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Imp3DDepthRemapper(E3dScene& rScene);
|
|
|
|
~Imp3DDepthRemapper();
|
|
|
|
|
|
|
|
sal_uInt32 RemapOrdNum(sal_uInt32 nOrdNum) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
Imp3DDepthRemapper::Imp3DDepthRemapper(E3dScene& rScene)
|
|
|
|
{
|
|
|
|
// only called when rScene.GetSubList() and nObjCount > 1L
|
|
|
|
SdrObjList* pList = rScene.GetSubList();
|
|
|
|
const sal_uInt32 nObjCount(pList->GetObjCount());
|
|
|
|
|
|
|
|
for(sal_uInt32 a(0L); a < nObjCount; a++)
|
|
|
|
{
|
|
|
|
SdrObject* pCandidate = pList->GetObj(a);
|
|
|
|
|
|
|
|
if(pCandidate)
|
|
|
|
{
|
|
|
|
if(pCandidate->ISA(E3dCompoundObject))
|
|
|
|
{
|
|
|
|
// single 3d object, calc depth
|
|
|
|
const double fMinimalDepth(((E3dCompoundObject*)pCandidate)->GetMinimalDepthInViewCoor(rScene));
|
|
|
|
ImpRemap3DDepth aEntry(a, fMinimalDepth);
|
|
|
|
maVector.push_back(aEntry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// scene, use standard entry for scene
|
|
|
|
ImpRemap3DDepth aEntry(a);
|
|
|
|
maVector.push_back(aEntry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now, we need to sort the maVector by it's members minimal depth. The
|
|
|
|
// smaller, the nearer to the viewer.
|
|
|
|
::std::sort(maVector.begin(), maVector.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
Imp3DDepthRemapper::~Imp3DDepthRemapper()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt32 Imp3DDepthRemapper::RemapOrdNum(sal_uInt32 nOrdNum) const
|
|
|
|
{
|
|
|
|
if(nOrdNum < maVector.size())
|
|
|
|
{
|
|
|
|
nOrdNum = maVector[(maVector.size() - 1) - nOrdNum].GetOrdNum();
|
|
|
|
}
|
|
|
|
|
|
|
|
return nOrdNum;
|
|
|
|
}
|
|
|
|
|
2003-11-24 15:37:52 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// BaseProperties section
|
|
|
|
|
|
|
|
sdr::properties::BaseProperties* E3dScene::CreateObjectSpecificProperties()
|
|
|
|
{
|
|
|
|
return new sdr::properties::E3dSceneProperties(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// #110094# DrawContact section
|
|
|
|
|
|
|
|
sdr::contact::ViewContact* E3dScene::CreateObjectSpecificViewContact()
|
|
|
|
{
|
|
|
|
return new sdr::contact::ViewContactOfE3dScene(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
TYPEINIT1(E3dScene, E3dObject);
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* E3dScene-Konstruktor
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
E3dScene::E3dScene()
|
|
|
|
: E3dObject(),
|
2006-11-14 12:21:55 +00:00
|
|
|
aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()),
|
2000-09-18 16:07:07 +00:00
|
|
|
aPaintTime(),
|
|
|
|
nDisplayQuality(255),
|
2004-02-26 16:46:08 +00:00
|
|
|
mp3DDepthRemapper(0L),
|
2006-06-19 14:47:24 +00:00
|
|
|
bDoubleBuffered(FALSE),
|
|
|
|
bClipping(FALSE),
|
|
|
|
bFitInSnapRect(TRUE),
|
2007-05-09 12:31:06 +00:00
|
|
|
bDrawOnlySelected(FALSE),
|
|
|
|
mfPolygonOffset(0.005) // #i71618#
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Defaults setzen
|
|
|
|
E3dDefaultAttributes aDefault;
|
|
|
|
SetDefaultAttributes(aDefault);
|
|
|
|
}
|
|
|
|
|
|
|
|
E3dScene::E3dScene(E3dDefaultAttributes& rDefault)
|
|
|
|
: E3dObject(),
|
2006-11-14 12:21:55 +00:00
|
|
|
aCamera(basegfx::B3DPoint(0.0, 0.0, 4.0), basegfx::B3DPoint()),
|
2000-09-18 16:07:07 +00:00
|
|
|
aPaintTime(),
|
|
|
|
nDisplayQuality(255),
|
2004-02-26 16:46:08 +00:00
|
|
|
mp3DDepthRemapper(0L),
|
2006-06-19 14:47:24 +00:00
|
|
|
bDoubleBuffered(FALSE),
|
|
|
|
bClipping(FALSE),
|
|
|
|
bFitInSnapRect(TRUE),
|
2007-05-09 12:31:06 +00:00
|
|
|
bDrawOnlySelected(FALSE),
|
|
|
|
mfPolygonOffset(0.005) // #i71618#
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Defaults setzen
|
|
|
|
SetDefaultAttributes(rDefault);
|
|
|
|
}
|
|
|
|
|
|
|
|
void E3dScene::SetDefaultAttributes(E3dDefaultAttributes& rDefault)
|
|
|
|
{
|
|
|
|
// Fuer OS/2 die FP-Exceptions abschalten
|
|
|
|
#if defined(OS2)
|
|
|
|
#define SC_FPEXCEPTIONS_ON() _control87( MCW_EM, 0 )
|
|
|
|
#define SC_FPEXCEPTIONS_OFF() _control87( MCW_EM, MCW_EM )
|
|
|
|
SC_FPEXCEPTIONS_OFF();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Fuer WIN95/NT die FP-Exceptions abschalten
|
|
|
|
#if defined(WNT) || defined(WIN)
|
|
|
|
#define SC_FPEXCEPTIONS_ON() _control87( _MCW_EM, 0 )
|
|
|
|
#define SC_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM )
|
|
|
|
SC_FPEXCEPTIONS_OFF();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Defaults setzen
|
2000-11-07 11:58:28 +00:00
|
|
|
|
|
|
|
// set defaults for LightGroup from ItemPool
|
|
|
|
aLightGroup.SetModelTwoSide(GetTwoSidedLighting());
|
|
|
|
aLightGroup.SetIntensity( GetLightColor1(), Base3DMaterialDiffuse, Base3DLight0);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor2(), Base3DMaterialDiffuse, Base3DLight1);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor3(), Base3DMaterialDiffuse, Base3DLight2);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor4(), Base3DMaterialDiffuse, Base3DLight3);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor5(), Base3DMaterialDiffuse, Base3DLight4);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor6(), Base3DMaterialDiffuse, Base3DLight5);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor7(), Base3DMaterialDiffuse, Base3DLight6);
|
|
|
|
aLightGroup.SetIntensity( GetLightColor8(), Base3DMaterialDiffuse, Base3DLight7);
|
|
|
|
aLightGroup.SetGlobalAmbientLight(GetGlobalAmbientColor());
|
|
|
|
aLightGroup.Enable( GetLightOnOff1(), Base3DLight0);
|
|
|
|
aLightGroup.Enable( GetLightOnOff2(), Base3DLight1);
|
|
|
|
aLightGroup.Enable( GetLightOnOff3(), Base3DLight2);
|
|
|
|
aLightGroup.Enable( GetLightOnOff4(), Base3DLight3);
|
|
|
|
aLightGroup.Enable( GetLightOnOff5(), Base3DLight4);
|
|
|
|
aLightGroup.Enable( GetLightOnOff6(), Base3DLight5);
|
|
|
|
aLightGroup.Enable( GetLightOnOff7(), Base3DLight6);
|
|
|
|
aLightGroup.Enable( GetLightOnOff8(), Base3DLight7);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection1(), Base3DLight0);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection2(), Base3DLight1);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection3(), Base3DLight2);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection4(), Base3DLight3);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection5(), Base3DLight4);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection6(), Base3DLight5);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection7(), Base3DLight6);
|
|
|
|
aLightGroup.SetDirection( GetLightDirection8(), Base3DLight7);
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
bDither = rDefault.GetDefaultDither();
|
|
|
|
|
|
|
|
// Alte Werte initialisieren
|
|
|
|
aCamera.SetViewWindow(-2, -2, 4, 4);
|
|
|
|
aCameraSet.SetDeviceRectangle(-2, 2, -2, 2);
|
|
|
|
aCamera.SetDeviceWindow(Rectangle(0, 0, 10, 10));
|
|
|
|
Rectangle aRect(0, 0, 10, 10);
|
|
|
|
aCameraSet.SetViewportRectangle(aRect);
|
|
|
|
|
2000-11-07 11:58:28 +00:00
|
|
|
// set defaults for Camera from ItemPool
|
|
|
|
aCamera.SetProjection(GetPerspective());
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aActualPosition(aCamera.GetPosition());
|
2000-11-07 11:58:28 +00:00
|
|
|
double fNew = GetDistance();
|
2003-11-24 15:37:52 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(fabs(fNew - aActualPosition.getZ()) > 1.0)
|
2003-11-24 15:37:52 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
aCamera.SetPosition( basegfx::B3DPoint( aActualPosition.getX(), aActualPosition.getY(), fNew) );
|
2003-11-24 15:37:52 +00:00
|
|
|
}
|
|
|
|
|
2000-11-07 11:58:28 +00:00
|
|
|
fNew = GetFocalLength() / 100.0;
|
|
|
|
aCamera.SetFocalLength(fNew);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Destruktor
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
E3dScene::~E3dScene()
|
|
|
|
{
|
2004-02-26 16:46:08 +00:00
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
|
|
|
}
|
|
|
|
|
|
|
|
// #110988#
|
|
|
|
void E3dScene::ImpCleanup3DDepthMapper()
|
|
|
|
{
|
|
|
|
if(mp3DDepthRemapper)
|
|
|
|
{
|
|
|
|
delete mp3DDepthRemapper;
|
|
|
|
mp3DDepthRemapper = 0L;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// #110988#
|
2006-06-19 14:47:24 +00:00
|
|
|
sal_uInt32 E3dScene::RemapOrdNum(sal_uInt32 nNewOrdNum) const
|
2004-02-26 16:46:08 +00:00
|
|
|
{
|
|
|
|
if(!mp3DDepthRemapper)
|
|
|
|
{
|
|
|
|
const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L);
|
|
|
|
|
|
|
|
if(nObjCount > 1L)
|
|
|
|
{
|
|
|
|
((E3dScene*)this)->mp3DDepthRemapper = new Imp3DDepthRemapper((E3dScene&)(*this));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mp3DDepthRemapper)
|
|
|
|
{
|
2006-06-19 14:47:24 +00:00
|
|
|
return mp3DDepthRemapper->RemapOrdNum(nNewOrdNum);
|
2004-02-26 16:46:08 +00:00
|
|
|
}
|
|
|
|
|
2006-06-19 14:47:24 +00:00
|
|
|
return nNewOrdNum;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Feststellen, ob die Szene transparente Teile enthaelt
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
BOOL E3dScene::AreThereTransparentParts() const
|
|
|
|
{
|
|
|
|
BOOL bRetval(FALSE);
|
|
|
|
|
|
|
|
SdrObjListIter a3DIterator(*pSub, IM_DEEPWITHGROUPS);
|
|
|
|
while ( !bRetval && a3DIterator.IsMore() )
|
|
|
|
{
|
|
|
|
SdrObject* pObj = a3DIterator.Next();
|
|
|
|
|
|
|
|
// Nur darstellbare Objekte bewerten
|
|
|
|
if(pObj->ISA(E3dCompoundObject))
|
|
|
|
{
|
2001-06-26 13:04:27 +00:00
|
|
|
// get const ItemSet reference
|
2003-11-24 15:37:52 +00:00
|
|
|
const SfxItemSet& rSet = pObj->GetMergedItemSet();
|
2001-06-26 13:04:27 +00:00
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
// Flaechenattribut testen
|
2001-06-26 13:04:27 +00:00
|
|
|
UINT16 nFillTrans = ((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue();
|
|
|
|
if(nFillTrans != 0)
|
2000-10-30 10:00:01 +00:00
|
|
|
bRetval = TRUE;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if(!bRetval)
|
|
|
|
{
|
|
|
|
// Linienattribut testen
|
2001-06-26 13:04:27 +00:00
|
|
|
UINT16 nLineTransparence = ((const XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue();
|
|
|
|
if(nLineTransparence != 0)
|
2000-10-30 10:00:01 +00:00
|
|
|
bRetval = TRUE;
|
2001-06-26 13:04:27 +00:00
|
|
|
|
|
|
|
if(!bRetval)
|
|
|
|
{
|
|
|
|
// test FloatTransparence
|
|
|
|
const XFillFloatTransparenceItem& rFloatTrans = ((const XFillFloatTransparenceItem&)(rSet.Get(XATTR_FILLFLOATTRANSPARENCE)));
|
|
|
|
if(rFloatTrans.IsEnabled())
|
|
|
|
bRetval = TRUE;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bRetval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Identifier zurueckgeben
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
UINT16 E3dScene::GetObjIdentifier() const
|
|
|
|
{
|
|
|
|
return E3D_SCENE_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Anzahl der Handles zurueckgeben
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
sal_uInt32 E3dScene::GetHdlCount() const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Ueberladung aus E3dObject rueckgaengig machen
|
|
|
|
return SdrAttrObj::GetHdlCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Handle-Liste fuellen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::AddToHdlList(SdrHdlList& rHdlList) const
|
|
|
|
{
|
|
|
|
// Ueberladung aus E3dObject rueckgaengig machen
|
|
|
|
SdrAttrObj::AddToHdlList(rHdlList);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
FASTBOOL E3dScene::HasSpecialDrag() const
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* SetSnapRect
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::NbcSetSnapRect(const Rectangle& rRect)
|
|
|
|
{
|
|
|
|
SetRectsDirty();
|
|
|
|
E3dObject::NbcSetSnapRect(rRect);
|
|
|
|
aCamera.SetDeviceWindow(rRect);
|
|
|
|
aCameraSet.SetViewportRectangle((Rectangle&)rRect);
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Objekt verschieben
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::NbcMove(const Size& rSize)
|
|
|
|
{
|
|
|
|
Rectangle aNewSnapRect = GetSnapRect();
|
|
|
|
MoveRect(aNewSnapRect, rSize);
|
|
|
|
NbcSetSnapRect(aNewSnapRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Objekt Resizen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::NbcResize(const Point& rRef, const Fraction& rXFact,
|
|
|
|
const Fraction& rYFact)
|
|
|
|
{
|
|
|
|
Rectangle aNewSnapRect = GetSnapRect();
|
|
|
|
ResizeRect(aNewSnapRect, rRef, rXFact, rYFact);
|
|
|
|
NbcSetSnapRect(aNewSnapRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Neue Kamera setzen, und dabei die Szene und ggf. das BoundVolume
|
|
|
|
|* als geaendert markieren
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SetCamera(const Camera3D& rNewCamera)
|
|
|
|
{
|
|
|
|
// Alte Kamera setzen
|
|
|
|
aCamera = rNewCamera;
|
2003-11-24 15:37:52 +00:00
|
|
|
((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera();
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
SetRectsDirty();
|
|
|
|
|
|
|
|
// Neue Kamera aus alter fuellen
|
|
|
|
Camera3D& rCam = (Camera3D&)GetCamera();
|
|
|
|
|
|
|
|
// Ratio abschalten
|
|
|
|
if(rCam.GetAspectMapping() == AS_NO_MAPPING)
|
|
|
|
GetCameraSet().SetRatio(0.0);
|
|
|
|
|
|
|
|
// Abbildungsgeometrie setzen
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aVRP(rCam.GetViewPoint());
|
|
|
|
basegfx::B3DVector aVPN(aVRP - rCam.GetVRP());
|
|
|
|
basegfx::B3DVector aVUV(rCam.GetVUV());
|
2001-08-15 14:44:02 +00:00
|
|
|
|
|
|
|
// #91047# use SetViewportValues() to set VRP, VPN and VUV as vectors, too.
|
|
|
|
// Else these values would not be exported/imported correctly.
|
|
|
|
GetCameraSet().SetViewportValues(aVRP, aVPN, aVUV);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Perspektive setzen
|
|
|
|
GetCameraSet().SetPerspective(rCam.GetProjection() == PR_PERSPECTIVE);
|
|
|
|
GetCameraSet().SetViewportRectangle((Rectangle&)rCam.GetDeviceWindow());
|
|
|
|
|
|
|
|
// E3dLabel-Objekte muessen neu an die Projektion angepasst werden
|
|
|
|
if ( aLabelList.Count() > 0 )
|
|
|
|
{
|
|
|
|
SetBoundVolInvalid();
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* 3D-Objekt einfuegen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::NewObjectInserted(const E3dObject* p3DObj)
|
|
|
|
{
|
|
|
|
E3dObject::NewObjectInserted(p3DObj);
|
|
|
|
|
|
|
|
if ( p3DObj == this )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( p3DObj->ISA(E3dLabelObj) )
|
|
|
|
{
|
|
|
|
aLabelList.Insert((E3dLabelObj*) p3DObj, LIST_APPEND);
|
|
|
|
}
|
|
|
|
|
|
|
|
// falls Unterobjekte vorhanden sind, auch diese pruefen
|
|
|
|
if ( p3DObj->IsGroupObject() )
|
|
|
|
{
|
|
|
|
SdrObjListIter a3DIterator(*p3DObj, IM_DEEPWITHGROUPS);
|
|
|
|
|
|
|
|
while ( a3DIterator.IsMore() )
|
|
|
|
{
|
|
|
|
SdrObject* pObj = a3DIterator.Next();
|
|
|
|
|
|
|
|
if ( pObj->ISA(E3dLabelObj) )
|
|
|
|
{
|
|
|
|
aLabelList.Insert((E3dLabelObj*) pObj, LIST_APPEND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Parent ueber Aenderung eines Childs informieren
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::StructureChanged(const E3dObject* p3DObj)
|
|
|
|
{
|
|
|
|
E3dObject::StructureChanged(p3DObj);
|
|
|
|
SetRectsDirty();
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Double Buffering aus-/einschalten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SetDoubleBuffered(FASTBOOL bBuff)
|
|
|
|
{
|
|
|
|
if ( bDoubleBuffered != (BOOL)bBuff )
|
|
|
|
{
|
|
|
|
bDoubleBuffered = bBuff;
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Clipping auf umschliessendes Rechteck der Szene aus-/einschalten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SetClipping(FASTBOOL bClip)
|
|
|
|
{
|
|
|
|
if ( bClipping != (BOOL)bClip )
|
|
|
|
{
|
|
|
|
bClipping = bClip;
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Einpassen der Objekte in umschliessendes Rechteck aus-/einschalten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SetFitInSnapRect(FASTBOOL bFit)
|
|
|
|
{
|
|
|
|
if ( bFitInSnapRect != (BOOL)bFit )
|
|
|
|
{
|
|
|
|
bFitInSnapRect = bFit;
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Einpassen der Projektion aller Szenenobjekte in das
|
|
|
|
|* umschliessende Rechteck
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DRange E3dScene::FitInSnapRect()
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DRange aNewVol;
|
|
|
|
const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(nObjCount)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
// Alter Kram
|
|
|
|
basegfx::B3DHomMatrix aFullTrans(GetFullTransform());
|
|
|
|
aCamera.FitViewToVolume(GetBoundVolume(), aFullTrans);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Neuer Kram
|
|
|
|
// Maximas holen in Augkoordinaten zwecks Z-Werten
|
|
|
|
basegfx::B3DPoint aTfVec;
|
|
|
|
Vol3DPointIterator aIter(GetBoundVolume());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
GetCameraSet().SetObjectTrans(aFullTrans);
|
|
|
|
|
|
|
|
while ( aIter.Next(aTfVec) )
|
|
|
|
{
|
|
|
|
aTfVec = GetCameraSet().ObjectToEyeCoor(aTfVec);
|
|
|
|
aNewVol.expand(aTfVec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ... und merken
|
|
|
|
double fZMin(-aNewVol.getMaxZ());
|
|
|
|
double fZMax(-aNewVol.getMinZ());
|
|
|
|
|
|
|
|
// Jetzt XY-Werte projizieren auf Projektionsflaeche
|
|
|
|
// in Device-Koordinaten
|
|
|
|
basegfx::B3DHomMatrix aWorldToDevice(GetCameraSet().GetOrientation());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if(aCamera.GetProjection() == PR_PERSPECTIVE)
|
2006-11-14 12:21:55 +00:00
|
|
|
{
|
|
|
|
aWorldToDevice.frustum(-1.0, 1.0, -1.0, 1.0, fZMin, fZMax);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
2006-11-14 12:21:55 +00:00
|
|
|
{
|
|
|
|
aWorldToDevice.ortho(-1.0, 1.0, -1.0, 1.0, fZMin, fZMax);
|
|
|
|
}
|
|
|
|
|
|
|
|
aNewVol.reset();
|
|
|
|
aIter.Reset();
|
|
|
|
|
|
|
|
while ( aIter.Next(aTfVec) )
|
|
|
|
{
|
|
|
|
aTfVec = GetCameraSet().ObjectToWorldCoor(aTfVec);
|
|
|
|
aTfVec *= aWorldToDevice;
|
|
|
|
aNewVol.expand(aTfVec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Labels behandeln
|
|
|
|
const sal_uInt32 nLabelCnt(aLabelList.Count());
|
|
|
|
|
|
|
|
if ( nLabelCnt )
|
|
|
|
{
|
|
|
|
// Vorlaeufige Projektion bestimmen und Transformation in
|
|
|
|
// ViewKoordinaten bestimmen
|
|
|
|
basegfx::B3DHomMatrix aMatWorldToView(GetCameraSet().GetOrientation());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(aCamera.GetProjection() == PR_PERSPECTIVE)
|
|
|
|
{
|
|
|
|
aMatWorldToView.frustum(aNewVol.getMinX(), aNewVol.getMaxX(), aNewVol.getMinY(), aNewVol.getMaxY(), fZMin, fZMax);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aMatWorldToView.ortho(aNewVol.getMinX(), aNewVol.getMaxX(), aNewVol.getMinY(), aNewVol.getMaxY(), fZMin, fZMax);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Logische Abmessungen der Szene holen
|
|
|
|
Rectangle aSceneRect = GetSnapRect();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Matrix DeviceToView aufbauen
|
|
|
|
basegfx::B3DPoint aTranslate, aScale;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
aTranslate.setX((double)aSceneRect.Left() + (aSceneRect.GetWidth() / 2.0));
|
|
|
|
aTranslate.setY((double)aSceneRect.Top() + (aSceneRect.GetHeight() / 2.0));
|
|
|
|
aTranslate.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Skalierung
|
|
|
|
aScale.setX((aSceneRect.GetWidth() - 1) / 2.0);
|
|
|
|
aScale.setY((aSceneRect.GetHeight() - 1) / -2.0);
|
|
|
|
aScale.setZ(ZBUFFER_DEPTH_RANGE / 2.0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
aMatWorldToView.scale(aScale.getX(), aScale.getY(), aScale.getZ());
|
|
|
|
aMatWorldToView.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Inverse Matrix ViewToDevice aufbauen
|
|
|
|
basegfx::B3DHomMatrix aMatViewToWorld(aMatWorldToView);
|
|
|
|
aMatViewToWorld.invert();
|
|
|
|
|
|
|
|
for (sal_uInt32 i = 0; i < nLabelCnt; i++)
|
|
|
|
{
|
|
|
|
E3dLabelObj* p3DObj = aLabelList.GetObject(i);
|
|
|
|
const SdrObject* pObj = p3DObj->Get2DLabelObj();
|
|
|
|
|
|
|
|
// View- Abmessungen des Labels holen
|
|
|
|
const Rectangle& rObjRect = pObj->GetLogicRect();
|
|
|
|
|
|
|
|
// Position des Objektes in Weltkoordinaten ermitteln
|
|
|
|
basegfx::B3DHomMatrix aObjTrans(p3DObj->GetFullTransform());
|
|
|
|
// Here, without the 'B3DPoint operator*( const B3DHomMatrix& rMat, const B3DPoint& rPoint )'
|
|
|
|
// from b3dpoint.hxx, the wrong multiplication is taken (the one with B3DVector). This
|
|
|
|
// leads to wrong results since tre translation is not added to vector-matrix multiplications.
|
|
|
|
basegfx::B3DPoint aObjPos(aObjTrans * p3DObj->GetPosition());
|
|
|
|
|
|
|
|
// View-Position des Objektes feststellen
|
|
|
|
// nach ViewKoordinaten
|
|
|
|
aObjPos *= aMatWorldToView;
|
|
|
|
|
|
|
|
// Relative Position des Labels in View-Koordinaten
|
|
|
|
basegfx::B3DPoint aRelPosOne(
|
|
|
|
pObj->GetRelativePos().X() + aObjPos.getX(),
|
|
|
|
pObj->GetRelativePos().Y() + aObjPos.getY(),
|
|
|
|
aObjPos.getZ());
|
|
|
|
|
|
|
|
basegfx::B3DPoint aRelPosTwo(
|
|
|
|
aRelPosOne.getX() + (double)rObjRect.GetWidth(),
|
|
|
|
aRelPosOne.getY() + (double)rObjRect.GetHeight(),
|
|
|
|
aRelPosOne.getZ());
|
|
|
|
|
|
|
|
// Jetzt Eckpunkte in DeviceKoordinaten bestimmen und
|
|
|
|
// den Abmessungen hinzufuegen
|
|
|
|
aRelPosOne *= aMatViewToWorld;
|
|
|
|
aRelPosOne *= aWorldToDevice;
|
|
|
|
aNewVol.expand(aRelPosOne);
|
|
|
|
|
|
|
|
aRelPosTwo *= aMatViewToWorld;
|
|
|
|
aRelPosTwo *= aWorldToDevice;
|
|
|
|
aNewVol.expand(aRelPosTwo);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Z-Werte eintragen
|
|
|
|
aNewVol = basegfx::B3DRange(aNewVol.getMinX(), aNewVol.getMinY(), fZMin, aNewVol.getMaxX(), aNewVol.getMaxY(), fZMax);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-02-26 16:46:08 +00:00
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
// Rueckgabewert setzen
|
|
|
|
return aNewVol;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Uebergeordnetes Szenenobjekt bestimmen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
E3dScene* E3dScene::GetScene() const
|
|
|
|
{
|
|
|
|
if(GetParentObj())
|
|
|
|
return GetParentObj()->GetScene();
|
|
|
|
else
|
|
|
|
return (E3dScene*)this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* TransformationSet vorbereiten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::InitTransformationSet()
|
|
|
|
{
|
|
|
|
Rectangle aBound(GetSnapRect());
|
|
|
|
|
|
|
|
// GeometricSet reset und mit pBase3D assoziieren
|
|
|
|
B3dCamera& rSet = GetCameraSet();
|
|
|
|
|
|
|
|
// Transformation auf Weltkoordinaten holen
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DHomMatrix mTransform = GetFullTransform();
|
2000-09-18 16:07:07 +00:00
|
|
|
rSet.SetObjectTrans(mTransform);
|
|
|
|
|
|
|
|
// 3D Ausgabe vorbereiten, Maximas holen in DeviceKoordinaten
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DRange aVolume(FitInSnapRect());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Maximas fuer Abbildung verwenden
|
|
|
|
rSet.SetDeviceVolume(aVolume, FALSE);
|
|
|
|
rSet.SetViewportRectangle(aBound);
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Einpassen der Objekte in umschliessendes Rechteck aus-/einschalten
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::FitSnapRectToBoundVol()
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aTfVec;
|
2000-09-18 16:07:07 +00:00
|
|
|
Volume3D aFitVol;
|
|
|
|
|
|
|
|
SetBoundVolInvalid();
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DHomMatrix aTransform = aCamera.GetViewTransform() * GetFullTransform(); // #112587#
|
2000-09-18 16:07:07 +00:00
|
|
|
Vol3DPointIterator aIter(GetBoundVolume(), &aTransform);
|
|
|
|
Rectangle aRect;
|
|
|
|
|
|
|
|
while ( aIter.Next(aTfVec) )
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
aTfVec = aCamera.DoProjection(aTfVec);
|
|
|
|
aFitVol.expand(aTfVec);
|
|
|
|
basegfx::B3DPoint aZwi(aCamera.MapToDevice(aTfVec));
|
|
|
|
Point aP((long)aZwi.getX(), (long)aZwi.getY());
|
2000-09-18 16:07:07 +00:00
|
|
|
aRect.Union(Rectangle(aP, aP));
|
|
|
|
}
|
2006-11-14 12:21:55 +00:00
|
|
|
aCamera.SetViewWindow(aFitVol.getMinX(), aFitVol.getMinY(), aFitVol.getWidth(), aFitVol.getHeight());
|
2000-09-18 16:07:07 +00:00
|
|
|
SetSnapRect(aRect);
|
|
|
|
|
|
|
|
// Die SnapRects aller beteiligten Objekte muessen auf dieser
|
|
|
|
// veraenderten Basis aufgebaut werden, invalidiere diese. Das
|
|
|
|
// eigene kann auch invalidiert werden, da ein RecalcSnapRect
|
|
|
|
// an einer Szene nur aus der Kamera liest
|
|
|
|
SetRectsDirty();
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Falls die Geometrie einer Szene sich ausgedehnt/vermindert hat,
|
|
|
|
|* muss das Volume und das SnapRect angepasst werden
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::CorrectSceneDimensions()
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
const sal_uInt32 nObjCount(GetSubList() ? GetSubList()->GetObjCount() : 0L);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(nObjCount)
|
|
|
|
{
|
|
|
|
// SnapRects der Objekte ungueltig
|
|
|
|
SetRectsDirty();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// SnapRect anpassen, invalidiert auch die SnapRects
|
|
|
|
// der enthaltenen Objekte
|
|
|
|
FitSnapRectToBoundVol();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Neues BoundVolume der Kamera holen
|
|
|
|
basegfx::B3DRange aVolume(FitInSnapRect());
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
// Neues BoundVolume an der Kamera setzen
|
|
|
|
GetCameraSet().SetDeviceVolume(aVolume, FALSE);
|
|
|
|
|
|
|
|
// Danach noch die SnapRects der enthaltenen Objekte
|
|
|
|
// invalidieren, um diese auf der neuen Grundlage berechnen
|
|
|
|
// zu lassen (falls diese von FitInSnapRect() berechnet wurden)
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Zuweisungsoperator
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::operator=(const SdrObject& rObj)
|
|
|
|
{
|
|
|
|
E3dObject::operator=(rObj);
|
|
|
|
|
|
|
|
const E3dScene& r3DObj = (const E3dScene&) rObj;
|
|
|
|
aCamera = r3DObj.aCamera;
|
|
|
|
bDoubleBuffered = r3DObj.bDoubleBuffered;
|
|
|
|
bClipping = r3DObj.bClipping;
|
|
|
|
bFitInSnapRect = r3DObj.bFitInSnapRect;
|
|
|
|
|
|
|
|
// neu ab 377:
|
|
|
|
aCameraSet = r3DObj.aCameraSet;
|
2003-11-24 15:37:52 +00:00
|
|
|
((sdr::properties::E3dSceneProperties&)GetProperties()).SetSceneItemsFromCamera();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// neu ab 383:
|
|
|
|
aLightGroup = r3DObj.aLightGroup;
|
2003-11-24 15:37:52 +00:00
|
|
|
((sdr::properties::E3dSceneProperties&)GetProperties()).SetLightItemsFromLightGroup(aLightGroup);
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
bDither = r3DObj.bDither;
|
|
|
|
|
|
|
|
bBoundVolValid = FALSE;
|
|
|
|
RebuildLists();
|
|
|
|
|
|
|
|
SetRectsDirty();
|
2004-02-26 16:46:08 +00:00
|
|
|
|
|
|
|
// #110988#
|
|
|
|
ImpCleanup3DDepthMapper();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Licht- und Labelobjektlisten neu aufbauen (nach Laden, Zuweisung)
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::RebuildLists()
|
|
|
|
{
|
|
|
|
// zuerst loeschen
|
|
|
|
aLabelList.Clear();
|
2006-06-19 14:47:24 +00:00
|
|
|
SdrLayerID nCurrLayerID = GetLayer();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
SdrObjListIter a3DIterator(*pSub, IM_FLAT);
|
|
|
|
|
|
|
|
// dann alle Objekte in der Szene pruefen
|
|
|
|
while ( a3DIterator.IsMore() )
|
|
|
|
{
|
|
|
|
E3dObject* p3DObj = (E3dObject*) a3DIterator.Next();
|
2006-06-19 14:47:24 +00:00
|
|
|
p3DObj->NbcSetLayer(nCurrLayerID);
|
2000-09-18 16:07:07 +00:00
|
|
|
NewObjectInserted(p3DObj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* erstelle neues GeoData-Objekt
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
SdrObjGeoData *E3dScene::NewGeoData() const
|
|
|
|
{
|
|
|
|
return new E3DSceneGeoData;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* uebergebe aktuelle werte an das GeoData-Objekt
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SaveGeoData(SdrObjGeoData& rGeo) const
|
|
|
|
{
|
|
|
|
E3dObject::SaveGeoData (rGeo);
|
|
|
|
|
|
|
|
((E3DSceneGeoData &) rGeo).aCamera = aCamera;
|
|
|
|
((E3DSceneGeoData &) rGeo).aLabelList = aLabelList;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* uebernehme werte aus dem GeoData-Objekt
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::RestGeoData(const SdrObjGeoData& rGeo)
|
|
|
|
{
|
|
|
|
E3dObject::RestGeoData (rGeo);
|
|
|
|
|
|
|
|
aLabelList = ((E3DSceneGeoData &) rGeo).aLabelList;
|
|
|
|
SetCamera (((E3DSceneGeoData &) rGeo).aCamera);
|
|
|
|
FitSnapRectToBoundVol();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Am StyleSheet wurde etwas geaendert, also Scene aendern
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::SFX_NOTIFY(SfxBroadcaster &rBC,
|
|
|
|
const TypeId &rBCType,
|
|
|
|
const SfxHint &rHint,
|
|
|
|
const TypeId &rHintType)
|
|
|
|
{
|
|
|
|
SetRectsDirty();
|
|
|
|
E3dObject::SFX_NOTIFY(rBC, rBCType, rHint, rHintType);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
2006-06-19 14:47:24 +00:00
|
|
|
void E3dScene::RotateScene (const Point& rRef, long /*nWink*/, double sn, double cs)
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
Point UpperLeft, LowerRight, Center, NewCenter;
|
|
|
|
|
|
|
|
UpperLeft = aOutRect.TopLeft();
|
|
|
|
LowerRight = aOutRect.BottomRight();
|
|
|
|
|
|
|
|
long dxOutRectHalf = labs(UpperLeft.X() - LowerRight.X());
|
|
|
|
dxOutRectHalf /= 2;
|
|
|
|
long dyOutRectHalf = labs(UpperLeft.Y() - LowerRight.Y());
|
|
|
|
dyOutRectHalf /= 2;
|
|
|
|
|
|
|
|
Rectangle RectQuelle(aOutRect), RectZiel(aOutRect);
|
|
|
|
|
|
|
|
// Nur der Mittelpunkt wird bewegt. Die Ecken werden von NbcMove bewegt.
|
|
|
|
// Fuer das Drehen wird von mir ein kartesisches Koordinatensystem verwendet in dem der Drehpunkt
|
|
|
|
// der Nullpunkt ist und die Y- Achse nach oben ansteigt, die X-Achse nach rechts.
|
|
|
|
// Dies muss bei den Y-Werten beachtet werden. (Auf dem Blatt zeigt die Y-Achse nach unten
|
|
|
|
Center.X() = (UpperLeft.X() + dxOutRectHalf) - rRef.X();
|
|
|
|
Center.Y() = -((UpperLeft.Y() + dyOutRectHalf) - rRef.Y());
|
|
|
|
// Ein paar Spezialfaelle zuerst abhandeln (n*90 Grad n ganzzahlig)
|
2005-02-16 16:55:24 +00:00
|
|
|
if (sn==1.0 && cs==0.0) { // 90deg
|
2000-09-18 16:07:07 +00:00
|
|
|
NewCenter.X() = -Center.Y();
|
|
|
|
NewCenter.Y() = -Center.X();
|
2005-02-16 16:55:24 +00:00
|
|
|
} else if (sn==0.0 && cs==-1.0) { // 180deg
|
2000-09-18 16:07:07 +00:00
|
|
|
NewCenter.X() = -Center.X();
|
|
|
|
NewCenter.Y() = -Center.Y();
|
2005-02-16 16:55:24 +00:00
|
|
|
} else if (sn==-1.0 && cs==0.0) { // 270deg
|
2000-09-18 16:07:07 +00:00
|
|
|
NewCenter.X() = Center.Y();
|
|
|
|
NewCenter.Y() = -Center.X();
|
|
|
|
}
|
|
|
|
else // Hier wird um einen beliebigen Winkel in mathematisch positiver Richtung gedreht!
|
|
|
|
{ // xneu = x * cos(alpha) - y * sin(alpha)
|
|
|
|
// yneu = x * sin(alpha) + y * cos(alpha)
|
|
|
|
// Unten Rechts wird nicht gedreht: die Seiten von RectQuelle muessen parallel
|
|
|
|
// zu den Koordinatenachsen bleiben.
|
|
|
|
NewCenter.X() = (long) (Center.X() * cs - Center.Y() * sn);
|
|
|
|
NewCenter.Y() = (long) (Center.X() * sn + Center.Y() * cs);
|
|
|
|
}
|
|
|
|
|
|
|
|
Size Differenz;
|
|
|
|
Point DiffPoint = (NewCenter - Center);
|
|
|
|
Differenz.Width() = DiffPoint.X();
|
|
|
|
Differenz.Height() = -DiffPoint.Y(); // Man beachte dass die Y-Achse nach unten positiv gezaehlt wird.
|
|
|
|
NbcMove (Differenz); // fuehrt die eigentliche Koordinatentransformation durch.
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Get the name of the object (singular)
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::TakeObjNameSingul(XubString& rName) const
|
|
|
|
{
|
|
|
|
rName=ImpGetResStr(STR_ObjNameSingulScene3d);
|
2002-06-07 11:08:48 +00:00
|
|
|
|
|
|
|
String aName( GetName() );
|
|
|
|
if(aName.Len())
|
|
|
|
{
|
|
|
|
rName += sal_Unicode(' ');
|
|
|
|
rName += sal_Unicode('\'');
|
|
|
|
rName += aName;
|
|
|
|
rName += sal_Unicode('\'');
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Get the name of the object (plural)
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::TakeObjNamePlural(XubString& rName) const
|
|
|
|
{
|
|
|
|
rName=ImpGetResStr(STR_ObjNamePluralScene3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
2005-02-16 16:55:24 +00:00
|
|
|
|* Die NbcRotate-Routine ueberlaedt die des SdrObject. Die Idee ist die Scene
|
2000-09-18 16:07:07 +00:00
|
|
|
|* drehen zu koennen und relativ zur Lage der Scene dann auch die Objekte
|
|
|
|
|* in der Scene
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
|
|
|
|
{
|
|
|
|
// Also derzeit sind die Klebepunkte relativ zum aOutRect der Szene definiert. Vor dem Drehen
|
|
|
|
// werden die Klebepunkte relativ zur Seite definiert. Sie nehmen an der Drehung der Szene noch nicht Teil
|
|
|
|
// dafuer gibt es den
|
|
|
|
SetGlueReallyAbsolute(TRUE);
|
|
|
|
|
|
|
|
// So dass war die Szene, ab jetzt kommen die Objekte in der Szene
|
2005-02-16 16:55:24 +00:00
|
|
|
// 3D-Objekte gibt es nur ein einziges das kann zwar mehrere Flaechen haben aber die Flaechen
|
2000-09-18 16:07:07 +00:00
|
|
|
// muessen ja nicht zusammenhaengend sein
|
|
|
|
// es ermoeglicht den Zugriff auf Kindobjekte
|
|
|
|
// Ich gehe also die gesamte Liste durch und rotiere um die Z-Achse die durch den
|
|
|
|
// Mittelpunkt von aOutRect geht (Satz von Steiner), also RotateZ
|
|
|
|
|
|
|
|
RotateScene (rRef, nWink, sn, cs); // Rotiert die Szene
|
|
|
|
double fWinkelInRad = nWink/100 * F_PI180;
|
|
|
|
NbcRotateZ(fWinkelInRad);
|
|
|
|
FitSnapRectToBoundVol();
|
|
|
|
SetRectsDirty(); // Veranlasst eine Neuberechnung aller BoundRects
|
|
|
|
NbcRotateGluePoints(rRef,nWink,sn,cs); // Rotiert die Klebepunkte (die haben noch Koordinaten relativ
|
|
|
|
// zum Urpsung des Blattes
|
|
|
|
SetGlueReallyAbsolute(FALSE); // ab jetzt sind sie wieder relativ zum BoundRect (also dem aOutRect definiert)
|
|
|
|
SetRectsDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* SnapRect berechnen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
void E3dScene::RecalcSnapRect()
|
|
|
|
{
|
|
|
|
E3dScene* pScene = GetScene();
|
|
|
|
if(pScene == this)
|
|
|
|
{
|
|
|
|
// Szene wird als 2D-Objekt benutzt, nimm SnapRect aus der
|
|
|
|
// 2D Bildschrimdarstellung
|
|
|
|
Camera3D& rCam = (Camera3D&)pScene->GetCamera();
|
2000-10-30 10:00:01 +00:00
|
|
|
maSnapRect = rCam.GetDeviceWindow();
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Szene ist selbst Mitglied einer anderen Szene, hole das
|
|
|
|
// SnapRect als zusammengesetztes Objekt
|
|
|
|
E3dObject::RecalcSnapRect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
|*
|
|
|
|
|* Aufbrechen
|
|
|
|
|*
|
|
|
|
\************************************************************************/
|
|
|
|
|
|
|
|
BOOL E3dScene::IsBreakObjPossible()
|
|
|
|
{
|
|
|
|
// Szene ist aufzubrechen, wenn alle Mitglieder aufzubrechen sind
|
|
|
|
SdrObjList* pSubList = GetSubList();
|
|
|
|
if(pSubList)
|
|
|
|
{
|
|
|
|
SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS);
|
|
|
|
while ( a3DIterator.IsMore() )
|
|
|
|
{
|
|
|
|
E3dObject* pObj = (E3dObject*) a3DIterator.Next();
|
|
|
|
DBG_ASSERT(pObj->ISA(E3dObject), "AW: In Szenen sind nur 3D-Objekte erlaubt!");
|
|
|
|
if(!pObj->IsBreakObjPossible())
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DVector E3dScene::GetShadowPlaneDirection() const
|
2000-10-30 10:00:01 +00:00
|
|
|
{
|
2000-11-07 11:58:28 +00:00
|
|
|
double fWink = (double)GetShadowSlant() * F_PI180;
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DVector aShadowPlaneDir(0.0, sin(fWink), cos(fWink));
|
|
|
|
aShadowPlaneDir.normalize();
|
2000-11-07 11:58:28 +00:00
|
|
|
return aShadowPlaneDir;
|
2000-10-30 10:00:01 +00:00
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
void E3dScene::SetShadowPlaneDirection(const basegfx::B3DVector& rVec)
|
2000-10-30 10:00:01 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
UINT16 nSceneShadowSlant = (UINT16)((atan2(rVec.getY(), rVec.getZ()) / F_PI180) + 0.5);
|
2003-11-24 15:37:52 +00:00
|
|
|
GetProperties().SetObjectItemDirect(Svx3DShadowSlantItem(nSceneShadowSlant));
|
2000-10-30 10:00:01 +00:00
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
// #115662#
|
|
|
|
// helper class for in-between results from E3dScene::HitTest
|
|
|
|
class ImplPairDephAndObject
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SdrObject* pObject;
|
|
|
|
double fDepth;
|
|
|
|
|
|
|
|
// for ::std::sort
|
|
|
|
bool operator<(const ImplPairDephAndObject& rComp) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool ImplPairDephAndObject::operator<(const ImplPairDephAndObject& rComp) const
|
|
|
|
{
|
|
|
|
if(fDepth < rComp.fDepth)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// #115662#
|
|
|
|
// For new chart, calculate the number of hit contained 3D objects at given point,
|
|
|
|
// give back the count and a depth-sorted list of SdrObjects (a Vector). The vector will be
|
|
|
|
// changed, at least cleared.
|
|
|
|
sal_uInt32 E3dScene::HitTest(const Point& rHitTestPosition, ::std::vector< SdrObject* >& o_rResult)
|
|
|
|
{
|
|
|
|
// prepare output variables
|
|
|
|
sal_uInt32 nRetval(0L);
|
|
|
|
o_rResult.clear();
|
|
|
|
SdrObjList* pList = GetSubList();
|
|
|
|
|
|
|
|
if(pList && pList->GetObjCount())
|
|
|
|
{
|
|
|
|
SdrObjListIter aIterator(*pList, IM_DEEPNOGROUPS);
|
|
|
|
::std::vector< ImplPairDephAndObject > aDepthAndObjectResults;
|
|
|
|
|
|
|
|
while(aIterator.IsMore())
|
|
|
|
{
|
|
|
|
SdrObject* pObj = aIterator.Next();
|
|
|
|
|
|
|
|
if(pObj->ISA(E3dCompoundObject))
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
E3dCompoundObject* pCompoundObj = (E3dCompoundObject*)pObj;
|
|
|
|
|
2004-05-10 13:29:12 +00:00
|
|
|
// get HitLine in local 3D ObjectKoordinates
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DHomMatrix mTransform = pCompoundObj->GetFullTransform();
|
2004-05-10 13:29:12 +00:00
|
|
|
GetCameraSet().SetObjectTrans(mTransform);
|
|
|
|
|
|
|
|
// create HitPoint Front und Back, transform to local object coordinates
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aFront(rHitTestPosition.X(), rHitTestPosition.Y(), 0.0);
|
|
|
|
basegfx::B3DPoint aBack(rHitTestPosition.X(), rHitTestPosition.Y(), ZBUFFER_DEPTH_RANGE);
|
2004-05-10 13:29:12 +00:00
|
|
|
aFront = GetCameraSet().ViewToObjectCoor(aFront);
|
|
|
|
aBack = GetCameraSet().ViewToObjectCoor(aBack);
|
|
|
|
|
|
|
|
// make BoundVolume HitTest for speedup first
|
2006-11-14 12:21:55 +00:00
|
|
|
const Volume3D& rBoundVol = pCompoundObj->GetBoundVolume();
|
2004-05-10 13:29:12 +00:00
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(!rBoundVol.isEmpty())
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
double fXMax(aFront.getX());
|
|
|
|
double fXMin(aBack.getX());
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
if(fXMax < fXMin)
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
fXMax = aBack.getX();
|
|
|
|
fXMin = aFront.getX();
|
2004-05-10 13:29:12 +00:00
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(rBoundVol.getMinX() <= fXMax && rBoundVol.getMaxX() >= fXMin)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
double fYMax(aFront.getY());
|
|
|
|
double fYMin(aBack.getY());
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
if(fYMax < fYMin)
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
fYMax = aBack.getY();
|
|
|
|
fYMin = aFront.getY();
|
2004-05-10 13:29:12 +00:00
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(rBoundVol.getMinY() <= fYMax && rBoundVol.getMaxY() >= fYMin)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
double fZMax(aFront.getZ());
|
|
|
|
double fZMin(aBack.getZ());
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
if(fZMax < fZMin)
|
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
fZMax = aBack.getZ();
|
|
|
|
fZMin = aFront.getZ();
|
2004-05-10 13:29:12 +00:00
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
if(rBoundVol.getMinZ() <= fZMax && rBoundVol.getMaxZ() >= fZMin)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
|
|
|
// BoundVol is hit, get geometry cuts now
|
2006-11-14 12:21:55 +00:00
|
|
|
::std::vector< basegfx::B3DPoint > aParameter;
|
|
|
|
const B3dGeometry& rGeometry = pCompoundObj->GetDisplayGeometry();
|
2004-05-10 13:29:12 +00:00
|
|
|
rGeometry.GetAllCuts(aParameter, aFront, aBack);
|
|
|
|
|
|
|
|
if(aParameter.size())
|
|
|
|
{
|
|
|
|
// take first cut as base, use Z-Coor in ViewCoor (0 ..ZBUFFER_DEPTH_RANGE)
|
|
|
|
ImplPairDephAndObject aTempResult;
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aTempVector(aParameter[0]);
|
2004-05-10 13:29:12 +00:00
|
|
|
aTempVector = GetCameraSet().ObjectToViewCoor(aTempVector);
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
aTempResult.pObject = pCompoundObj;
|
|
|
|
aTempResult.fDepth = aTempVector.getZ();
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
// look for cut points in front of the first one
|
2006-11-14 12:21:55 +00:00
|
|
|
::std::vector< basegfx::B3DPoint >::iterator aIterator2(aParameter.begin());
|
2006-06-19 14:47:24 +00:00
|
|
|
aIterator2++;
|
2004-05-10 13:29:12 +00:00
|
|
|
|
2006-06-19 14:47:24 +00:00
|
|
|
for(;aIterator2 != aParameter.end(); aIterator2++)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B3DPoint aTempVector2(*aIterator2);
|
|
|
|
aTempVector2 = GetCameraSet().ObjectToViewCoor(aTempVector2);
|
2004-05-10 13:29:12 +00:00
|
|
|
|
|
|
|
// use the smallest one
|
2006-11-14 12:21:55 +00:00
|
|
|
if(aTempVector2.getZ() < aTempResult.fDepth)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-11-14 12:21:55 +00:00
|
|
|
aTempResult.fDepth = aTempVector2.getZ();
|
2004-05-10 13:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// remember smallest cut with this object
|
|
|
|
aDepthAndObjectResults.push_back(aTempResult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// fill nRetval
|
|
|
|
nRetval = aDepthAndObjectResults.size();
|
|
|
|
|
|
|
|
if(nRetval)
|
|
|
|
{
|
|
|
|
// sort aDepthAndObjectResults by depth
|
|
|
|
::std::sort(aDepthAndObjectResults.begin(), aDepthAndObjectResults.end());
|
|
|
|
|
|
|
|
// copy SdrObject pointers to return result set
|
2006-06-19 14:47:24 +00:00
|
|
|
::std::vector< ImplPairDephAndObject >::iterator aIterator2(aDepthAndObjectResults.begin());
|
2004-05-10 13:29:12 +00:00
|
|
|
|
2006-06-19 14:47:24 +00:00
|
|
|
for(;aIterator2 != aDepthAndObjectResults.end(); aIterator2++)
|
2004-05-10 13:29:12 +00:00
|
|
|
{
|
2006-06-19 14:47:24 +00:00
|
|
|
o_rResult.push_back(aIterator2->pObject);
|
2004-05-10 13:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nRetval;
|
|
|
|
}
|
|
|
|
|
2006-11-14 12:21:55 +00:00
|
|
|
basegfx::B2DPolyPolygon E3dScene::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
|
|
|
|
{
|
|
|
|
return TakeXorPoly(sal_True);
|
|
|
|
}
|
|
|
|
|
|
|
|
FASTBOOL E3dScene::BegCreate(SdrDragStat& rStat)
|
|
|
|
{
|
|
|
|
rStat.SetOrtho4Possible();
|
|
|
|
Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
|
|
|
|
aRect1.Justify();
|
|
|
|
rStat.SetActionRect(aRect1);
|
|
|
|
NbcSetSnapRect(aRect1);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
FASTBOOL E3dScene::MovCreate(SdrDragStat& rStat)
|
|
|
|
{
|
|
|
|
Rectangle aRect1;
|
|
|
|
rStat.TakeCreateRect(aRect1);
|
|
|
|
aRect1.Justify();
|
|
|
|
rStat.SetActionRect(aRect1);
|
|
|
|
NbcSetSnapRect(aRect1);
|
|
|
|
bBoundRectDirty=TRUE;
|
|
|
|
bSnapRectDirty=TRUE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
FASTBOOL E3dScene::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
|
|
|
|
{
|
|
|
|
Rectangle aRect1;
|
|
|
|
rStat.TakeCreateRect(aRect1);
|
|
|
|
aRect1.Justify();
|
|
|
|
NbcSetSnapRect(aRect1);
|
|
|
|
SetRectsDirty();
|
|
|
|
return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
|
|
|
|
}
|
|
|
|
|
|
|
|
FASTBOOL E3dScene::BckCreate(SdrDragStat& /*rStat*/)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void E3dScene::BrkCreate(SdrDragStat& /*rStat*/)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2004-05-10 13:29:12 +00:00
|
|
|
// eof
|