diff options
Diffstat (limited to 'binfilter/bf_svx/source/engine3d/svx_obj3d.cxx')
-rw-r--r-- | binfilter/bf_svx/source/engine3d/svx_obj3d.cxx | 2969 |
1 files changed, 2969 insertions, 0 deletions
diff --git a/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx b/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx new file mode 100644 index 000000000000..950028c4469a --- /dev/null +++ b/binfilter/bf_svx/source/engine3d/svx_obj3d.cxx @@ -0,0 +1,2969 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define ITEMID_COLOR SID_ATTR_3D_LIGHTCOLOR + +#include "svdstr.hrc" + +#include "svdview.hxx" + + + + + + +#include "globl3d.hxx" + + + +#include "polyob3d.hxx" + + +#include "polysc3d.hxx" + + + + + + +#include "xoutx.hxx" + + + + + + + + + + + +#include "xlnwtit.hxx" + + +#include "svdio.hxx" + + + +#include "svxids.hrc" + + + + + + + + + + + +#include "eeitem.hxx" + + +namespace binfilter { + +#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() + +/************************************************************************* +|* +|* Liste fuer 3D-Objekte +|* +\************************************************************************/ + +/*N*/ TYPEINIT1(E3dObjList, SdrObjList); + +/*N*/ E3dObjList::E3dObjList(SdrModel* pNewModel, SdrPage* pNewPage, E3dObjList* pNewUpList) +/*N*/ : SdrObjList(pNewModel, pNewPage, pNewUpList) +/*N*/ { +/*N*/ } + +/*?*/ E3dObjList::E3dObjList(const E3dObjList& rSrcList) +/*?*/ : SdrObjList(rSrcList) +/*?*/ { +/*?*/ } + +/*N*/ E3dObjList::~E3dObjList() +/*N*/ { +/*N*/ } + +/*N*/ void E3dObjList::NbcInsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason) +/*N*/ { +/*N*/ // Owner holen +/*N*/ DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Einfuegen 3DObject in Parent != 3DObject"); +/*N*/ +/*N*/ // Ist es ueberhaupt ein 3D-Objekt? +/*N*/ if(pObj && pObj->ISA(E3dObject)) +/*N*/ { +/*N*/ // Normales 3D Objekt, einfuegen mittels +/*N*/ // call parent +/*N*/ SdrObjList::NbcInsertObject(pObj, nPos, pReason); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ // Kein 3D Objekt, fuege in Seite statt in Szene ein... +/*?*/ GetOwnerObj()->GetPage()->InsertObject(pObj, nPos); +/*N*/ } +/*N*/ } + + +/*N*/ SdrObject* E3dObjList::RemoveObject(ULONG nObjNum) +/*N*/ { +/*N*/ // Owner holen +/*N*/ DBG_ASSERT(GetOwnerObj()->ISA(E3dObject), "AW: Entfernen 3DObject aus Parent != 3DObject"); +/*N*/ E3dObject* pOwner = (E3dObject*)GetOwnerObj(); +/*N*/ +/*N*/ // call parent +/*N*/ SdrObject* pRetval = SdrObjList::RemoveObject(nObjNum); +/*N*/ +/*N*/ // FitSnapRectToBoundVol vorbereiten +/*N*/ if(GetOwnerObj() && GetOwnerObj()->ISA(E3dScene)) +/*N*/ ((E3dScene*)GetOwnerObj())->CorrectSceneDimensions(); +/*N*/ +/*N*/ return pRetval; +/*N*/ } + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +/*N*/ TYPEINIT1(E3dObject, SdrAttrObj); + +/*N*/ E3dObject::E3dObject() : +/*N*/ nLogicalGroup(0), +/*N*/ nObjTreeLevel(0), +/*N*/ eDragDetail(E3DDETAIL_ONEBOX), +/*N*/ nPartOfParent(0), +/*N*/ bTfHasChanged(TRUE), +/*N*/ bBoundVolValid(TRUE), +/*N*/ bIsSelected(FALSE) +/*N*/ { +/*N*/ bIs3DObj = TRUE; +/*N*/ pSub = new E3dObjList(NULL, NULL); +/*N*/ pSub->SetOwnerObj(this); +/*N*/ pSub->SetListKind(SDROBJLIST_GROUPOBJ); +/*N*/ bClosedObj = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +/*N*/ E3dObject::~E3dObject() +/*N*/ { +/*N*/ delete pSub; +/*N*/ pSub = NULL; +/*N*/ } + +/************************************************************************* +|* +|* Selektions-Flag setzen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Aufbrechen, default-Implementierungen +|* +\************************************************************************/ + + +/*N*/ SdrAttrObj* E3dObject::GetBreakObj() +/*N*/ { +/*N*/ return 0L; +/*N*/ } + +/************************************************************************* +|* +|* SetRectsDirty muss ueber die lokale SdrSubList gehen +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetRectsDirty(FASTBOOL bNotMyself) +/*N*/ { +/*N*/ // call parent +/*N*/ SdrAttrObj::SetRectsDirty(bNotMyself); +/*N*/ +/*N*/ // Eigene SubListe AUCH behandeln +/*N*/ if(pSub && pSub->GetObjCount()) +/*N*/ { +/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++) +/*N*/ { +/*N*/ SdrObject* pObj = pSub->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ ((E3dObject*)pObj)->SetRectsDirty(bNotMyself); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Inventor zurueckgeben +|* +\************************************************************************/ + +/*N*/ UINT32 E3dObject::GetObjInventor() const +/*N*/ { +/*N*/ return E3dInventor; +/*N*/ } + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +/*N*/ UINT16 E3dObject::GetObjIdentifier() const +/*N*/ { +/*N*/ return E3D_OBJECT_ID; +/*N*/ } + +/************************************************************************* +|* +|* Faehigkeiten des Objektes feststellen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Layer abfragen +|* +\************************************************************************/ + +/*N*/ SdrLayerID E3dObject::GetLayer() const +/*N*/ { +/*N*/ FASTBOOL bFirst = TRUE; +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ SdrLayerID nLayer = SdrLayerID(nLayerID); +/*N*/ +/*N*/ for ( ULONG i = 0; i < nObjCnt; i++ ) +/*N*/ { +/*N*/ SdrLayerID nObjLayer; +/*N*/ if(pOL->GetObj(i)->ISA(E3dPolyObj)) +/*N*/ nObjLayer = SdrLayerID(nLayerID); +/*N*/ else +/*N*/ nObjLayer = pOL->GetObj(i)->GetLayer(); +/*N*/ +/*N*/ if (bFirst) +/*N*/ { +/*N*/ nLayer = nObjLayer; +/*N*/ bFirst = FALSE; +/*N*/ } +/*N*/ else if ( nObjLayer != nLayer ) +/*N*/ return 0; +/*N*/ } +/*N*/ return nLayer; +/*N*/ } + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::NbcSetLayer(SdrLayerID nLayer) +/*N*/ { +/*N*/ SdrAttrObj::NbcSetLayer(nLayer); +/*N*/ +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ ULONG i; +/*N*/ for ( i = 0; i < nObjCnt; i++ ) +/*N*/ pOL->GetObj(i)->NbcSetLayer(nLayer); +/*N*/ } + +/************************************************************************* +|* +|* ObjList auch an SubList setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetObjList(SdrObjList* pNewObjList) +/*N*/ { +/*N*/ SdrObject::SetObjList(pNewObjList); +/*N*/ pSub->SetUpList(pNewObjList); +/*N*/ } + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetPage(SdrPage* pNewPage) +/*N*/ { +/*N*/ SdrAttrObj::SetPage(pNewPage); +/*N*/ pSub->SetPage(pNewPage); +/*N*/ } + +/************************************************************************* +|* +|* Layer setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetModel(SdrModel* pNewModel) +/*N*/ { +/*N*/ SdrAttrObj::SetModel(pNewModel); +/*N*/ pSub->SetModel(pNewModel); +/*N*/ } + +/************************************************************************* +|* +|* resize object, used from old 2d interfaces, e.g. in Move/Scale dialog +|* (F4) +|* +\************************************************************************/ +/*N*/ void E3dObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) +/*N*/ { +/*N*/ #ifndef SVX_LIGHT +/*N*/ // SdrAttrObj::NbcResize(rRef, xFact, yFact); +/*N*/ +/*N*/ // Bewegung in X,Y im Augkoordinatensystem +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ +/*N*/ if(pScene) +/*N*/ { +/*N*/ // pos ermitteln +/*N*/ B3dTransformationSet& rTransSet = pScene->GetCameraSet(); +/*N*/ Vector3D aScaleCenter((double)rRef.X(), (double)rRef.Y(), 32768.0); +/*N*/ aScaleCenter = rTransSet.ViewToEyeCoor(aScaleCenter); +/*N*/ +/*N*/ // scale-faktoren holen +/*N*/ double fScaleX = xFact; +/*N*/ double fScaleY = yFact; +/*N*/ +/*N*/ // build transform +/*N*/ Matrix4D mFullTransform(GetFullTransform()); +/*N*/ Matrix4D mTrans(mFullTransform); +/*N*/ +/*N*/ mTrans *= rTransSet.GetOrientation(); +/*N*/ mTrans.Translate(-aScaleCenter); +/*N*/ mTrans.Scale(fScaleX, fScaleY, 1.0); +/*N*/ mTrans.Translate(aScaleCenter); +/*N*/ mTrans *= rTransSet.GetInvOrientation(); +/*N*/ mFullTransform.Invert(); +/*N*/ mTrans *= mFullTransform; +/*N*/ +/*N*/ // anwenden +/*N*/ Matrix4D mObjTrans(GetTransform()); +/*N*/ mObjTrans *= mTrans; +/*N*/ SetTransform(mObjTrans); +/*N*/ +/*N*/ // force new camera and SnapRect on scene, geometry may have really +/*N*/ // changed +/*N*/ pScene->CorrectSceneDimensions(); +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* Objekt verschieben in 2D, wird bei Cursortasten benoetigt +|* +\************************************************************************/ + +/************************************************************************* +|* +|* liefere die Sublist, aber nur dann, wenn darin Objekte enthalten sind ! +|* +\************************************************************************/ + +/*N*/ SdrObjList* E3dObject::GetSubList() const +/*N*/ { +/*N*/ return pSub; +/*N*/ } + +/************************************************************************* +|* +|* Anzahl der Handles zurueckgeben +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Handle-Liste fuellen +|* +\************************************************************************/ + + +/************************************************************************* +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Paint; wird z.Z. nicht benutzt, da das Paint ueber die +|* (2D-)Displayliste der Szene laeuft +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Objekt als Kontur in das Polygon einfuegen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Schatten fuer 3D-Objekte zeichnen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* SnapRect berechnen +|* +\************************************************************************/ + +/*N*/ void E3dObject::RecalcSnapRect() +/*N*/ { +/*N*/ maSnapRect = Rectangle(); +/*N*/ if(pSub && pSub->GetObjCount()) +/*N*/ { +/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++) +/*N*/ { +/*N*/ SdrObject* pObj = pSub->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ Rectangle aSubRect = ((E3dObject*)pObj)->GetSnapRect(); +/*N*/ maSnapRect.Union(aSubRect); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* BoundRect berechnen +|* +\************************************************************************/ + +/*N*/ void E3dObject::RecalcBoundRect() +/*N*/ { +/*N*/ // BoundRect aus SnapRect berechnen +/*N*/ aOutRect = GetSnapRect(); +/*N*/ +/*N*/ if(pSub && pSub->GetObjCount()) +/*N*/ { +/*N*/ for (ULONG i = 0; i < pSub->GetObjCount(); i++) +/*N*/ { +/*N*/ SdrObject* pObj = pSub->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "AW: In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ Rectangle aSubRect = ((E3dObject*)pObj)->GetBoundRect(); +/*N*/ aOutRect.Union(aSubRect); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Einfuegen eines 3D-Objekts an den Parent weitermelden, damit dieser +|* ggf. eine Sonderbehandlung fuer spezielle Objekte durchfuehren kann +|* (z.B. Light/Label in E3dScene) +|* +\************************************************************************/ + +/*N*/ void E3dObject::NewObjectInserted(const E3dObject* p3DObj) +/*N*/ { +/*N*/ if(GetParentObj()) +/*N*/ GetParentObj()->NewObjectInserted(p3DObj); +/*N*/ } + +/************************************************************************* +|* +|* Parent ueber Aenderung der Struktur (z.B. durch Transformation) +|* informieren; dabei wird das Objekt, in welchem die Aenderung +|* aufgetreten ist, uebergeben +|* +\************************************************************************/ + +/*N*/ void E3dObject::StructureChanged(const E3dObject* p3DObj) +/*N*/ { +/*N*/ if ( GetParentObj() ) +/*N*/ { +/*N*/ // Wenn sich im Child das BoundVolume geaendert hat, muessen +/*N*/ // auch die der Parents angepasst werden +/*N*/ if ( !p3DObj->bBoundVolValid ) +/*N*/ GetParentObj()->bBoundVolValid = FALSE; +/*N*/ +/*N*/ GetParentObj()->StructureChanged(p3DObj); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 3D-Objekt einfuegen +|* +\************************************************************************/ + +/*N*/ void E3dObject::Insert3DObj(E3dObject* p3DObj) +/*N*/ { +/*N*/ DBG_ASSERT(p3DObj, "Insert3DObj mit NULL-Zeiger!"); +/*N*/ p3DObj->SetObjTreeLevel(nObjTreeLevel + 1); +/*N*/ SdrPage* pPg = pPage; +/*N*/ pSub->InsertObject(p3DObj); +/*N*/ pPage = pPg; +/*N*/ bBoundVolValid = FALSE; +/*N*/ NewObjectInserted(p3DObj); +/*N*/ StructureChanged(this); +/*N*/ } + +/*N*/ void E3dObject::Remove3DObj(E3dObject* p3DObj) +/*N*/ { +/*N*/ DBG_ASSERT(p3DObj, "Remove3DObj mit NULL-Zeiger!"); +/*N*/ +/*N*/ if(p3DObj->GetParentObj() == this) +/*N*/ { +/*N*/ SdrPage* pPg = pPage; +/*N*/ pSub->RemoveObject(p3DObj->GetOrdNum()); +/*N*/ pPage = pPg; +/*N*/ +/*N*/ bBoundVolValid = FALSE; +/*N*/ StructureChanged(this); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Parent holen +|* +\************************************************************************/ + +/*N*/ E3dObject* E3dObject::GetParentObj() const +/*N*/ { +/*N*/ E3dObject* pRetval = NULL; +/*N*/ +/*N*/ if(GetObjList() +/*N*/ && GetObjList()->GetOwnerObj() +/*N*/ && GetObjList()->GetOwnerObj()->ISA(E3dObject)) +/*N*/ pRetval = ((E3dObject*)GetObjList()->GetOwnerObj()); +/*N*/ return pRetval; +/*N*/ } + +/************************************************************************* +|* +|* Uebergeordnetes Szenenobjekt bestimmen +|* +\************************************************************************/ + +/*N*/ E3dScene* E3dObject::GetScene() const +/*N*/ { +/*N*/ if(GetParentObj()) +/*N*/ return GetParentObj()->GetScene(); +/*N*/ return NULL; +/*N*/ } + +/************************************************************************* +|* +|* umschliessendes Volumen inklusive aller Kindobjekte berechnen +|* +\************************************************************************/ + +/*N*/ void E3dObject::RecalcBoundVolume() +/*N*/ { +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ +/*N*/ if(nObjCnt) +/*N*/ { +/*N*/ aBoundVol = Volume3D(); +/*N*/ +/*N*/ for (ULONG i = 0; i < nObjCnt; i++) +/*N*/ { +/*N*/ SdrObject* pObj = pOL->GetObj(i); +/*N*/ +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ // Bei den Kindobjekten auch die lokalen Transformationen +/*N*/ // beruecksichtigen +/*N*/ E3dObject* p3DObj = (E3dObject*) pObj; +/*N*/ const Volume3D& rVol = p3DObj->GetBoundVolume(); +/*N*/ const Matrix4D& rTf = p3DObj->GetTransform(); +/*N*/ aBoundVol.Union(rVol.GetTransformVolume(rTf)); +/*N*/ } +/*N*/ +/*N*/ aLocalBoundVol = aBoundVol; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aBoundVol = aLocalBoundVol; +/*N*/ } +/*N*/ +/*N*/ bBoundVolValid = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* umschliessendes Volumen zurueckgeben und ggf. neu berechnen +|* +\************************************************************************/ + +/*N*/ const Volume3D& E3dObject::GetBoundVolume() +/*N*/ { +/*N*/ if ( !bBoundVolValid ) +/*N*/ RecalcBoundVolume(); +/*N*/ +/*N*/ if(!aBoundVol.IsValid()) +/*N*/ aBoundVol = Volume3D(Vector3D(), Vector3D()); +/*N*/ +/*N*/ return aBoundVol; +/*N*/ } + +/************************************************************************* +|* +|* Mittelpunkt liefern +|* +\************************************************************************/ + +/*N*/ Vector3D E3dObject::GetCenter() +/*N*/ { +/*N*/ Volume3D aVolume = GetBoundVolume(); +/*N*/ return (aVolume.MaxVec() + aVolume.MinVec()) / 2.0; +/*N*/ } + +/************************************************************************* +|* +|* Aederung des BoundVolumes an alle Kindobjekte weitergeben +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetBoundVolInvalid() +/*N*/ { +/*N*/ bBoundVolValid = FALSE; +/*N*/ +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ +/*N*/ for (ULONG i = 0; i < nObjCnt; i++) +/*N*/ { +/*N*/ SdrObject* pObj = pOL->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ +/*N*/ ((E3dObject*) pObj)->SetBoundVolInvalid(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Aederung der Transformation an alle Kindobjekte weitergeben +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetTransformChanged() +/*N*/ { +/*N*/ bTfHasChanged = TRUE; +/*N*/ bBoundVolValid = FALSE; +/*N*/ +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ +/*N*/ for (ULONG i = 0; i < nObjCnt; i++) +/*N*/ { +/*N*/ SdrObject* pObj = pOL->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ +/*N*/ ((E3dObject*) pObj)->SetTransformChanged(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* hierarchische Transformation ueber alle Parents bestimmen und mit +|* der uebergebenen Matrix verketten +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* hierarchische Transformation ueber alle Parents bestimmen, in +|* aFullTfMatrix ablegen und diese zurueckgeben +|* +\************************************************************************/ + +/*N*/ const Matrix4D& E3dObject::GetFullTransform() +/*N*/ { +/*N*/ if ( bTfHasChanged ) +/*N*/ { +/*N*/ aFullTfMatrix = aTfMatrix; +/*N*/ +/*N*/ if ( GetParentObj() ) +/*N*/ aFullTfMatrix *= GetParentObj()->GetFullTransform(); +/*N*/ +/*N*/ bTfHasChanged = FALSE; +/*N*/ } +/*N*/ +/*N*/ return aFullTfMatrix; +/*N*/ } + +/************************************************************************* +|* +|* Transformationsmatrix abfragen +|* +\************************************************************************/ + +/*N*/ const Matrix4D& E3dObject::GetTransform() const +/*N*/ { +/*N*/ return aTfMatrix; +/*N*/ } + +/************************************************************************* +|* +|* Transformationsmatrix setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::NbcSetTransform(const Matrix4D& rMatrix) +/*N*/ { +/*N*/ aTfMatrix = rMatrix; +/*N*/ SetTransformChanged(); +/*N*/ StructureChanged(this); +/*N*/ } + +/************************************************************************* +|* +|* Transformationsmatrix auf Einheitsmatrix zuruecksetzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::NbcResetTransform() +/*N*/ { +/*N*/ aTfMatrix.Identity(); +/*N*/ SetTransformChanged(); +/*N*/ StructureChanged(this); +/*N*/ } + +/************************************************************************* +|* +|* Transformationsmatrix setzen mit Repaint-Broadcast +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetTransform(const Matrix4D& rMatrix) +/*N*/ { +/*N*/ SendRepaintBroadcast(); +/*N*/ NbcSetTransform(rMatrix); +/*N*/ SetChanged(); +/*N*/ SendRepaintBroadcast(); +/*N*/ if (pUserCall != NULL) pUserCall->Changed(*this, SDRUSERCALL_RESIZE, Rectangle()); +/*N*/ } + +/************************************************************************* +|* +|* Transformationsmatrix zuruecksetzen mit Repaint-Broadcast +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Translation +|* +\************************************************************************/ + +/************************************************************************* +|* +|* Translation mit Repaint-Broadcast +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Skalierungen +|* +\************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************* +|* +|* gleichmaessige Skalierung +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Skalierungen mit mit Repaint-Broadcast +|* +\************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************* +|* +|* Rotationen mit Winkel in Radiant +|* +\************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************* +|* +|* Rotationen mit Repaint-Broadcast +|* +\************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************/ + + +/************************************************************************* +|* +|* Objektbaum-Ebene des Objekts und aller Children setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::SetObjTreeLevel(USHORT nNewLevel) +/*N*/ { +/*N*/ nObjTreeLevel = nNewLevel; +/*N*/ nNewLevel++; +/*N*/ +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ +/*N*/ for (ULONG i = 0; i < nObjCnt; i++) +/*N*/ { +/*N*/ SdrObject* pObj = pOL->GetObj(i); +/*N*/ DBG_ASSERT(pObj->ISA(E3dObject), "In E3dObject sind nur 3D-Objekte erlaubt!"); +/*N*/ +/*N*/ ((E3dObject*) pObj)->SetObjTreeLevel(nNewLevel); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* logische Gruppe setzen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Linien fuer die Wireframe-Darstellung des Objekts dem uebergebenen +|* Polygon3D hinzufuegen. Als default wird das BoundVolume verwendet. +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Get the name of the object (singular) +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Get the name of the object (plural) +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Wireframe-XPolyPolygon erzeugen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Drag-Polygon zurueckgeben +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Zuweisungsoperator +|* +\************************************************************************/ + + +////////////////////////////////////////////////////////////////////////////// +// ItemSet access + +/*N*/ const SfxItemSet& E3dObject::GetItemSet() const +/*N*/ { +/*N*/ // include Items of scene this object belongs to +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ if(pScene && pScene != this) +/*N*/ { +/*N*/ SfxItemSet& rSet = (SfxItemSet&)SdrAttrObj::GetItemSet(); +/*N*/ SfxItemSet aSet(*rSet.GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST); +/*N*/ aSet.Put(pScene->E3dObject::GetItemSet()); +/*N*/ rSet.Put(aSet); +/*N*/ } +/*N*/ +/*N*/ return SdrAttrObj::GetItemSet(); +/*N*/ } + +/*N*/ SfxItemSet* E3dObject::CreateNewItemSet(SfxItemPool& rPool) +/*N*/ { +/*N*/ // include ALL items, 2D and 3D +/*N*/ return new SfxItemSet(rPool, +/*N*/ // ranges from SdrAttrObj +/*N*/ SDRATTR_START, SDRATTRSET_SHADOW, +/*N*/ SDRATTRSET_OUTLINER, SDRATTRSET_MISC, +/*N*/ +/*N*/ // ranges for 3D (object and scene) +/*N*/ SDRATTR_3D_FIRST, SDRATTR_3D_LAST, +/*N*/ +/*N*/ // outliner and end +/*N*/ EE_ITEMS_START, EE_ITEMS_END, +/*N*/ 0, 0); +/*N*/ } + +// private support routines for ItemSet access. NULL pointer means clear item. +/*N*/ void E3dObject::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) +/*N*/ { +/*N*/ // propagate item changes to scene +/*N*/ if(!nWhich || (nWhich >= SDRATTR_3DSCENE_FIRST && nWhich <= SDRATTR_3DSCENE_LAST)) +/*N*/ { +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ if(pScene && pScene != this) +/*N*/ pScene->E3dObject::ItemChange(nWhich, pNewItem); +/*N*/ } +/*N*/ +/*N*/ // call parent +/*N*/ SdrAttrObj::ItemChange(nWhich, pNewItem); +/*N*/ } + +// #107770# Like propagating ItemChange to the scene if scene items are changed, +// do the same with the PostItemChange calls. +/*N*/ void E3dObject::PostItemChange(const sal_uInt16 nWhich) +/*N*/ { +/*N*/ // propagate item changes to scene +/*N*/ if(!nWhich || (nWhich >= SDRATTR_3DSCENE_FIRST && nWhich <= SDRATTR_3DSCENE_LAST)) +/*N*/ { +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ if(pScene && pScene != this) +/*N*/ pScene->PostItemChange(nWhich); +/*N*/ } +/*N*/ +/*N*/ // call parent +/*N*/ SdrAttrObj::PostItemChange(nWhich); +/*N*/ } + +/*N*/ void E3dObject::ItemSetChanged( const SfxItemSet& rSet ) +/*N*/ { +/*N*/ // call parent +/*N*/ SdrAttrObj::ItemSetChanged( rSet ); +/*N*/ +/*N*/ // local changes +/*N*/ StructureChanged(this); +/*N*/ } + +/************************************************************************* +|* +|* StyleSheet setzen +|* +\************************************************************************/ + +/*N*/ void E3dObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, +/*N*/ FASTBOOL bDontRemoveHardAttr) +/*N*/ { +/*N*/ // call parent +/*N*/ SdrAttrObj::NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); +/*N*/ +/*N*/ E3dObjList* pOL = pSub; +/*N*/ ULONG nObjCnt = pOL->GetObjCount(); +/*N*/ for ( ULONG i = 0; i < nObjCnt; i++ ) +/*?*/ pOL->GetObj(i)->NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); +/*N*/ } + +/************************************************************************* +|* +|* Nur die Member des E3dObjekts in den Stream speichern +|* Dies wird direkt auch von E3dSphere gerufen um zu verhindern dass die +|* Subliste weggeschrieben wird. (FG) +|* +\************************************************************************/ + +/*N*/ #ifndef SVX_LIGHT +/*N*/ void E3dObject::WriteOnlyOwnMembers(SvStream& rOut) const +/*N*/ { +/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code) +/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dObjectOwnMembers"); +/*N*/ #endif +/*N*/ +/*N*/ rOut << aLocalBoundVol; +/*N*/ +/*N*/ Old_Matrix3D aMat3D; +/*N*/ aMat3D = aTfMatrix; +/*N*/ rOut << aMat3D; +/*N*/ +/*N*/ rOut << nLogicalGroup; +/*N*/ rOut << nObjTreeLevel; +/*N*/ rOut << nPartOfParent; +/*N*/ rOut << UINT16(eDragDetail); +/*N*/ } +/*N*/ #endif + +/************************************************************************* +|* +|* Objektdaten in Stream speichern +|* +\************************************************************************/ + +/*N*/ void E3dObject::WriteData(SvStream& rOut) const +/*N*/ { +/*N*/ #ifndef SVX_LIGHT +/*N*/ long position = rOut.Tell(); +/*N*/ SdrAttrObj::WriteData(rOut); +/*N*/ position = rOut.Tell(); +/*N*/ +/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code) +/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dObject"); +/*N*/ #endif +/*N*/ +/*N*/ position = rOut.Tell(); +/*N*/ pSub->Save(rOut); +/*N*/ position = rOut.Tell(); +/*N*/ +/*N*/ if (rOut.GetVersion() < 3560) +/*N*/ { +/*N*/ rOut << aLocalBoundVol; +/*N*/ +/*N*/ Old_Matrix3D aMat3D; +/*N*/ aMat3D = aTfMatrix; +/*N*/ rOut << aMat3D; +/*N*/ +/*N*/ rOut << nLogicalGroup; +/*N*/ rOut << nObjTreeLevel; +/*N*/ rOut << nPartOfParent; +/*N*/ rOut << UINT16(eDragDetail); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ WriteOnlyOwnMembers(rOut); +/*N*/ } +/*N*/ position = rOut.Tell(); +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* Objektdaten aus Stream laden +|* +\************************************************************************/ + +/*N*/ void E3dObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn) +/*N*/ { +/*N*/ long position = rIn.Tell(); +/*N*/ if (ImpCheckSubRecords (rHead, rIn)) +/*N*/ { +/*N*/ position = rIn.Tell(); +/*N*/ SdrAttrObj::ReadData(rHead, rIn); +/*N*/ position = rIn.Tell(); +/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code) +/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dObject"); +/*N*/ #endif +/*N*/ pSub->Load(rIn, *pPage); +/*N*/ +/*N*/ position = rIn.Tell(); +/*N*/ if ((rIn.GetVersion() < 3560) || (rHead.GetVersion() <= 12)) +/*N*/ { +/*N*/ UINT16 nTmp16; +/*N*/ +/*N*/ rIn >> aLocalBoundVol; +/*N*/ +/*N*/ Old_Matrix3D aMat3D; +/*N*/ rIn >> aMat3D; +/*N*/ aTfMatrix = Matrix4D(aMat3D); +/*N*/ +/*N*/ rIn >> nLogicalGroup; +/*N*/ rIn >> nObjTreeLevel; +/*N*/ rIn >> nPartOfParent; +/*N*/ rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ReadOnlyOwnMembers(rHead, rIn); +/*N*/ } +/*N*/ position = rIn.Tell(); +/*N*/ +/*N*/ // Wie ein veraendertes Objekt behandeln +/*N*/ SetTransformChanged(); +/*N*/ StructureChanged(this); +/*N*/ +/*N*/ // BoundVolume muss neu berechnet werden +/*N*/ bBoundVolValid = FALSE; +/*N*/ +/*N*/ // SnapRect auch +/*N*/ bSnapRectDirty = TRUE; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Nur die Daten des E3dObject aus Stream laden (nicht der Sublisten und +|* der Basisklassen). Wird von E3dSphere auch genutzt. (FileFormat-Optimierung) +|* +\************************************************************************/ + +/*N*/ void E3dObject::ReadOnlyOwnMembers(const SdrObjIOHeader& rHead, SvStream& rIn) +/*N*/ { +/*N*/ // Fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code) +/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dObjectOwnMembers"); +/*N*/ #endif +/*N*/ UINT16 nTmp16; +/*N*/ +/*N*/ rIn >> aLocalBoundVol; +/*N*/ +/*N*/ Old_Matrix3D aMat3D; +/*N*/ rIn >> aMat3D; +/*N*/ aTfMatrix = Matrix4D(aMat3D); +/*N*/ +/*N*/ rIn >> nLogicalGroup; +/*N*/ rIn >> nObjTreeLevel; +/*N*/ rIn >> nPartOfParent; +/*N*/ rIn >> nTmp16; eDragDetail = E3dDragDetail(nTmp16); +/*N*/ +/*N*/ bBoundVolValid = FALSE; +/*N*/ } + + +/************************************************************************* +|* +|* nach dem Laden... +|* +\************************************************************************/ + +/*N*/ void E3dObject::AfterRead() +/*N*/ { +/*N*/ SdrAttrObj::AfterRead(); +/*N*/ if (pSub) +/*N*/ pSub->AfterRead(); +/*N*/ } + +/************************************************************************* +|* +|* erstelle neues GeoData-Objekt +|* +\************************************************************************/ + +/*N*/ SdrObjGeoData *E3dObject::NewGeoData() const +/*N*/ { +/*N*/ // Theoretisch duerfen auch nur Szenen ihre GeoDatas erstellen und verwalten !! +/*N*/ // AW: Dies stimmt nicht mehr, diese Stelle ist mit der neuen Engine OK! +/*N*/ return new E3DObjGeoData; +/*N*/ } + +/************************************************************************* +|* +|* uebergebe aktuelle werte an das GeoData-Objekt +|* +\************************************************************************/ + +/*N*/ void E3dObject::SaveGeoData(SdrObjGeoData& rGeo) const +/*N*/ { +/*N*/ SdrAttrObj::SaveGeoData (rGeo); +/*N*/ +/*N*/ ((E3DObjGeoData &) rGeo).aLocalBoundVol = aLocalBoundVol; +/*N*/ ((E3DObjGeoData &) rGeo).aTfMatrix = aTfMatrix; +/*N*/ } + +/************************************************************************* +|* +|* uebernehme werte aus dem GeoData-Objekt +|* +\************************************************************************/ + +/*N*/ void E3dObject::RestGeoData(const SdrObjGeoData& rGeo) +/*N*/ { +/*N*/ aLocalBoundVol = ((E3DObjGeoData &) rGeo).aLocalBoundVol; +/*N*/ NbcSetTransform (((E3DObjGeoData &) rGeo).aTfMatrix); +/*N*/ +/*N*/ SdrAttrObj::RestGeoData (rGeo); +/*N*/ GetScene()->FitSnapRectToBoundVol(); +/*N*/ } + +/************************************************************************* +|* +|* Pruefe, ob die SubRecords ok sind und mit der Factory gelesen werden +|* koennen. +|* +\************************************************************************/ + +/*N*/ BOOL E3dObject::ImpCheckSubRecords (const SdrObjIOHeader& rHead, +/*N*/ SvStream& rIn) +/*N*/ { +/*N*/ BOOL bDoRead = FALSE; +/*N*/ +/*N*/ if ( rIn.GetError() == SVSTREAM_OK ) +/*N*/ { +/*N*/ if (rHead.GetVersion () <= 12) +/*N*/ { +/*N*/ ULONG nPos0 = rIn.Tell(); +/*N*/ // Einen SubRecord ueberspringen (SdrObject) +/*N*/ { SdrDownCompat aCompat(rIn,STREAM_READ); } +/*N*/ // Nocheinen SubRecord ueberspringen (SdrAttrObj) +/*N*/ { SdrDownCompat aCompat(rIn,STREAM_READ); } +/*N*/ // Und nun muesste meiner kommen +/*N*/ bDoRead = rHead.GetBytesLeft() != 0; +/*N*/ rIn.Seek (nPos0); // FilePos wieder restaurieren +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bDoRead = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return bDoRead; +/*N*/ } + +/************************************************************************* +|* +|* Keine DefaultAttr, zu langsam +|* +\************************************************************************/ + +/*N*/ void E3dObject::ForceDefaultAttr() +/*N*/ { +/*N*/ } + +/*************************************************************************/ + +/*N*/ TYPEINIT1(E3dCompoundObject, E3dObject); + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +/*N*/ E3dCompoundObject::E3dCompoundObject() : E3dObject() +/*N*/ { +/*N*/ // Defaults setzen +/*N*/ E3dDefaultAttributes aDefault; +/*N*/ SetDefaultAttributes(aDefault); +/*N*/ +/*N*/ bBytesLeft = FALSE; +/*N*/ bCreateE3dPolyObj = FALSE; +/*N*/ bGeometryValid = FALSE; +/*N*/ } + +/*N*/ E3dCompoundObject::E3dCompoundObject(E3dDefaultAttributes& rDefault) : E3dObject() +/*N*/ { +/*N*/ // Defaults setzen +/*N*/ SetDefaultAttributes(rDefault); +/*N*/ +/*N*/ bBytesLeft = FALSE; +/*N*/ bCreateE3dPolyObj = FALSE; +/*N*/ bGeometryValid = FALSE; +/*N*/ } + +/*N*/ void E3dCompoundObject::SetDefaultAttributes(E3dDefaultAttributes& rDefault) +/*N*/ { +/*N*/ // Defaults setzen +/*N*/ aMaterialAmbientColor = rDefault.GetDefaultAmbientColor(); +/*N*/ +//is always default, so it needs not to be set /*N*/ aBackMaterial = rDefault.GetDefaultBackMaterial(); +/*N*/ bCreateNormals = rDefault.GetDefaultCreateNormals(); +/*N*/ bCreateTexture = rDefault.GetDefaultCreateTexture(); +/*N*/ bUseDifferentBackMaterial = rDefault.GetDefaultUseDifferentBackMaterial(); +/*N*/ } + +/************************************************************************* +|* +|* Destruktor +|* +\************************************************************************/ + +/*N*/ E3dCompoundObject::~E3dCompoundObject () +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* Start der Geometrieerzeugung ankuendigen +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::StartCreateGeometry() +/*N*/ { +/*N*/ // Geometriestart mitteilen +/*N*/ aDisplayGeometry.StartDescription(); +/*N*/ +/*N*/ // Lokales Volumen reset +/*N*/ aLocalBoundVol = Volume3D(); +/*N*/ +/*N*/ // Geometrie ist ab jetzt gueltig, um ein rekursives weiteres +/*N*/ // Erzeugen zu verhindern +/*N*/ bGeometryValid = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* Identifier zurueckgeben +|* +\************************************************************************/ + +/*N*/ UINT16 E3dCompoundObject::GetObjIdentifier() const +/*N*/ { +/*N*/ return E3D_COMPOUNDOBJ_ID; +/*N*/ } + +/************************************************************************* +|* +|* Compounds brauchen Defaults +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::ForceDefaultAttr() +/*N*/ { +/*N*/ SdrAttrObj::ForceDefaultAttr(); +/*N*/ } + +/************************************************************************* +|* +|* SnapRect berechnen +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::RecalcSnapRect() +/*N*/ { +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ if(pScene) +/*N*/ { +/*N*/ // Objekttransformation uebernehmen +/*N*/ const Volume3D& rBoundVol = GetBoundVolume(); +/*N*/ maSnapRect = Rectangle(); +/*N*/ +/*N*/ if(rBoundVol.IsValid()) +/*N*/ { +/*N*/ const Matrix4D& rTrans = GetFullTransform(); +/*N*/ Vol3DPointIterator aIter(rBoundVol, &rTrans); +/*N*/ Vector3D aTfVec; +/*N*/ while ( aIter.Next(aTfVec) ) +/*N*/ { +/*N*/ aTfVec = pScene->GetCameraSet().WorldToViewCoor(aTfVec); +/*N*/ Point aPoint((long)(aTfVec.X() + 0.5), (long)(aTfVec.Y() + 0.5)); +/*N*/ maSnapRect.Union(Rectangle(aPoint, aPoint)); +/*N*/ } +/*N*/ } +/*N*/ bSnapRectDirty = FALSE; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* BoundRect berechnen und evtl. Schatten einbeziehen +|* Dazu muss ein eventueller Schatten des einzelnen 3D-Objektes +|* beruecksichtigt werden +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::RecalcBoundRect() +/*N*/ { +/*N*/ // BoundRect aus SnapRect berechnen +/*N*/ aOutRect = GetSnapRect(); +/*N*/ +/*N*/ E3dScene* pScene = GetScene(); +/*N*/ if(pScene) +/*N*/ { +/*N*/ // Schatten beruecksichtigen +/*N*/ if(DoDrawShadow()) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } + + // Linienbreite beruecksichtigen +/*N*/ INT32 nLineWidth = ((const XLineWidthItem&)(GetItem(XATTR_LINEWIDTH))).GetValue(); +/*N*/ if(nLineWidth) +/*N*/ { +/*?*/ Rectangle aShadowRect = aOutRect; +/*?*/ aShadowRect.Left() -= nLineWidth; +/*?*/ aShadowRect.Right() += nLineWidth; +/*?*/ aShadowRect.Top() -= nLineWidth; +/*?*/ aShadowRect.Bottom() += nLineWidth; +/*?*/ aOutRect.Union(aShadowRect); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* BoundVolume holen. Falls die Geometrie ungueltig ist, diese neu +|* erzeugen und das BoundVol neu berechnen +|* +\************************************************************************/ + +/*N*/ const Volume3D& E3dCompoundObject::GetBoundVolume() +/*N*/ { +/*N*/ // Geometrie aktuell? +/*N*/ if(!bGeometryValid) +/*N*/ { +/*N*/ // Neu erzeugen und eine Neubestimmung des BoundVol erzwingen +/*N*/ ReCreateGeometry(); +/*N*/ bBoundVolValid = FALSE; +/*N*/ } +/*N*/ +/*N*/ // call parent +/*N*/ return E3dObject::GetBoundVolume(); +/*N*/ } + +/************************************************************************* +|* +|* Rausschreiben der Datenmember eines E3dCompounds +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::WriteData(SvStream& rOut) const +/*N*/ { +/*N*/ #ifndef SVX_LIGHT +/*N*/ #ifdef E3D_STREAMING +/*N*/ +/*N*/ if (!aLocalBoundVol.IsValid() && aBoundVol.IsValid()) +/*N*/ { +/*N*/ // Das aLocalBoundVol wird gespeichert. +/*N*/ // Ist dieses ungueltig, so wird das aBoundVol genommen +/*N*/ // (sollten beim E3dCompoundObject sowieso gleich sein) +/*N*/ ((E3dCompoundObject*) this)->aLocalBoundVol = aBoundVol; +/*N*/ } +/*N*/ +/*N*/ E3dObject::WriteData(rOut); +/*N*/ if (rOut.GetVersion() < 3560) +/*N*/ { +/*N*/ // In diesem Fall passiert nichts, da vor der Version 4.0 +/*N*/ // also im Falle der Revision 3.1 +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SdrDownCompat aCompat(rOut, STREAM_WRITE); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dCompoundObject"); +/*N*/ #endif +/*N*/ rOut << BOOL(GetDoubleSided()); +/*N*/ #endif +/*N*/ +/*N*/ // neue Parameter zur Geometrieerzeugung +/*N*/ rOut << BOOL(bCreateNormals); +/*N*/ rOut << BOOL(bCreateTexture); +/*N*/ +/*N*/ sal_uInt16 nVal = GetNormalsKind(); +/*N*/ rOut << BOOL(nVal > 0); +/*N*/ rOut << BOOL(nVal > 1); +/*N*/ +/*N*/ nVal = GetTextureProjectionX(); +/*N*/ rOut << BOOL(nVal > 0); +/*N*/ rOut << BOOL(nVal > 1); +/*N*/ +/*N*/ nVal = GetTextureProjectionY(); +/*N*/ rOut << BOOL(nVal > 0); +/*N*/ rOut << BOOL(nVal > 1); +/*N*/ +/*N*/ rOut << BOOL(GetShadow3D()); +/*N*/ +/*N*/ // neu al 384: +/*N*/ rOut << GetMaterialAmbientColor(); +/*N*/ rOut << GetMaterialColor(); +/*N*/ rOut << GetMaterialSpecular(); +/*N*/ rOut << GetMaterialEmission(); +/*N*/ rOut << GetMaterialSpecularIntensity(); +/*N*/ +/*N*/ aBackMaterial.WriteData(rOut); +/*N*/ +/*N*/ rOut << (UINT16)GetTextureKind(); +/*N*/ +/*N*/ rOut << (UINT16)GetTextureMode(); +/*N*/ +/*N*/ rOut << BOOL(GetNormalsInvert()); +/*N*/ +/*N*/ // neu ab 534: (hat noch gefehlt) +/*N*/ rOut << BOOL(GetTextureFilter()); +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* Einlesen der Datenmember eines E3dCompounds +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::ReadData(const SdrObjIOHeader& rHead, SvStream& rIn) +/*N*/ { +/*N*/ if ( rIn.GetError() != SVSTREAM_OK ) +/*N*/ return; +/*N*/ +/*N*/ E3dObject::ReadData(rHead, rIn); +/*N*/ +/*N*/ // Vor der Filerevision 13 wurde das Objekt nie geschrieben. +/*N*/ // auch kein Kompatibilitaetsrecord. +/*N*/ if ((rHead.GetVersion() < 13) || (rIn.GetVersion() < 3560)) +/*N*/ { +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ SdrDownCompat aCompat(rIn, STREAM_READ); +/*N*/ #ifdef DBG_UTIL +/*N*/ aCompat.SetID("E3dCompoundObject"); +/*N*/ #endif +/*N*/ +/*N*/ bBytesLeft = FALSE; +/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL)) +/*N*/ { +/*N*/ BOOL bTmp, bTmp2; +/*N*/ sal_uInt16 nTmp; +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ mpObjectItemSet->Put(Svx3DDoubleSidedItem(bTmp)); +/*N*/ +/*N*/ // neue Parameter zur Geometrieerzeugung +/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL)) +/*N*/ { +/*N*/ rIn >> bTmp; +/*N*/ bCreateNormals = bTmp; +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ bCreateTexture = bTmp; +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ rIn >> bTmp2; +/*N*/ if(bTmp == FALSE && bTmp2 == FALSE) +/*N*/ nTmp = 0; +/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE) +/*N*/ nTmp = 1; +/*N*/ else +/*N*/ nTmp = 2; +/*N*/ mpObjectItemSet->Put(Svx3DNormalsKindItem(nTmp)); +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ rIn >> bTmp2; +/*N*/ if(bTmp == FALSE && bTmp2 == FALSE) +/*N*/ nTmp = 0; +/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE) +/*N*/ nTmp = 1; +/*N*/ else +/*N*/ nTmp = 2; +/*N*/ mpObjectItemSet->Put(Svx3DTextureProjectionXItem(nTmp)); +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ rIn >> bTmp2; +/*N*/ if(bTmp == FALSE && bTmp2 == FALSE) +/*N*/ nTmp = 0; +/*N*/ else if(bTmp == TRUE && bTmp2 == FALSE) +/*N*/ nTmp = 1; +/*N*/ else +/*N*/ nTmp = 2; +/*N*/ mpObjectItemSet->Put(Svx3DTextureProjectionYItem(nTmp)); +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ mpObjectItemSet->Put(Svx3DShadow3DItem(bTmp)); +/*N*/ +/*N*/ // Setze ein Flag fuer den Aufrufer, dass neues Format +/*N*/ // zu lesen ist +/*N*/ bBytesLeft = TRUE; +/*N*/ } +/*N*/ +/*N*/ // neu al 384: +/*N*/ if (aCompat.GetBytesLeft () >= sizeof (B3dMaterial)) +/*N*/ { +/*N*/ UINT16 nTmp; +/*N*/ +/*N*/ Color aCol; +/*N*/ +/*N*/ rIn >> aCol; +/*N*/ SetMaterialAmbientColor(aCol); +/*N*/ +/*N*/ rIn >> aCol; +/*N*/ // do NOT use, this is the old 3D-Color(!) +/*N*/ // SetItem(XFillColorItem(String(), aCol)); +/*N*/ +/*N*/ rIn >> aCol; +/*N*/ mpObjectItemSet->Put(Svx3DMaterialSpecularItem(aCol)); +/*N*/ +/*N*/ rIn >> aCol; +/*N*/ mpObjectItemSet->Put(Svx3DMaterialEmissionItem(aCol)); +/*N*/ +/*N*/ rIn >> nTmp; +/*N*/ mpObjectItemSet->Put(Svx3DMaterialSpecularIntensityItem(nTmp)); +/*N*/ +/*N*/ aBackMaterial.ReadData(rIn); +/*N*/ +/*N*/ rIn >> nTmp; +/*N*/ mpObjectItemSet->Put(Svx3DTextureKindItem(nTmp)); +/*N*/ +/*N*/ rIn >> nTmp; +/*N*/ mpObjectItemSet->Put(Svx3DTextureModeItem(nTmp)); +/*N*/ +/*N*/ rIn >> bTmp; +/*N*/ mpObjectItemSet->Put(Svx3DNormalsInvertItem(bTmp)); +/*N*/ } +/*N*/ +/*N*/ // neu ab 534: (hat noch gefehlt) +/*N*/ if (aCompat.GetBytesLeft () >= sizeof (BOOL)) +/*N*/ { +/*N*/ rIn >> bTmp; +/*N*/ mpObjectItemSet->Put(Svx3DTextureFilterItem(bTmp)); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Bitmaps fuer 3D-Darstellung von Gradients und Hatches holen +|* +\************************************************************************/ + + + + +/************************************************************************* +|* +|* Give out simple line geometry +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Geometrieerzeugung +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::DestroyGeometry() +/*N*/ { +/*N*/ // Alle Objekte in der Sub-Liste zerstoeren. Dies sind die +/*N*/ // zur Visualisierung des Objektes verwendeten Hilfsobjekte +/*N*/ pSub->Clear(); +/*N*/ delete pSub; +/*N*/ pSub = new E3dObjList(NULL, NULL); +/*N*/ pSub->SetOwnerObj(this); +/*N*/ pSub->SetListKind(SDROBJLIST_GROUPOBJ); +/*N*/ +/*N*/ // Neue Geometrie zerstoeren +/*N*/ aDisplayGeometry.Erase(); +/*N*/ +/*N*/ // BoundVols resetten +/*N*/ aLocalBoundVol = Volume3D(); +/*N*/ bBoundVolValid = FALSE; +/*N*/ StructureChanged(this); +/*N*/ +/*N*/ // Geometrie ist ungueltig +/*N*/ bGeometryValid = FALSE; +/*N*/ } + +/*N*/ void E3dCompoundObject::CreateGeometry() +/*N*/ { +/*N*/ // Geometrie ist gueltig, um rekursion zu verhindern +/*N*/ bGeometryValid = TRUE; +/*N*/ +/*N*/ // Eventuell entstandene Geometrie noch korrigieren +/*N*/ // und Default -Normalen oder -Texturkoordinaten erzeugen +/*N*/ if(bCreateNormals) +/*N*/ { +/*N*/ if(GetNormalsKind() > 1) +/*?*/ GetDisplayGeometry().CreateDefaultNormalsSphere(); +/*N*/ if(GetNormalsInvert()) +/*?*/ GetDisplayGeometry().InvertNormals(); +/*N*/ } +/*N*/ +/*N*/ if(bCreateTexture) +/*N*/ { +/*N*/ GetDisplayGeometry().CreateDefaultTexture( +/*N*/ ((GetTextureProjectionX() > 0) ? B3D_CREATE_DEFAULT_X : FALSE) +/*N*/ |((GetTextureProjectionY() > 0) ? B3D_CREATE_DEFAULT_Y : FALSE), +/*N*/ GetTextureProjectionX() > 1); +/*N*/ } +/*N*/ +/*N*/ // Am Ende der Geometrieerzeugung das model an den erzeugten +/*N*/ // PolyObj's setzen, d.h. beim ueberladen dieser Funktion +/*N*/ // den parent am Ende rufen. +/*N*/ if(bCreateE3dPolyObj) +/*N*/ SetModel(pModel); +/*N*/ +/*N*/ // Das Ende der Geometrieerzeugung anzeigen +/*N*/ aDisplayGeometry.EndDescription(); +/*N*/ } + +/*N*/ void E3dCompoundObject::ReCreateGeometry(BOOL bCreateOldGeometry) +/*N*/ { +/*N*/ // Geometrie zerstoeren +/*N*/ DestroyGeometry(); +/*N*/ +/*N*/ // Flag fuer Geometrieerzeugung setzen +/*N*/ bCreateE3dPolyObj = bCreateOldGeometry; +/*N*/ +/*N*/ // ... und neu erzeugen +/*N*/ CreateGeometry(); +/*N*/ } + +/************************************************************************* +|* +|* Geometrieerzeugung +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::AddGeometry(const PolyPolygon3D& rPolyPolygon3D, +/*N*/ BOOL bHintIsComplex, BOOL bOutline) +/*N*/ { +/*N*/ if(rPolyPolygon3D.Count()) +/*N*/ { +/*N*/ // eventuell alte Geometrie erzeugen (z.B. zum speichern) +/*N*/ if(bCreateE3dPolyObj) +/*N*/ { +/*N*/ E3dPolyObj* pObj = new E3dPolyObj( +/*N*/ rPolyPolygon3D, GetDoubleSided(), TRUE); +/*N*/ pObj->SetPartOfParent(); +/*N*/ Insert3DObj(pObj); +/*N*/ } +/*N*/ +/*N*/ // neue Geometrie erzeugen +/*N*/ for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ ) +/*N*/ { +/*N*/ const Polygon3D& rPoly3D = rPolyPolygon3D[a]; +/*N*/ aDisplayGeometry.StartObject(bHintIsComplex, bOutline); +/*N*/ for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ ) +/*N*/ aDisplayGeometry.AddEdge(rPoly3D[b]); +/*N*/ } +/*N*/ aDisplayGeometry.EndObject(); +/*N*/ +/*N*/ // LocalBoundVolume pflegen +/*N*/ aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize()); +/*N*/ +/*N*/ // Eigenes BoundVol nicht mehr gueltig +/*N*/ SetBoundVolInvalid(); +/*N*/ SetRectsDirty(); +/*N*/ } +/*N*/ } + +/*?*/ void E3dCompoundObject::AddGeometry( +/*?*/ const PolyPolygon3D& rPolyPolygon3D, +/*?*/ const PolyPolygon3D& rPolyNormal3D, +/*?*/ BOOL bHintIsComplex, BOOL bOutline) +/*?*/ { +/*?*/ if(rPolyPolygon3D.Count()) +/*?*/ { +/*?*/ // eventuell alte Geometrie erzeugen (z.B. zum speichern) +/*?*/ if(bCreateE3dPolyObj) +/*?*/ { +/*?*/ E3dPolyObj* pObj = new E3dPolyObj( +/*?*/ rPolyPolygon3D, rPolyNormal3D, GetDoubleSided(), TRUE); +/*?*/ pObj->SetPartOfParent(); +/*?*/ Insert3DObj(pObj); +/*?*/ } +/*?*/ +/*?*/ // neue Geometrie erzeugen +/*?*/ for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ ) +/*?*/ { +/*?*/ const Polygon3D& rPoly3D = rPolyPolygon3D[a]; +/*?*/ const Polygon3D& rNormal3D = rPolyNormal3D[a]; +/*?*/ aDisplayGeometry.StartObject(bHintIsComplex, bOutline); +/*?*/ for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ ) +/*?*/ aDisplayGeometry.AddEdge(rPoly3D[b], rNormal3D[b]); +/*?*/ } +/*?*/ aDisplayGeometry.EndObject(); +/*?*/ +/*?*/ // LocalBoundVolume pflegen +/*?*/ aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize()); +/*?*/ +/*?*/ // Eigenes BoundVol nicht mehr gueltig +/*?*/ SetBoundVolInvalid(); +/*?*/ SetRectsDirty(); +/*?*/ } +/*?*/ } + +/*N*/ void E3dCompoundObject::AddGeometry( +/*N*/ const PolyPolygon3D& rPolyPolygon3D, +/*N*/ const PolyPolygon3D& rPolyNormal3D, +/*N*/ const PolyPolygon3D& rPolyTexture3D, +/*N*/ BOOL bHintIsComplex, BOOL bOutline) +/*N*/ { +/*N*/ if(rPolyPolygon3D.Count()) +/*N*/ { +/*N*/ // eventuell alte Geometrie erzeugen (z.B. zum speichern) +/*N*/ if(bCreateE3dPolyObj) +/*N*/ { +/*N*/ E3dPolyObj* pObj = new E3dPolyObj( +/*N*/ rPolyPolygon3D, rPolyNormal3D, +/*N*/ rPolyTexture3D, GetDoubleSided(), TRUE); +/*N*/ pObj->SetPartOfParent(); +/*N*/ Insert3DObj(pObj); +/*N*/ } +/*N*/ +/*N*/ // neue Geometrie erzeugen +/*N*/ for(USHORT a = 0; a < rPolyPolygon3D.Count(); a++ ) +/*N*/ { +/*N*/ const Polygon3D& rPoly3D = rPolyPolygon3D[a]; +/*N*/ const Polygon3D& rNormal3D = rPolyNormal3D[a]; +/*N*/ const Polygon3D& rTexture3D = rPolyTexture3D[a]; +/*N*/ aDisplayGeometry.StartObject(bHintIsComplex, bOutline); +/*N*/ for(USHORT b = 0; b < rPoly3D.GetPointCount(); b++ ) +/*N*/ aDisplayGeometry.AddEdge(rPoly3D[b], rNormal3D[b], rTexture3D[b]); +/*N*/ } +/*N*/ aDisplayGeometry.EndObject(); +/*N*/ +/*N*/ // LocalBoundVolume pflegen +/*N*/ aLocalBoundVol.Union(rPolyPolygon3D.GetPolySize()); +/*N*/ +/*N*/ // Eigenes BoundVol nicht mehr gueltig +/*N*/ SetBoundVolInvalid(); +/*N*/ SetRectsDirty(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Hilfsfunktionen zur Geometrieerzeugung +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::RotatePoly( +/*N*/ PolyPolygon3D& rPolyPolyRotate, +/*N*/ Matrix4D& rRotMat) +/*N*/ { +/*N*/ USHORT nPolyCnt = rPolyPolyRotate.Count(); +/*N*/ +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ Polygon3D& rPolyRotate = rPolyPolyRotate[a]; +/*N*/ USHORT nPntCnt = rPolyRotate.GetPointCount(); +/*N*/ +/*N*/ for(UINT16 b=0;b<nPntCnt;b++) +/*N*/ rPolyRotate[b] *= rRotMat; +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::GrowPoly( +/*N*/ PolyPolygon3D& rPolyPolyGrow, +/*N*/ PolyPolygon3D& rPolyPolyNormals, +/*N*/ double fFactor) +/*N*/ { +/*N*/ USHORT nPolyCnt = rPolyPolyGrow.Count(); +/*N*/ +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ Polygon3D& rPolyGrow = rPolyPolyGrow[a]; +/*N*/ const Polygon3D& rPolyNormals = rPolyPolyNormals[a]; +/*N*/ USHORT nPntCnt = rPolyGrow.GetPointCount(); +/*N*/ +/*N*/ for(UINT16 b=0;b<nPntCnt;b++) +/*N*/ rPolyGrow[b] += rPolyNormals[b] * fFactor; +/*N*/ } +/*N*/ } + + +/*N*/ void E3dCompoundObject::ScalePoly( +/*N*/ PolyPolygon3D& rPolyPolyScale, +/*N*/ double fFactor) +/*N*/ { +/*N*/ USHORT nPolyCnt = rPolyPolyScale.Count(); +/*N*/ Vector3D aMiddle = rPolyPolyScale.GetMiddle(); +/*N*/ +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ Polygon3D& rPolyScale = rPolyPolyScale[a]; +/*N*/ USHORT nPntCnt = rPolyScale.GetPointCount(); +/*N*/ +/*N*/ for(UINT16 b=0;b<nPntCnt;b++) +/*N*/ rPolyScale[b] = ((rPolyScale[b] - aMiddle) * fFactor) + aMiddle; +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::CreateFront( +/*N*/ const PolyPolygon3D& rPolyPoly3D, +/*N*/ const PolyPolygon3D& rFrontNormals, +/*N*/ BOOL bCreateNormals, +/*N*/ BOOL bCreateTexture) +/*N*/ { +/*N*/ // Vorderseite +/*N*/ if(bCreateNormals) +/*N*/ { +/*N*/ if(bCreateTexture) +/*N*/ { +/*N*/ // Polygon fuer die Textur erzeugen +/*N*/ PolyPolygon3D aPolyTexture = rPolyPoly3D; +/*N*/ Volume3D aSize = aPolyTexture.GetPolySize(); +/*N*/ Matrix4D aTrans; +/*N*/ +/*N*/ aTrans.Identity(); +/*N*/ aTrans.Translate(-aSize.MinVec()); +/*N*/ aPolyTexture.Transform(aTrans); +/*N*/ +/*N*/ double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0); +/*N*/ +/*N*/ if(aSize.GetWidth() != 0.0) +/*N*/ fFactorX = 1.0 / aSize.GetWidth(); +/*N*/ +/*N*/ if(aSize.GetHeight() != 0.0) +/*N*/ fFactorY = 1.0 / aSize.GetHeight(); +/*N*/ +/*N*/ if(aSize.GetDepth() != 0.0) +/*N*/ fFactorZ = 1.0 / aSize.GetDepth(); +/*N*/ +/*N*/ aTrans.Identity(); +/*N*/ aTrans.Scale(fFactorX, -fFactorY, fFactorZ); +/*N*/ aTrans.Translate(Vector3D(0.0, 1.0, 0.0)); +/*N*/ aPolyTexture.Transform(aTrans); +/*N*/ +/*N*/ AddGeometry(rPolyPoly3D, rFrontNormals, aPolyTexture, TRUE); +/*N*/ } +/*N*/ else +/*N*/ AddGeometry(rPolyPoly3D, rFrontNormals, TRUE); +/*N*/ } +/*N*/ else +/*N*/ AddGeometry(rPolyPoly3D, TRUE); +/*N*/ } + +/*N*/ void E3dCompoundObject::AddFrontNormals( +/*N*/ const PolyPolygon3D& rPolyPoly3D, +/*N*/ PolyPolygon3D& rNormalsFront, +/*N*/ Vector3D &rOffset) +/*N*/ { +/*N*/ Vector3D aFrontNormal = -rOffset; +/*N*/ aFrontNormal.Normalize(); +/*N*/ USHORT nPolyCnt = rPolyPoly3D.Count(); +/*N*/ +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ const Polygon3D& rPoly3D = rPolyPoly3D[a]; +/*N*/ Polygon3D& rNormalPoly = rNormalsFront[a]; +/*N*/ USHORT nPntCnt = rPoly3D.GetPointCount(); +/*N*/ +/*N*/ for(UINT16 b=0;b<nPntCnt;b++) +/*N*/ { +/*N*/ rNormalPoly[b] += aFrontNormal; +/*N*/ rNormalPoly[b].Normalize(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::CreateBack( +/*N*/ const PolyPolygon3D& rPolyPoly3D, +/*N*/ const PolyPolygon3D& rBackNormals, +/*N*/ BOOL bCreateNormals, +/*N*/ BOOL bCreateTexture) +/*N*/ { +/*N*/ // PolyPolygon umdrehen +/*N*/ PolyPolygon3D aLocalPoly = rPolyPoly3D; +/*N*/ aLocalPoly.FlipDirections(); +/*N*/ +/*N*/ // Rueckseite +/*N*/ if(bCreateNormals) +/*N*/ { +/*N*/ PolyPolygon3D aLocalNormals = rBackNormals; +/*N*/ aLocalNormals.FlipDirections(); +/*N*/ if(bCreateTexture) +/*N*/ { +/*N*/ // Polygon fuer die Textur erzeugen +/*N*/ PolyPolygon3D aPolyTexture(aLocalPoly); +/*N*/ Volume3D aSize = aPolyTexture.GetPolySize(); +/*N*/ Matrix4D aTrans; +/*N*/ +/*N*/ aTrans.Identity(); +/*N*/ aTrans.Translate(-aSize.MinVec()); +/*N*/ aPolyTexture.Transform(aTrans); +/*N*/ +/*N*/ double fFactorX(1.0), fFactorY(1.0), fFactorZ(1.0); +/*N*/ +/*N*/ if(aSize.GetWidth() != 0.0) +/*N*/ fFactorX = 1.0 / aSize.GetWidth(); +/*N*/ +/*N*/ if(aSize.GetHeight() != 0.0) +/*N*/ fFactorY = 1.0 / aSize.GetHeight(); +/*N*/ +/*N*/ if(aSize.GetDepth() != 0.0) +/*N*/ fFactorZ = 1.0 / aSize.GetDepth(); +/*N*/ +/*N*/ aTrans.Identity(); +/*N*/ aTrans.Scale(fFactorX, -fFactorY, fFactorZ); +/*N*/ aTrans.Translate(Vector3D(0.0, 1.0, 0.0)); +/*N*/ aPolyTexture.Transform(aTrans); +/*N*/ +/*N*/ AddGeometry(aLocalPoly, aLocalNormals, aPolyTexture, TRUE); +/*N*/ } +/*N*/ else +/*N*/ AddGeometry(aLocalPoly, aLocalNormals, TRUE); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ AddGeometry(aLocalPoly, TRUE); +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::AddBackNormals( +/*N*/ const PolyPolygon3D& rPolyPoly3D, +/*N*/ PolyPolygon3D& rNormalsBack, +/*N*/ Vector3D& rOffset) +/*N*/ { +/*N*/ Vector3D aBackNormal = rOffset; +/*N*/ aBackNormal.Normalize(); +/*N*/ USHORT nPolyCnt = rPolyPoly3D.Count(); +/*N*/ +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ const Polygon3D& rPoly3D = rPolyPoly3D[a]; +/*N*/ Polygon3D& rNormalPoly = rNormalsBack[a]; +/*N*/ USHORT nPntCnt = rPoly3D.GetPointCount(); +/*N*/ +/*N*/ for(UINT16 b=0;b<nPntCnt;b++) +/*N*/ { +/*N*/ rNormalPoly[b] += aBackNormal; +/*N*/ rNormalPoly[b].Normalize(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::CreateInBetween( +/*N*/ const PolyPolygon3D& rPolyPolyFront, +/*N*/ const PolyPolygon3D& rPolyPolyBack, +/*N*/ const PolyPolygon3D& rFrontNormals, +/*N*/ const PolyPolygon3D& rBackNormals, +/*N*/ BOOL bCreateNormals, +/*N*/ double fSurroundFactor, +/*N*/ double fTextureStart, +/*N*/ double fTextureDepth, +/*N*/ BOOL bRotateTexture90) +/*N*/ { +/*N*/ USHORT nPolyCnt = rPolyPolyFront.Count(); +/*N*/ BOOL bCreateTexture = (fTextureDepth == 0.0) ? FALSE : TRUE; +/*N*/ double fPolyLength, fPolyPos; +/*N*/ USHORT nLastIndex; +/*N*/ +/*N*/ // Verbindungsstuecke +/*N*/ if(bCreateNormals) +/*N*/ { +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a]; +/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a]; +/*N*/ +/*N*/ const Polygon3D& rPolyNormalsFront = rFrontNormals[a]; +/*N*/ const Polygon3D& rPolyNormalsBack = rBackNormals[a]; +/*N*/ +/*N*/ Polygon3D aRect3D(4); +/*N*/ Polygon3D aNormal3D(4); +/*N*/ Polygon3D aTexture3D(4); +/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount(); +/*N*/ USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0; +/*N*/ +/*N*/ aRect3D[3] = rPoly3DFront[nPrefillIndex]; +/*N*/ aRect3D[2] = rPoly3DBack[nPrefillIndex]; +/*N*/ aNormal3D[3] = rPolyNormalsFront[nPrefillIndex]; +/*N*/ aNormal3D[2] = rPolyNormalsBack[nPrefillIndex]; +/*N*/ +/*N*/ if(bCreateTexture) +/*N*/ { +/*N*/ fPolyLength = rPoly3DFront.GetLength(); +/*N*/ fPolyPos = 0.0; +/*N*/ nLastIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0; +/*N*/ +/*N*/ if(bRotateTexture90) +/*N*/ { +/*N*/ // X,Y vertauschen +/*N*/ aTexture3D[3].X() = fTextureStart; +/*N*/ aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor; +/*N*/ +/*N*/ aTexture3D[2].X() = fTextureStart + fTextureDepth; +/*N*/ aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTexture3D[3].X() = fPolyPos * fSurroundFactor; +/*N*/ aTexture3D[3].Y() = fTextureStart; +/*N*/ +/*N*/ aTexture3D[2].X() = fPolyPos * fSurroundFactor; +/*N*/ aTexture3D[2].Y() = fTextureStart + fTextureDepth; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++) +/*N*/ { +/*N*/ aRect3D[0] = aRect3D[3]; +/*N*/ aRect3D[1] = aRect3D[2]; +/*N*/ +/*N*/ aRect3D[3] = rPoly3DFront[i]; +/*N*/ aRect3D[2] = rPoly3DBack[i]; +/*N*/ +/*N*/ aNormal3D[0] = aNormal3D[3]; +/*N*/ aNormal3D[1] = aNormal3D[2]; +/*N*/ +/*N*/ aNormal3D[3] = rPolyNormalsFront[i]; +/*N*/ aNormal3D[2] = rPolyNormalsBack[i]; +/*N*/ +/*N*/ if(bCreateTexture) +/*N*/ { +/*N*/ // Texturkoordinaten ermitteln +/*N*/ Vector3D aPart = rPoly3DFront[i] - rPoly3DFront[nLastIndex]; +/*N*/ fPolyPos += aPart.GetLength() / fPolyLength; +/*N*/ nLastIndex = i; +/*N*/ +/*N*/ // Der Abschnitt am Polygon entspricht dem Teil +/*N*/ // von fPolyPos bis fPolyPos+fPartLength +/*N*/ +/*N*/ aTexture3D[0] = aTexture3D[3]; +/*N*/ aTexture3D[1] = aTexture3D[2]; +/*N*/ +/*N*/ if(bRotateTexture90) +/*N*/ { +/*N*/ // X,Y vertauschen +/*N*/ aTexture3D[3].X() = fTextureStart; +/*N*/ aTexture3D[3].Y() = (1.0 - fPolyPos) * fSurroundFactor; +/*N*/ +/*N*/ aTexture3D[2].X() = fTextureStart + fTextureDepth; +/*N*/ aTexture3D[2].Y() = (1.0 - fPolyPos) * fSurroundFactor; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTexture3D[3].X() = fPolyPos * fSurroundFactor; +/*N*/ aTexture3D[3].Y() = fTextureStart; +/*N*/ +/*N*/ aTexture3D[2].X() = fPolyPos * fSurroundFactor; +/*N*/ aTexture3D[2].Y() = fTextureStart + fTextureDepth; +/*N*/ } +/*N*/ +/*N*/ AddGeometry(aRect3D, aNormal3D, aTexture3D, FALSE); +/*N*/ } +/*N*/ else +/*N*/ AddGeometry(aRect3D, aNormal3D, FALSE); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a]; +/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a]; +/*N*/ Polygon3D aRect3D(4); +/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount(); +/*N*/ USHORT nPrefillIndex = rPoly3DFront.IsClosed() ? nPntCnt - 1 : 0; +/*N*/ +/*N*/ aRect3D[3] = rPoly3DFront[nPrefillIndex]; +/*N*/ aRect3D[2] = rPoly3DBack[nPrefillIndex]; +/*N*/ +/*N*/ for (USHORT i = rPoly3DFront.IsClosed() ? 0 : 1; i < nPntCnt; i++) +/*N*/ { +/*N*/ aRect3D[0] = aRect3D[3]; +/*N*/ aRect3D[1] = aRect3D[2]; +/*N*/ +/*N*/ aRect3D[3] = rPoly3DFront[i]; +/*N*/ aRect3D[2] = rPoly3DBack[i]; +/*N*/ +/*N*/ AddGeometry(aRect3D, FALSE); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void E3dCompoundObject::AddInBetweenNormals( +/*N*/ const PolyPolygon3D& rPolyPolyFront, +/*N*/ const PolyPolygon3D& rPolyPolyBack, +/*N*/ PolyPolygon3D& rNormals, +/*N*/ BOOL bSmoothed) +/*N*/ { +/*N*/ USHORT nPolyCnt = rPolyPolyFront.Count(); +/*N*/ +/*N*/ // Verbindungsstuecke +/*N*/ for(UINT16 a=0;a<nPolyCnt;a++) +/*N*/ { +/*N*/ const Polygon3D& rPoly3DFront = rPolyPolyFront[a]; +/*N*/ const Polygon3D& rPoly3DBack = rPolyPolyBack[a]; +/*N*/ Polygon3D& rNormalPoly = rNormals[a]; +/*N*/ USHORT nPntCnt = rPoly3DFront.GetPointCount(); +/*N*/ +/*N*/ if(rPoly3DBack.IsClosed()) +/*N*/ { +/*N*/ Vector3D aNormal = (rPoly3DBack[nPntCnt - 1] - rPoly3DFront[nPntCnt - 1]) +/*N*/ |(rPoly3DFront[0] - rPoly3DFront[nPntCnt - 1]); +/*N*/ aNormal.Normalize(); +/*N*/ for (USHORT i = 0; i < nPntCnt; i++) +/*N*/ { +/*N*/ Vector3D aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i]) +/*N*/ |(rPoly3DFront[(i+1 == nPntCnt) ? 0 : i+1] - rPoly3DFront[i]); +/*N*/ aNextNormal.Normalize(); +/*N*/ if(bSmoothed) +/*N*/ { +/*N*/ Vector3D aMidNormal = aNormal + aNextNormal; +/*N*/ aMidNormal.Normalize(); +/*N*/ rNormalPoly[i] += aMidNormal; +/*N*/ } +/*N*/ else +/*N*/ rNormalPoly[i] += aNormal; +/*N*/ rNormalPoly[i].Normalize(); +/*N*/ aNormal = aNextNormal; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Vector3D aNormal; +/*N*/ if(rPoly3DBack[0] == rPoly3DFront[0]) +/*N*/ { +/*N*/ aNormal = (rPoly3DBack[1] - rPoly3DFront[1]) +/*N*/ |(rPoly3DFront[1] - rPoly3DFront[0]); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aNormal = (rPoly3DBack[0] - rPoly3DFront[0]) +/*N*/ |(rPoly3DFront[1] - rPoly3DFront[0]); +/*N*/ } +/*N*/ aNormal.Normalize(); +/*N*/ rNormalPoly[0] += aNormal; rNormalPoly[0].Normalize(); +/*N*/ for (USHORT i = 1; i < nPntCnt; i++) +/*N*/ { +/*N*/ Vector3D aNextNormal; +/*N*/ if(i+1 == nPntCnt) +/*N*/ { +/*N*/ aNextNormal = aNormal; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aNextNormal = (rPoly3DBack[i] - rPoly3DFront[i]) +/*N*/ |(rPoly3DFront[i+1] - rPoly3DFront[i]); +/*N*/ } +/*N*/ aNextNormal.Normalize(); +/*N*/ if(bSmoothed) +/*N*/ { +/*N*/ Vector3D aMidNormal = aNormal + aNextNormal; +/*N*/ aMidNormal.Normalize(); +/*N*/ rNormalPoly[i] += aMidNormal; +/*N*/ } +/*N*/ else +/*N*/ rNormalPoly[i] += aNormal; +/*N*/ rNormalPoly[i].Normalize(); +/*N*/ aNormal = aNextNormal; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Copy-Operator +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Ausgabeparameter an 3D-Kontext setzen +|* +\************************************************************************/ + + + + +/************************************************************************* +|* +|* Hittest fuer 3D-Objekte, wird an Geometrie weitergegeben +|* +\************************************************************************/ + +/*N*/ SdrObject* E3dCompoundObject::CheckHit(const Point& rPnt, USHORT nTol, +/*N*/ const SetOfByte* pVisiLayer) const +/*N*/ { +/*N*/ E3dPolyScene* pScene = (E3dPolyScene*)GetScene(); +/*N*/ if(pScene) +/*N*/ { +/*N*/ // HitLine holen in ObjektKoordinaten +/*N*/ // ObjectTrans setzen +/*N*/ Matrix4D mTransform = ((E3dCompoundObject*)this)->GetFullTransform(); +/*N*/ pScene->GetCameraSet().SetObjectTrans(mTransform); +/*N*/ +/*N*/ // HitPoint Front und Back erzeugen und umrechnen +/*N*/ Vector3D aFront(rPnt.X(), rPnt.Y(), 0.0); +/*N*/ Vector3D aBack(rPnt.X(), rPnt.Y(), ZBUFFER_DEPTH_RANGE); +/*N*/ aFront = pScene->GetCameraSet().ViewToObjectCoor(aFront); +/*N*/ aBack = pScene->GetCameraSet().ViewToObjectCoor(aBack); +/*N*/ +/*N*/ const Volume3D& rBoundVol = ((E3dCompoundObject*)this)->GetBoundVolume(); +/*N*/ if(rBoundVol.IsValid()) +/*N*/ { +/*N*/ double fXMax = aFront.X(); +/*N*/ double fXMin = aBack.X(); +/*N*/ +/*N*/ if(fXMax < fXMin) +/*N*/ { +/*N*/ fXMax = aBack.X(); +/*N*/ fXMin = aFront.X(); +/*N*/ } +/*N*/ +/*N*/ if(rBoundVol.MinVec().X() <= fXMax && rBoundVol.MaxVec().X() >= fXMin) +/*N*/ { +/*N*/ double fYMax = aFront.Y(); +/*N*/ double fYMin = aBack.Y(); +/*N*/ +/*N*/ if(fYMax < fYMin) +/*N*/ { +/*N*/ fYMax = aBack.Y(); +/*N*/ fYMin = aFront.Y(); +/*N*/ } +/*N*/ +/*N*/ if(rBoundVol.MinVec().Y() <= fYMax && rBoundVol.MaxVec().Y() >= fYMin) +/*N*/ { +/*N*/ double fZMax = aFront.Z(); +/*N*/ double fZMin = aBack.Z(); +/*N*/ +/*N*/ if(fZMax < fZMin) +/*N*/ { +/*N*/ fZMax = aBack.Z(); +/*N*/ fZMin = aFront.Z(); +/*N*/ } +/*N*/ +/*N*/ if(rBoundVol.MinVec().Z() <= fZMax && rBoundVol.MaxVec().Z() >= fZMin) +/*N*/ { +/*N*/ // Geometrie herstellen +/*N*/ if(!bGeometryValid) +/*?*/ ((E3dCompoundObject*)this)->ReCreateGeometry(); +/*N*/ +/*N*/ // 3D Volumes schneiden sich, teste in der Geometrie +/*N*/ // auf Basis der Projektion weiter +/*N*/ if(((E3dCompoundObject*)this)->aDisplayGeometry.CheckHit(aFront, aBack, nTol) != -1L) +/*?*/ return ((E3dCompoundObject*)this); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/************************************************************************* +|* +|* Geometrie des Objektes auf angegebenen Punkt zentrieren +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Schattenattribute holen +|* +\************************************************************************/ + + + + + + +/*N*/ BOOL E3dCompoundObject::DoDrawShadow() +/*N*/ { +/*N*/ const SfxItemSet& rSet = GetItemSet(); +/*N*/ BOOL bRetval(FALSE); +/*N*/ BOOL bShadOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue(); +/*N*/ +/*N*/ if(bShadOn) +/*N*/ { +/*?*/ bRetval = TRUE; +/*?*/ +/*?*/ if(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue() == XFILL_NONE) +/*?*/ { +/*?*/ if(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue() == XLINE_NONE) +/*?*/ { +/*?*/ bRetval = FALSE; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ return bRetval; +/*N*/ } + +/************************************************************************* +|* +|* Objekt als WireFrame zeichnen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Create vertical polygons for line polygon +|* +\************************************************************************/ + +// #78972# +/*N*/ void E3dCompoundObject::ImpCompleteLinePolygon(PolyPolygon3D& rLinePolyPoly, +/*N*/ sal_uInt16 nPolysPerRun, BOOL bClosed) +/*N*/ { +/*N*/ if(rLinePolyPoly.Count() && nPolysPerRun) +/*N*/ { +/*N*/ // get number of layers +/*N*/ sal_uInt16 nLayers(rLinePolyPoly.Count() / nPolysPerRun); +/*N*/ sal_uInt16 a, b, c; +/*N*/ +/*N*/ // add vertical Polygons if at least two horizontal ones exist +/*N*/ if(nLayers > 1) +/*N*/ { +/*N*/ for(a = 0; a < nPolysPerRun; a++) +/*N*/ { +/*N*/ const sal_uInt16 nPntCnt = rLinePolyPoly[a].GetPointCount(); +/*N*/ +/*N*/ for(b = 0; b < nPntCnt; b++) +/*N*/ { +/*N*/ Polygon3D aNewVerPoly(bClosed ? nLayers + 1 : nLayers); +/*N*/ +/*N*/ for(c = 0; c < nLayers; c++) +/*N*/ aNewVerPoly[c] = rLinePolyPoly[(c * nPolysPerRun) + a][b]; +/*N*/ +/*N*/ // evtl. set first point again to close polygon +/*N*/ if(bClosed) +/*N*/ aNewVerPoly[aNewVerPoly.GetPointCount()] = aNewVerPoly[0]; +/*N*/ +/*N*/ // insert +/*N*/ rLinePolyPoly.Insert(aNewVerPoly); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // open closed polygons +/*N*/ for(a = 0; a < rLinePolyPoly.Count(); a++) +/*N*/ { +/*N*/ if(rLinePolyPoly[a].IsClosed()) +/*N*/ { +/*N*/ rLinePolyPoly[a][rLinePolyPoly[a].GetPointCount()] = rLinePolyPoly[a][0]; +/*N*/ rLinePolyPoly[a].SetClosed(FALSE); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/************************************************************************* +|* +|* Ein Segment fuer Extrude oder Lathe erzeugen +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::ImpCreateSegment( +/*N*/ const PolyPolygon3D& rFront, // vorderes Polygon +/*N*/ const PolyPolygon3D& rBack, // hinteres Polygon +/*N*/ const PolyPolygon3D* pPrev, // smooth uebergang zu Vorgaenger +/*N*/ const PolyPolygon3D* pNext, // smooth uebergang zu Nachfolger +/*N*/ BOOL bCreateFront, // vorderen Deckel erzeugen +/*N*/ BOOL bCreateBack, // hinteren Deckel erzeugen +/*N*/ double fPercentDiag, // Anteil des Deckels an der Tiefe +/*N*/ BOOL bSmoothLeft, // Glaetten der umlaufenden Normalen links +/*N*/ BOOL bSmoothRight, // Glaetten der umlaufenden Normalen rechts +/*N*/ BOOL bSmoothFrontBack, // Glaetten der Abschlussflaechen +/*N*/ double fSurroundFactor, // Wertebereich der Texturkoordinaten im Umlauf +/*N*/ double fTextureStart, // TexCoor ueber Extrude-Tiefe +/*N*/ double fTextureDepth, // TexCoor ueber Extrude-Tiefe +/*N*/ BOOL bCreateTexture, +/*N*/ BOOL bCreateNormals, +/*N*/ BOOL bCharacterExtrude, // FALSE=exakt, TRUE=ohne Ueberschneidungen +/*N*/ BOOL bRotateTexture90, // Textur der Seitenflaechen um 90 Grad kippen +/*N*/ PolyPolygon3D* pLineGeometry // For creation of line geometry +/*N*/ ) +/*N*/ { +/*N*/ PolyPolygon3D aNormalsLeft, aNormalsRight; +/*N*/ AddInBetweenNormals(rFront, rBack, aNormalsLeft, bSmoothLeft); +/*N*/ AddInBetweenNormals(rFront, rBack, aNormalsRight, bSmoothRight); +/*N*/ Vector3D aOffset = rBack.GetMiddle() - rFront.GetMiddle(); +/*N*/ +/*N*/ // Ausnahmen: Nicht geschlossen +/*N*/ if(!rFront.IsClosed()) +/*N*/ { +/*N*/ bCreateFront = FALSE; +/*N*/ } +/*N*/ if(!rBack.IsClosed()) +/*N*/ { +/*N*/ bCreateBack = FALSE; +/*N*/ } +/*N*/ +/*N*/ // Ausnahmen: Einfache Linie +/*N*/ if(rFront[0].GetPointCount() < 3 || (!bCreateFront && !bCreateBack)) +/*N*/ { +/*N*/ fPercentDiag = 0.0; +/*N*/ } +/*N*/ +/*N*/ if(fPercentDiag == 0.0) +/*N*/ { +/*N*/ // Ohne Schraegen, Vorderseite +/*N*/ if(bCreateFront) +/*N*/ { +/*N*/ PolyPolygon3D aNormalsFront; +/*N*/ AddFrontNormals(rFront, aNormalsFront, aOffset); +/*N*/ +/*N*/ if(!bSmoothFrontBack) +/*N*/ CreateFront(rFront, aNormalsFront, bCreateNormals, bCreateTexture); +/*N*/ if(bSmoothLeft) +/*N*/ AddFrontNormals(rFront, aNormalsLeft, aOffset); +/*N*/ if(bSmoothFrontBack) +/*?*/ CreateFront(rFront, aNormalsLeft, bCreateNormals, bCreateTexture); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if(pPrev) +/*N*/ AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft); +/*N*/ } +/*N*/ +/*N*/ // Ohne Schraegen, Rueckseite +/*N*/ if(bCreateBack) +/*N*/ { +/*N*/ PolyPolygon3D aNormalsBack; +/*N*/ AddBackNormals(rBack, aNormalsBack, aOffset); +/*N*/ +/*N*/ if(!bSmoothFrontBack) +/*N*/ CreateBack(rBack, aNormalsBack, bCreateNormals, bCreateTexture); +/*N*/ if(bSmoothRight) +/*N*/ AddBackNormals(rBack, aNormalsRight, aOffset); +/*N*/ if(bSmoothFrontBack) +/*?*/ CreateBack(rBack, aNormalsRight, bCreateNormals, bCreateTexture); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if(pNext) +/*N*/ AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight); +/*N*/ } +/*N*/ +/*N*/ // eigentliches Zwischenstueck +/*N*/ CreateInBetween(rFront, rBack, +/*N*/ aNormalsLeft, aNormalsRight, +/*N*/ bCreateNormals, +/*N*/ fSurroundFactor, +/*N*/ fTextureStart, +/*N*/ fTextureDepth, +/*N*/ bRotateTexture90); +/*N*/ +/*N*/ // #78972# +/*N*/ if(pLineGeometry) +/*N*/ { +/*N*/ pLineGeometry->Insert(rFront); +/*N*/ if(bCreateBack) +/*N*/ pLineGeometry->Insert(rBack); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Mit Scraegen, Vorderseite +/*N*/ PolyPolygon3D aLocalFront = rFront; +/*N*/ PolyPolygon3D aLocalBack = rBack; +/*N*/ double fExtrudeDepth, fDiagLen; +/*N*/ double fTexMidStart = fTextureStart; +/*N*/ double fTexMidDepth = fTextureDepth; +/*N*/ +/*N*/ if(bCreateFront || bCreateBack) +/*N*/ { +/*N*/ fExtrudeDepth = aOffset.GetLength(); +/*N*/ fDiagLen = fPercentDiag * fExtrudeDepth; +/*N*/ } +/*N*/ +/*N*/ PolyPolygon3D aOuterFront; +/*N*/ PolyPolygon3D aOuterBack; +/*N*/ +/*N*/ if(bCreateFront) +/*N*/ { +/*N*/ PolyPolygon3D aNormalsOuterFront; +/*N*/ AddFrontNormals(aLocalFront, aNormalsOuterFront, aOffset); +/*N*/ +/*N*/ if(bCharacterExtrude) +/*N*/ { +/*N*/ // Polygon kopieren +/*N*/ aOuterFront = aLocalFront; +/*N*/ +/*N*/ // notwendige Normalen erzeugen +/*N*/ PolyPolygon3D aGrowDirection; +/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft); +/*N*/ +/*N*/ // Groesse inneres Polygon merken +/*N*/ Volume3D aOldSize(aLocalFront.GetPolySize()); +/*N*/ +/*N*/ // Inneres Polygon vergroessern +/*N*/ GrowPoly(aLocalFront, aGrowDirection, fDiagLen); +/*N*/ +/*N*/ // Inneres Polygon nach innen verschieben +/*N*/ //GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen); +/*N*/ +/*N*/ // Neue Groesse inneres Polygon feststellen +/*N*/ Volume3D aNewSize(aLocalFront.GetPolySize()); +/*N*/ +/*N*/ // Skalierung feststellen (nur X,Y) +/*N*/ Vector3D aScaleVec( +/*N*/ (aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0, +/*N*/ (aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0, +/*N*/ (aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0); +/*N*/ +/*N*/ // Transformation bilden +/*N*/ Matrix4D aTransMat; +/*N*/ aTransMat.Scale(aScaleVec); +/*N*/ +/*N*/ // aeusseres und inneres Polygon skalieren +/*N*/ aLocalFront.Transform(aTransMat); +/*N*/ aOuterFront.Transform(aTransMat); +/*N*/ +/*N*/ // Neue Groesse aktualisieren +/*N*/ aNewSize = aLocalFront.GetPolySize(); +/*N*/ +/*N*/ // Translation feststellen +/*N*/ Vector3D aTransVec( +/*N*/ aOldSize.MinVec().X() - aNewSize.MinVec().X(), +/*N*/ aOldSize.MinVec().Y() - aNewSize.MinVec().Y(), +/*N*/ aOldSize.MinVec().Z() - aNewSize.MinVec().Z()); +/*N*/ +/*N*/ // Transformation bilden +/*N*/ aTransMat.Identity(); +/*N*/ aTransMat.Translate(aTransVec); +/*N*/ +/*N*/ // aeusseres und inneres Polygon skalieren +/*N*/ aLocalFront.Transform(aTransMat); +/*N*/ aOuterFront.Transform(aTransMat); +/*N*/ +/*N*/ // move aLocalFront again, scale and translate has moved it back +/*N*/ GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Polygon kopieren +/*N*/ aOuterFront = aLocalFront; +/*N*/ +/*N*/ // notwendige Normalen erzeugen +/*N*/ PolyPolygon3D aGrowDirection; +/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothLeft); +/*N*/ +/*N*/ // Aeusseres Polygon verkleinern +/*N*/ GrowPoly(aOuterFront, aGrowDirection, -fDiagLen); +/*N*/ aOuterFront.CorrectGrownPoly(aLocalFront); +/*N*/ +/*N*/ // Inneres Polygon nach innen verschieben +/*N*/ GrowPoly(aLocalFront, aNormalsOuterFront, -fDiagLen); +/*N*/ } +/*N*/ +/*N*/ // eventuell noch glaetten +/*N*/ if(bSmoothLeft) +/*N*/ { +/*N*/ if(bSmoothFrontBack) +/*?*/ AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsOuterFront, bSmoothLeft); +/*N*/ AddInBetweenNormals(aOuterFront, aLocalFront, aNormalsLeft, bSmoothLeft); +/*N*/ } +/*N*/ +/*N*/ // vordere Zwischenstuecke erzeugen +/*N*/ CreateInBetween(aOuterFront, aLocalFront, +/*N*/ aNormalsOuterFront, aNormalsLeft, +/*N*/ bCreateNormals, +/*N*/ fSurroundFactor, +/*N*/ fTextureStart, +/*N*/ fTextureDepth * fPercentDiag, +/*N*/ bRotateTexture90); +/*N*/ +/*N*/ // Vorderseite erzeugen +/*N*/ CreateFront(aOuterFront, aNormalsOuterFront, bCreateNormals, bCreateTexture); +/*N*/ +/*N*/ // Weitere Texturwerte setzen +/*N*/ fTexMidStart += fTextureDepth * fPercentDiag; +/*N*/ fTexMidDepth -= fTextureDepth * fPercentDiag; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if(pPrev) +/*?*/ AddInBetweenNormals(*pPrev, rFront, aNormalsLeft, bSmoothLeft); +/*N*/ } +/*N*/ +/*N*/ // Mit Scraegen, Rueckseite +/*N*/ if(bCreateBack) +/*N*/ { +/*N*/ PolyPolygon3D aNormalsOuterBack; +/*N*/ AddBackNormals(aLocalBack, aNormalsOuterBack, aOffset); +/*N*/ +/*N*/ if(bCharacterExtrude) +/*N*/ { +/*N*/ // Polygon kopieren +/*N*/ aOuterBack = aLocalBack; +/*N*/ +/*N*/ // notwendige Normalen erzeugen +/*N*/ PolyPolygon3D aGrowDirection; +/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight); +/*N*/ +/*N*/ // Groesse inneres Polygon merken +/*N*/ Volume3D aOldSize(aLocalBack.GetPolySize()); +/*N*/ +/*N*/ // Inneres Polygon vergroessern +/*N*/ GrowPoly(aLocalBack, aGrowDirection, fDiagLen); +/*N*/ +/*N*/ // Inneres Polygon nach innen verschieben +/*N*/ //GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen); +/*N*/ +/*N*/ // Neue Groesse inneres Polygon feststellen +/*N*/ Volume3D aNewSize(aLocalBack.GetPolySize()); +/*N*/ +/*N*/ // Skalierung feststellen (nur X,Y) +/*N*/ Vector3D aScaleVec( +/*N*/ (aNewSize.GetWidth() != 0.0) ? aOldSize.GetWidth() / aNewSize.GetWidth() : 1.0, +/*N*/ (aNewSize.GetHeight() != 0.0) ? aOldSize.GetHeight() / aNewSize.GetHeight() : 1.0, +/*N*/ (aNewSize.GetDepth() != 0.0) ? aOldSize.GetDepth() / aNewSize.GetDepth() : 1.0); +/*N*/ +/*N*/ // Transformation bilden +/*N*/ Matrix4D aTransMat; +/*N*/ aTransMat.Scale(aScaleVec); +/*N*/ +/*N*/ // aeusseres und inneres Polygon skalieren +/*N*/ aLocalBack.Transform(aTransMat); +/*N*/ aOuterBack.Transform(aTransMat); +/*N*/ +/*N*/ // Neue Groesse aktualisieren +/*N*/ aNewSize = aLocalBack.GetPolySize(); +/*N*/ +/*N*/ // Translation feststellen +/*N*/ Vector3D aTransVec( +/*N*/ aOldSize.MinVec().X() - aNewSize.MinVec().X(), +/*N*/ aOldSize.MinVec().Y() - aNewSize.MinVec().Y(), +/*N*/ aOldSize.MinVec().Z() - aNewSize.MinVec().Z()); +/*N*/ +/*N*/ // Transformation bilden +/*N*/ aTransMat.Identity(); +/*N*/ aTransMat.Translate(aTransVec); +/*N*/ +/*N*/ // aeusseres und inneres Polygon skalieren +/*N*/ aLocalBack.Transform(aTransMat); +/*N*/ aOuterBack.Transform(aTransMat); +/*N*/ +/*N*/ // move aLocalBack again, scale and translate has moved it back +/*N*/ GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Polygon kopieren +/*N*/ aOuterBack = aLocalBack; +/*N*/ +/*N*/ // notwendige Normalen erzeugen +/*N*/ PolyPolygon3D aGrowDirection; +/*N*/ AddInBetweenNormals(aLocalFront, aLocalBack, aGrowDirection, bSmoothRight); +/*N*/ +/*N*/ // Aeusseres Polygon verkleinern +/*N*/ GrowPoly(aOuterBack, aGrowDirection, -fDiagLen); +/*N*/ aOuterBack.CorrectGrownPoly(aLocalBack); +/*N*/ +/*N*/ // Inneres Polygon nach innen verschieben +/*N*/ GrowPoly(aLocalBack, aNormalsOuterBack, -fDiagLen); +/*N*/ } +/*N*/ +/*N*/ // eventuell noch glaetten +/*N*/ if(bSmoothRight) +/*N*/ { +/*N*/ if(bSmoothFrontBack) +/*?*/ AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsOuterBack, bSmoothRight); +/*N*/ AddInBetweenNormals(aLocalBack, aOuterBack, aNormalsRight, bSmoothRight); +/*N*/ } +/*N*/ +/*N*/ // vordere Zwischenstuecke erzeugen +/*N*/ // hintere Zwischenstuecke erzeugen +/*N*/ CreateInBetween(aLocalBack, aOuterBack, +/*N*/ aNormalsRight, aNormalsOuterBack, +/*N*/ bCreateNormals, +/*N*/ fSurroundFactor, +/*N*/ fTextureStart + (fTextureDepth * (1.0 - fPercentDiag)), +/*N*/ fTextureDepth * fPercentDiag, +/*N*/ bRotateTexture90); +/*N*/ +/*N*/ // Rueckseite erzeugen +/*N*/ CreateBack(aOuterBack, aNormalsOuterBack, bCreateNormals, bCreateTexture); +/*N*/ +/*N*/ // Weitere Texturwerte setzen +/*N*/ fTexMidDepth -= fTextureDepth * fPercentDiag; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if(pNext) +/*?*/ AddInBetweenNormals(rBack, *pNext, aNormalsRight, bSmoothRight); +/*?*/ } +/*N*/ +/*N*/ // eigentliches Zwischenstueck +/*N*/ CreateInBetween(aLocalFront, aLocalBack, +/*N*/ aNormalsLeft, aNormalsRight, +/*N*/ bCreateNormals, +/*N*/ fSurroundFactor, +/*N*/ fTexMidStart, +/*N*/ fTexMidDepth, +/*N*/ bRotateTexture90); +/*N*/ +/*N*/ // #78972# +/*N*/ if(pLineGeometry) +/*N*/ { +/*N*/ if(bCreateFront) +/*N*/ pLineGeometry->Insert(aOuterFront); +/*N*/ pLineGeometry->Insert(aLocalFront); +/*N*/ if(bCreateBack) +/*N*/ { +/*N*/ pLineGeometry->Insert(aLocalBack); +/*N*/ pLineGeometry->Insert(aOuterBack); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* Parameter Geometrieerzeugung setzen +|* +\************************************************************************/ + + + +/************************************************************************* +|* +|* DisplayGeometry rausruecken +|* +\************************************************************************/ + +/*N*/ B3dGeometry& E3dCompoundObject::GetDisplayGeometry() +/*N*/ { +/*N*/ // Geometrie herstellen +/*N*/ if(!bGeometryValid) +/*?*/ ReCreateGeometry(); +/*N*/ +/*N*/ return aDisplayGeometry; +/*N*/ } + +/************************************************************************* +|* +|* Material des Objektes +|* +\************************************************************************/ + +/*N*/ void E3dCompoundObject::SetMaterialAmbientColor(const Color& rColor) +/*N*/ { +/*N*/ if(aMaterialAmbientColor != rColor) +/*N*/ { +/*?*/ aMaterialAmbientColor = rColor; +/*N*/ } +/*N*/ } + + + +/************************************************************************* +|* +|* 3D Ausgabe +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Objekt als Kontur in das Polygon einfuegen +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Schatten fuer 3D-Objekte zeichnen +|* +\************************************************************************/ + + + + +/************************************************************************* +|* +|* convert given PolyPolygon3D to screen coor +|* +\************************************************************************/ + + +/************************************************************************* +|* +|* Attribute setzen +|* +\************************************************************************/ + +// private support routines for ItemSet access. NULL pointer means clear item. +/*N*/ void E3dCompoundObject::PostItemChange(const sal_uInt16 nWhich) +/*N*/ { +/*N*/ // call parent +/*N*/ E3dObject::PostItemChange(nWhich); +/*N*/ +/*N*/ // handle value change +/*N*/ switch(nWhich) +/*N*/ { +/*N*/ case SDRATTR_3DOBJ_DOUBLE_SIDED: +/*N*/ { +/*N*/ bGeometryValid = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ case SDRATTR_3DOBJ_NORMALS_KIND: +/*N*/ { +/*N*/ bGeometryValid = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ case SDRATTR_3DOBJ_NORMALS_INVERT: +/*N*/ { +/*N*/ bGeometryValid = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ case SDRATTR_3DOBJ_TEXTURE_PROJ_X: +/*N*/ { +/*N*/ bGeometryValid = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ case SDRATTR_3DOBJ_TEXTURE_PROJ_Y: +/*N*/ { +/*N*/ bGeometryValid = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } + +// EOF +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |