diff options
author | Mathias Bauer <mba@openoffice.org> | 2009-12-15 21:55:40 +0100 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2009-12-15 21:55:40 +0100 |
commit | 4770f50e0c8e6706f0f514bd73a8bcfd7dd88cb3 (patch) | |
tree | b21b3409ecc71d4802ab2f5eafd6e01c3bfd5254 /tools | |
parent | 003fc5390522ecad9e1f3a2c99b2a0a324ae5473 (diff) |
#i107706#: liquidate goodies module
Diffstat (limited to 'tools')
-rw-r--r-- | tools/inc/tools/b3dtrans.hxx | 355 | ||||
-rw-r--r-- | tools/prj/d.lst | 1 | ||||
-rw-r--r-- | tools/source/generic/b3dtrans.cxx | 1017 | ||||
-rw-r--r-- | tools/source/generic/makefile.mk | 2 |
4 files changed, 1375 insertions, 0 deletions
diff --git a/tools/inc/tools/b3dtrans.hxx b/tools/inc/tools/b3dtrans.hxx new file mode 100644 index 000000000000..e2b1bdb8d262 --- /dev/null +++ b/tools/inc/tools/b3dtrans.hxx @@ -0,0 +1,355 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b3dtrans.hxx,v $ + * $Revision: 1.6 $ + * + * 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. + * + ************************************************************************/ + +#ifndef _B3D_B3DTRANS_HXX +#define _B3D_B3DTRANS_HXX + +// Zu verwendender DephRange des Z-Buffers +#define ZBUFFER_DEPTH_RANGE ((double)(256L * 256L * 256L)) + +#include <basegfx/matrix/b3dhommatrix.hxx> +#include <basegfx/range/b3drange.hxx> +#include <tools/gen.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <tools/toolsdllapi.h> + +// Vorausdeklarationen + +/************************************************************************* +|* +|* Unterstuetzte Methoden, um das Seitenverhaeltnis einzuhalten +|* +\************************************************************************/ + +enum Base3DRatio +{ + Base3DRatioGrow = 1, + Base3DRatioShrink, + Base3DRatioMiddle +}; + +/************************************************************************* +|* +|* Typ der Projektion +|* +\************************************************************************/ + +enum Base3DProjectionType +{ + Base3DProjectionTypeParallel = 1, + Base3DProjectionTypePerspective +}; + +/************************************************************************* +|* +|* Transformationen fuer alle 3D Ausgaben +|* +\************************************************************************/ + +class TOOLS_DLLPUBLIC B3dTransformationSet +{ +private: + // Object Matrix Object -> World + basegfx::B3DHomMatrix maObjectTrans; + basegfx::B3DHomMatrix maInvObjectTrans; + + // Orientation Matrix + basegfx::B3DHomMatrix maOrientation; + basegfx::B3DHomMatrix maInvOrientation; + + // Projection Matrix + basegfx::B3DHomMatrix maProjection; + basegfx::B3DHomMatrix maInvProjection; + + // Texture Matrices + basegfx::B2DHomMatrix maTexture; + + // Speziell zum Umwandeln von Punkten Objekt -> Device + basegfx::B3DHomMatrix maObjectToDevice; + + // Transponierte Inverse fuer Vectortransformationen + basegfx::B3DHomMatrix maInvTransObjectToEye; + + // Transformation World->View + basegfx::B3DHomMatrix maMatFromWorldToView; + basegfx::B3DHomMatrix maInvMatFromWorldToView; + + // Parameters for ViewportTransformation + basegfx::B3DVector maScale; + basegfx::B3DVector maTranslate; + + // ViewPlane DeviceRectangle (vom Benutzer gesetzt) + double mfLeftBound; + double mfRightBound; + double mfBottomBound; + double mfTopBound; + + // Near and far clipping planes + double mfNearBound; + double mfFarBound; + + // Seitenverhaeltnis der 3D Abbildung (Y / X) + // default ist 1:1 -> 1.0 + // Deaktivieren mit 0.0 als Wert + double mfRatio; + + // Der gesetzte Ausgabebereich (in logischen Koordinaten) + // und der dazugehoerige sichtbare Bereich + Rectangle maViewportRectangle; + Rectangle maVisibleRectangle; + + // Die tatsaechlich von CalcViewport gesetzten Abmessungen + // des sichtbaren Bereichs (in logischen Koordinaten) + Rectangle maSetBound; + + // Methode zur Aufrechterhaltung des Seitenverhaeltnisses + // default ist Base3DRatioGrow + Base3DRatio meRatio; + + // Flags + unsigned mbPerspective : 1; + unsigned mbWorldToViewValid : 1; + unsigned mbInvTransObjectToEyeValid : 1; + unsigned mbObjectToDeviceValid : 1; + unsigned mbProjectionValid : 1; + +public: + B3dTransformationSet(); + virtual ~B3dTransformationSet(); + + // Zurueck auf Standard + void Reset(); + + // ObjectTrans + void SetObjectTrans(const basegfx::B3DHomMatrix& rObj); + const basegfx::B3DHomMatrix& GetObjectTrans() { return maObjectTrans; } + const basegfx::B3DHomMatrix& GetInvObjectTrans() { return maInvObjectTrans; } + + // Orientation + void SetOrientation( + basegfx::B3DPoint aVRP = basegfx::B3DPoint(0.0,0.0,1.0), + basegfx::B3DVector aVPN = basegfx::B3DVector(0.0,0.0,1.0), + basegfx::B3DVector aVUP = basegfx::B3DVector(0.0,1.0,0.0)); + void SetOrientation(basegfx::B3DHomMatrix& mOrient); + const basegfx::B3DHomMatrix& GetOrientation() { return maOrientation; } + const basegfx::B3DHomMatrix& GetInvOrientation() { return maInvOrientation; } + + // Projection + void SetProjection(const basegfx::B3DHomMatrix& mProject); + const basegfx::B3DHomMatrix& GetProjection(); + const basegfx::B3DHomMatrix& GetInvProjection(); + + // Texture + void SetTexture(const basegfx::B2DHomMatrix& rTxt); + const basegfx::B2DHomMatrix& GetTexture() { return maTexture; } + + // Seitenverhaeltnis und Modus zu dessen Aufrechterhaltung + double GetRatio() { return mfRatio; } + void SetRatio(double fNew=1.0); + Base3DRatio GetRatioMode() { return meRatio; } + void SetRatioMode(Base3DRatio eNew=Base3DRatioGrow); + + // Parameter der ViewportTransformation + void SetDeviceRectangle(double fL=-1.0, double fR=1.0, double fB=-1.0, double fT=1.0, sal_Bool bBroadCastChange=sal_True); + void SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange=sal_True); + void GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT); + basegfx::B3DRange GetDeviceVolume(); + double GetDeviceRectangleWidth() const { return mfRightBound - mfLeftBound; } + double GetDeviceRectangleHeight() const { return mfTopBound - mfBottomBound; } + void SetFrontClippingPlane(double fF=0.0); + double GetFrontClippingPlane() { return mfNearBound; } + void SetBackClippingPlane(double fB=1.0); + double GetBackClippingPlane() { return mfFarBound; } + void SetPerspective(sal_Bool bNew); + sal_Bool GetPerspective() { return mbPerspective; } + void SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible); + void SetViewportRectangle(Rectangle& rRect) { SetViewportRectangle(rRect, rRect); } + const Rectangle& GetViewportRectangle() { return maViewportRectangle; } + void CalcViewport(); + + // Spezielle Matritzen anfordern + basegfx::B3DHomMatrix GetMatFromObjectToView(); + + // Transponierte Inverse fuer Vectortransformationen + const basegfx::B3DHomMatrix& GetInvTransObjectToEye(); + + // Speziell zum Umwandeln von Punkten Objekt -> Device + const basegfx::B3DHomMatrix& GetObjectToDevice(); + + // Speziell zum Umwandeln von Punkten World -> View + const basegfx::B3DHomMatrix& GetMatFromWorldToView(); + const basegfx::B3DHomMatrix& GetInvMatFromWorldToView(); + + // Bounds des Viewports lesen + const Rectangle& GetLogicalViewportBounds(); + const basegfx::B3DVector& GetScale(); + const basegfx::B3DVector& GetTranslate(); + + // Direkter Zugriff auf verschiedene Transformationen + const basegfx::B3DPoint WorldToEyeCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint EyeToWorldCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint EyeToViewCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ViewToEyeCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint WorldToViewCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ViewToWorldCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint DeviceToViewCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ViewToDeviceCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ObjectToWorldCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint WorldToObjectCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ObjectToViewCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ViewToObjectCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint ObjectToEyeCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint EyeToObjectCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint DeviceToEyeCoor(const basegfx::B3DPoint& rVec); + const basegfx::B3DPoint EyeToDeviceCoor(const basegfx::B3DPoint& rVec); + + const basegfx::B3DPoint InvTransObjectToEye(const basegfx::B3DPoint& rVec); + const basegfx::B2DPoint TransTextureCoor(const basegfx::B2DPoint& rVec); + + static void Frustum( + basegfx::B3DHomMatrix& rTarget, + double fLeft = -1.0, double fRight = 1.0, + double fBottom = -1.0, double fTop = 1.0, + double fNear = 0.001, double fFar = 1.0); + static void Ortho( + basegfx::B3DHomMatrix& rTarget, + double fLeft = -1.0, double fRight = 1.0, + double fBottom = -1.0, double fTop = 1.0, + double fNear = 0.0, double fFar = 1.0); + static void Orientation( + basegfx::B3DHomMatrix& rTarget, + basegfx::B3DPoint aVRP = basegfx::B3DPoint(0.0,0.0,1.0), + basegfx::B3DVector aVPN = basegfx::B3DVector(0.0,0.0,1.0), + basegfx::B3DVector aVUP = basegfx::B3DVector(0.0,1.0,0.0)); + +protected: + void PostSetObjectTrans(); + void PostSetOrientation(); + void PostSetProjection(); + void PostSetTexture(); + void PostSetViewport(); + + void CalcMatObjectToDevice(); + void CalcMatFromWorldToView(); + void CalcMatInvTransObjectToEye(); + + virtual void DeviceRectangleChange(); +}; + +/************************************************************************* +|* +|* Viewport fuer B3D +|* +|* Verwendet wird hier ein vereinfachtes System, bei dem der abzubildende +|* Punkt durch VRP repraesentiert wird +|* +\************************************************************************/ + +class TOOLS_DLLPUBLIC B3dViewport : public B3dTransformationSet +{ +private: + basegfx::B3DPoint aVRP; // View Reference Point + basegfx::B3DVector aVPN; // View Plane Normal + basegfx::B3DVector aVUV; // View Up Vector + +public: + B3dViewport(); + virtual ~B3dViewport(); + + void SetVRP(const basegfx::B3DPoint& rNewVRP); + void SetVPN(const basegfx::B3DVector& rNewVPN); + void SetVUV(const basegfx::B3DVector& rNewVUV); + void SetViewportValues( + const basegfx::B3DPoint& rNewVRP, + const basegfx::B3DVector& rNewVPN, + const basegfx::B3DVector& rNewVUV); + + const basegfx::B3DPoint& GetVRP() const { return aVRP; } + const basegfx::B3DVector& GetVPN() const { return aVPN; } + const basegfx::B3DVector& GetVUV() const { return aVUV; } + +protected: + void CalcOrientation(); +}; + +/************************************************************************* +|* +|* Kamera fuer B3D +|* +\************************************************************************/ + +class TOOLS_DLLPUBLIC B3dCamera : public B3dViewport +{ +private: + basegfx::B3DPoint aPosition; + basegfx::B3DPoint aCorrectedPosition; + basegfx::B3DVector aLookAt; + double fFocalLength; + double fBankAngle; + + unsigned bUseFocalLength : 1; + +public: + B3dCamera( + const basegfx::B3DPoint& rPos = basegfx::B3DPoint(0.0, 0.0, 1.0), + const basegfx::B3DVector& rLkAt = basegfx::B3DVector(0.0, 0.0, 0.0), + double fFocLen = 35.0, double fBnkAng = 0.0, + sal_Bool bUseFocLen = sal_False); + virtual ~B3dCamera(); + + // Positionen + void SetPosition(const basegfx::B3DPoint& rNewPos); + const basegfx::B3DPoint& GetPosition() const { return aPosition; } + void SetLookAt(const basegfx::B3DVector& rNewLookAt); + const basegfx::B3DVector& GetLookAt() const { return aLookAt; } + void SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt); + + // Brennweite in mm + void SetFocalLength(double fLen); + double GetFocalLength() const { return fFocalLength; } + + // Neigung links/rechts + void SetBankAngle(double fAngle); + double GetBankAngle() const { return fBankAngle; } + + // FocalLength Flag + void SetUseFocalLength(sal_Bool bNew); + sal_Bool GetUseFocalLength() const { return (sal_Bool)bUseFocalLength; } + +protected: + void CalcNewViewportValues(); + sal_Bool CalcFocalLength(); + + virtual void DeviceRectangleChange(); +}; + + +#endif // _B3D_B3DTRANS_HXX diff --git a/tools/prj/d.lst b/tools/prj/d.lst index 3208ecbb3168..76cb0107453c 100644 --- a/tools/prj/d.lst +++ b/tools/prj/d.lst @@ -112,6 +112,7 @@ mkdir: %_DEST%\inc%_EXT%\bootstrp ..\inc\tools\testtoolloader.hxx %_DEST%\inc%_EXT%\tools\testtoolloader.hxx ..\inc\tools\svborder.hxx %_DEST%\inc%_EXT%\tools\svborder.hxx ..\inc\tools\getprocessworkingdir.hxx %_DEST%\inc%_EXT%\tools\getprocessworkingdir.hxx +..\inc\tools\b3dtrans.hxx %_DEST%\inc%_EXT%\tools\b3dtrans.hxx ..\%__SRC%\bin\rscdep.exe %_DEST%\bin%_EXT%\rscdep.exe ..\%__SRC%\bin\rscdep %_DEST%\bin%_EXT%\rscdep diff --git a/tools/source/generic/b3dtrans.cxx b/tools/source/generic/b3dtrans.cxx new file mode 100644 index 000000000000..251a532dd9d1 --- /dev/null +++ b/tools/source/generic/b3dtrans.cxx @@ -0,0 +1,1017 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: b3dtrans.cxx,v $ + * $Revision: 1.10.42.1 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_tools.hxx" +#include <tools/b3dtrans.hxx> +#include <tools/debug.hxx> + +/************************************************************************* +|* +|* Transformationen fuer alle 3D Ausgaben +|* +\************************************************************************/ + +B3dTransformationSet::B3dTransformationSet() +{ + Reset(); +} + +B3dTransformationSet::~B3dTransformationSet() +{ +} + +void B3dTransformationSet::Orientation(basegfx::B3DHomMatrix& rTarget, basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP) +{ + rTarget.translate( -aVRP.getX(), -aVRP.getY(), -aVRP.getZ()); + aVUP.normalize(); + aVPN.normalize(); + basegfx::B3DVector aRx(aVUP); + basegfx::B3DVector aRy(aVPN); + aRx = aRx.getPerpendicular(aRy); + aRx.normalize(); + aRy = aRy.getPerpendicular(aRx); + aRy.normalize(); + basegfx::B3DHomMatrix aTemp; + aTemp.set(0, 0, aRx.getX()); + aTemp.set(0, 1, aRx.getY()); + aTemp.set(0, 2, aRx.getZ()); + aTemp.set(1, 0, aRy.getX()); + aTemp.set(1, 1, aRy.getY()); + aTemp.set(1, 2, aRy.getZ()); + aTemp.set(2, 0, aVPN.getX()); + aTemp.set(2, 1, aVPN.getY()); + aTemp.set(2, 2, aVPN.getZ()); + rTarget *= aTemp; +} + +void B3dTransformationSet::Frustum(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar) +{ + if(!(fNear > 0.0)) + { + fNear = 0.001; + } + if(!(fFar > 0.0)) + { + fFar = 1.0; + } + if(fNear == fFar) + { + fFar = fNear + 1.0; + } + if(fLeft == fRight) + { + fLeft -= 1.0; + fRight += 1.0; + } + if(fTop == fBottom) + { + fBottom -= 1.0; + fTop += 1.0; + } + basegfx::B3DHomMatrix aTemp; + + aTemp.set(0, 0, 2.0 * fNear / (fRight - fLeft)); + aTemp.set(1, 1, 2.0 * fNear / (fTop - fBottom)); + aTemp.set(0, 2, (fRight + fLeft) / (fRight - fLeft)); + aTemp.set(1, 2, (fTop + fBottom) / (fTop - fBottom)); + aTemp.set(2, 2, -1.0 * ((fFar + fNear) / (fFar - fNear))); + aTemp.set(3, 2, -1.0); + aTemp.set(2, 3, -1.0 * ((2.0 * fFar * fNear) / (fFar - fNear))); + aTemp.set(3, 3, 0.0); + + rTarget *= aTemp; +} + +void B3dTransformationSet::Ortho(basegfx::B3DHomMatrix& rTarget, double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar) +{ + if(fNear == fFar) + { + DBG_ERROR("Near and far clipping plane in Ortho definition are identical"); + fFar = fNear + 1.0; + } + if(fLeft == fRight) + { + DBG_ERROR("Left and right in Ortho definition are identical"); + fLeft -= 1.0; + fRight += 1.0; + } + if(fTop == fBottom) + { + DBG_ERROR("Top and bottom in Ortho definition are identical"); + fBottom -= 1.0; + fTop += 1.0; + } + basegfx::B3DHomMatrix aTemp; + + aTemp.set(0, 0, 2.0 / (fRight - fLeft)); + aTemp.set(1, 1, 2.0 / (fTop - fBottom)); + aTemp.set(2, 2, -1.0 * (2.0 / (fFar - fNear))); + aTemp.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft))); + aTemp.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom))); + aTemp.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear))); + + rTarget *= aTemp; +} + +/************************************************************************* +|* +|* Reset der Werte +|* +\************************************************************************/ + +void B3dTransformationSet::Reset() +{ + // Matritzen auf Einheitsmatritzen + maObjectTrans.identity(); + PostSetObjectTrans(); + + Orientation(maOrientation); + PostSetOrientation(); + + maTexture.identity(); + + mfLeftBound = mfBottomBound = -1.0; + mfRightBound = mfTopBound = 1.0; + mfNearBound = 0.001; + mfFarBound = 1.001; + + meRatio = Base3DRatioGrow; + mfRatio = 0.0; + + maViewportRectangle = Rectangle(-1, -1, 2, 2); + maVisibleRectangle = maViewportRectangle; + + mbPerspective = sal_True; + + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + + CalcViewport(); +} + +/************************************************************************* +|* +|* Objekttransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetObjectTrans(const basegfx::B3DHomMatrix& rObj) +{ + maObjectTrans = rObj; + + mbObjectToDeviceValid = sal_False; + mbInvTransObjectToEyeValid = sal_False; + + PostSetObjectTrans(); +} + +void B3dTransformationSet::PostSetObjectTrans() +{ + // Zuweisen und Inverse bestimmen + maInvObjectTrans = maObjectTrans; + maInvObjectTrans.invert(); +} + +/************************************************************************* +|* +|* Orientierungstransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetOrientation( basegfx::B3DPoint aVRP, basegfx::B3DVector aVPN, basegfx::B3DVector aVUP) +{ + maOrientation.identity(); + Orientation(maOrientation, aVRP, aVPN, aVUP); + + mbInvTransObjectToEyeValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + + PostSetOrientation(); +} + +void B3dTransformationSet::SetOrientation(basegfx::B3DHomMatrix& mOrient) +{ + maOrientation = mOrient; + + mbInvTransObjectToEyeValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + + PostSetOrientation(); +} + +void B3dTransformationSet::PostSetOrientation() +{ + // Zuweisen und Inverse bestimmen + maInvOrientation = maOrientation; + maInvOrientation.invert(); +} + +/************************************************************************* +|* +|* Projektionstransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetProjection(const basegfx::B3DHomMatrix& mProject) +{ + maProjection = mProject; + PostSetProjection(); +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetProjection() +{ + if(!mbProjectionValid) + CalcViewport(); + return maProjection; +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvProjection() +{ + if(!mbProjectionValid) + CalcViewport(); + return maInvProjection; +} + +void B3dTransformationSet::PostSetProjection() +{ + // Zuweisen und Inverse bestimmen + maInvProjection = GetProjection(); + maInvProjection.invert(); + + // Abhaengige Matritzen invalidieren + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; +} + +/************************************************************************* +|* +|* Texturtransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetTexture(const basegfx::B2DHomMatrix& rTxt) +{ + maTexture = rTxt; + PostSetTexture(); +} + +void B3dTransformationSet::PostSetTexture() +{ +} + +/************************************************************************* +|* +|* Viewport-Transformation +|* +\************************************************************************/ + +void B3dTransformationSet::CalcViewport() +{ + // Faktoren fuer die Projektion + double fLeft(mfLeftBound); + double fRight(mfRightBound); + double fBottom(mfBottomBound); + double fTop(mfTopBound); + + // Soll das Seitenverhaeltnis Beachtung finden? + // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen + if(GetRatio() != 0.0) + { + // Berechne aktuelles Seitenverhaeltnis der Bounds + double fBoundWidth = (double)(maViewportRectangle.GetWidth() + 1); + double fBoundHeight = (double)(maViewportRectangle.GetHeight() + 1); + double fActRatio = 1; + double fFactor; + + if(fBoundWidth != 0.0) + fActRatio = fBoundHeight / fBoundWidth; + // FIXME else in this case has a lot of problems, should this return. + + switch(meRatio) + { + case Base3DRatioShrink : + { + // Kleineren Teil vergroessern + if(fActRatio > mfRatio) + { + // X vergroessern + fFactor = 1.0 / fActRatio; + fRight *= fFactor; + fLeft *= fFactor; + } + else + { + // Y vergroessern + fFactor = fActRatio; + fTop *= fFactor; + fBottom *= fFactor; + } + break; + } + case Base3DRatioGrow : + { + // GroesserenTeil verkleinern + if(fActRatio > mfRatio) + { + // Y verkleinern + fFactor = fActRatio; + fTop *= fFactor; + fBottom *= fFactor; + } + else + { + // X verkleinern + fFactor = 1.0 / fActRatio; + fRight *= fFactor; + fLeft *= fFactor; + } + break; + } + case Base3DRatioMiddle : + { + // Mitteln + fFactor = ((1.0 / fActRatio) + 1.0) / 2.0; + fRight *= fFactor; + fLeft *= fFactor; + fFactor = (fActRatio + 1.0) / 2.0; + fTop *= fFactor; + fBottom *= fFactor; + break; + } + } + } + + // Ueberschneiden sich Darstellungsflaeche und Objektflaeche? + maSetBound = maViewportRectangle; + + // Mit den neuen Werten Projektion und ViewPort setzen + basegfx::B3DHomMatrix aNewProjection; + + // #i36281# + // OpenGL needs a little more rough additional size to not let + // the front face vanish. Changed from SMALL_DVALUE to 0.000001, + // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE. + const double fDistPart((mfFarBound - mfNearBound) * 0.0001); + + // Near, Far etwas grosszuegiger setzen, um falsches, + // zu kritisches clippen zu verhindern + if(mbPerspective) + { + Frustum(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart); + } + else + { + Ortho(aNewProjection, fLeft, fRight, fBottom, fTop, mfNearBound - fDistPart, mfFarBound + fDistPart); + } + + // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden + mbProjectionValid = sal_True; + + // Neue Projektion setzen + SetProjection(aNewProjection); + + // fill parameters for ViewportTransformation + // Translation + maTranslate.setX((double)maSetBound.Left() + ((maSetBound.GetWidth() - 1L) / 2.0)); + maTranslate.setY((double)maSetBound.Top() + ((maSetBound.GetHeight() - 1L) / 2.0)); + maTranslate.setZ(ZBUFFER_DEPTH_RANGE / 2.0); + + // Skalierung + maScale.setX((maSetBound.GetWidth() - 1L) / 2.0); + maScale.setY((maSetBound.GetHeight() - 1L) / -2.0); + maScale.setZ(ZBUFFER_DEPTH_RANGE / 2.0); + + // Auf Veraenderung des ViewPorts reagieren + PostSetViewport(); +} + +void B3dTransformationSet::SetRatio(double fNew) +{ + if(mfRatio != fNew) + { + mfRatio = fNew; + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::SetRatioMode(Base3DRatio eNew) +{ + if(meRatio != eNew) + { + meRatio = eNew; + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::SetDeviceRectangle(double fL, double fR, double fB, double fT, + sal_Bool bBroadCastChange) +{ + if(fL != mfLeftBound || fR != mfRightBound || fB != mfBottomBound || fT != mfTopBound) + { + mfLeftBound = fL; + mfRightBound = fR; + mfBottomBound = fB; + mfTopBound = fT; + + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + + // Aenderung bekanntmachen + if(bBroadCastChange) + DeviceRectangleChange(); + } +} + +void B3dTransformationSet::SetDeviceVolume(const basegfx::B3DRange& rVol, sal_Bool bBroadCastChange) +{ + SetDeviceRectangle(rVol.getMinX(), rVol.getMaxX(), rVol.getMinY(), rVol.getMaxY(), bBroadCastChange); + SetFrontClippingPlane(rVol.getMinZ()); + SetBackClippingPlane(rVol.getMaxZ()); +} + +void B3dTransformationSet::DeviceRectangleChange() +{ +} + +void B3dTransformationSet::GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT) +{ + fL = mfLeftBound; + fR = mfRightBound; + fB = mfBottomBound; + fT = mfTopBound; + + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; +} + +basegfx::B3DRange B3dTransformationSet::GetDeviceVolume() +{ + basegfx::B3DRange aRet; + + aRet.expand(basegfx::B3DTuple(mfLeftBound, mfBottomBound, mfNearBound)); + aRet.expand(basegfx::B3DTuple(mfRightBound, mfTopBound, mfFarBound)); + + return aRet; +} + +void B3dTransformationSet::SetFrontClippingPlane(double fF) +{ + if(mfNearBound != fF) + { + mfNearBound = fF; + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::SetBackClippingPlane(double fB) +{ + if(mfFarBound != fB) + { + mfFarBound = fB; + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::SetPerspective(sal_Bool bNew) +{ + if(mbPerspective != bNew) + { + mbPerspective = bNew; + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible) +{ + if(rRect != maViewportRectangle || rVisible != maVisibleRectangle) + { + maViewportRectangle = rRect; + maVisibleRectangle = rVisible; + + mbProjectionValid = sal_False; + mbObjectToDeviceValid = sal_False; + mbWorldToViewValid = sal_False; + } +} + +void B3dTransformationSet::PostSetViewport() +{ +} + +const Rectangle& B3dTransformationSet::GetLogicalViewportBounds() +{ + if(!mbProjectionValid) + CalcViewport(); + return maSetBound; +} + +const basegfx::B3DVector& B3dTransformationSet::GetScale() +{ + if(!mbProjectionValid) + CalcViewport(); + return maScale; +} + +const basegfx::B3DVector& B3dTransformationSet::GetTranslate() +{ + if(!mbProjectionValid) + CalcViewport(); + return maTranslate; +} + +/************************************************************************* +|* +|* Hilfsmatrixberechnungsroutinen +|* +\************************************************************************/ + +void B3dTransformationSet::CalcMatObjectToDevice() +{ + // ObjectToDevice berechnen (Orientation * Projection * Object) + maObjectToDevice = maObjectTrans; + maObjectToDevice *= maOrientation; + maObjectToDevice *= GetProjection(); + + // auf gueltig setzen + mbObjectToDeviceValid = sal_True; +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetObjectToDevice() +{ + if(!mbObjectToDeviceValid) + CalcMatObjectToDevice(); + return maObjectToDevice; +} + +void B3dTransformationSet::CalcMatInvTransObjectToEye() +{ + maInvTransObjectToEye = maObjectTrans; + maInvTransObjectToEye *= maOrientation; + maInvTransObjectToEye.invert(); + maInvTransObjectToEye.transpose(); + + // eventuelle Translationen rausschmeissen, da diese + // Matrix nur zur Transformation von Vektoren gedacht ist + maInvTransObjectToEye.set(3, 0, 0.0); + maInvTransObjectToEye.set(3, 1, 0.0); + maInvTransObjectToEye.set(3, 2, 0.0); + maInvTransObjectToEye.set(3, 3, 1.0); + + // auf gueltig setzen + mbInvTransObjectToEyeValid = sal_True; +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvTransObjectToEye() +{ + if(!mbInvTransObjectToEyeValid) + CalcMatInvTransObjectToEye(); + return maInvTransObjectToEye; +} + +basegfx::B3DHomMatrix B3dTransformationSet::GetMatFromObjectToView() +{ + basegfx::B3DHomMatrix aFromObjectToView = GetObjectToDevice(); + + const basegfx::B3DVector& rScale(GetScale()); + aFromObjectToView.scale(rScale.getX(), rScale.getY(), rScale.getZ()); + const basegfx::B3DVector& rTranslate(GetTranslate()); + aFromObjectToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ()); + + return aFromObjectToView; +} + +void B3dTransformationSet::CalcMatFromWorldToView() +{ + maMatFromWorldToView = maOrientation; + maMatFromWorldToView *= GetProjection(); + const basegfx::B3DVector& rScale(GetScale()); + maMatFromWorldToView.scale(rScale.getX(), rScale.getY(), rScale.getZ()); + const basegfx::B3DVector& rTranslate(GetTranslate()); + maMatFromWorldToView.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ()); + maInvMatFromWorldToView = maMatFromWorldToView; + maInvMatFromWorldToView.invert(); + + // gueltig setzen + mbWorldToViewValid = sal_True; +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetMatFromWorldToView() +{ + if(!mbWorldToViewValid) + CalcMatFromWorldToView(); + return maMatFromWorldToView; +} + +const basegfx::B3DHomMatrix& B3dTransformationSet::GetInvMatFromWorldToView() +{ + if(!mbWorldToViewValid) + CalcMatFromWorldToView(); + return maInvMatFromWorldToView; +} + +/************************************************************************* +|* +|* Direkter Zugriff auf verschiedene Transformationen +|* +\************************************************************************/ + +const basegfx::B3DPoint B3dTransformationSet::WorldToEyeCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetOrientation(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::EyeToWorldCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvOrientation(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::EyeToViewCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetProjection(); + aVec *= GetScale(); + aVec += GetTranslate(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ViewToEyeCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec -= GetTranslate(); + aVec = aVec / GetScale(); + aVec *= GetInvProjection(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::WorldToViewCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetMatFromWorldToView(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ViewToWorldCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvMatFromWorldToView(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::DeviceToViewCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetScale(); + aVec += GetTranslate(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ViewToDeviceCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec -= GetTranslate(); + aVec = aVec / GetScale(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ObjectToWorldCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetObjectTrans(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::WorldToObjectCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ObjectToViewCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetObjectTrans(); + aVec *= GetMatFromWorldToView(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ViewToObjectCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvMatFromWorldToView(); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::ObjectToEyeCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetObjectTrans(); + aVec *= GetOrientation(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::EyeToObjectCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvOrientation(); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::DeviceToEyeCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvProjection(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::EyeToDeviceCoor(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetProjection(); + return aVec; +} + +const basegfx::B3DPoint B3dTransformationSet::InvTransObjectToEye(const basegfx::B3DPoint& rVec) +{ + basegfx::B3DPoint aVec(rVec); + aVec *= GetInvTransObjectToEye(); + return aVec; +} + +const basegfx::B2DPoint B3dTransformationSet::TransTextureCoor(const basegfx::B2DPoint& rVec) +{ + basegfx::B2DPoint aVec(rVec); + aVec *= GetTexture(); + return aVec; +} + +/************************************************************************* +|* +|* Konstruktor B3dViewport +|* +\************************************************************************/ + +B3dViewport::B3dViewport() +: B3dTransformationSet(), + aVRP(0, 0, 0), + aVPN(0, 0, 1), + aVUV(0, 1, 0) +{ + CalcOrientation(); +} + +B3dViewport::~B3dViewport() +{ +} + +void B3dViewport::SetVRP(const basegfx::B3DPoint& rNewVRP) +{ + aVRP = rNewVRP; + CalcOrientation(); +} + +void B3dViewport::SetVPN(const basegfx::B3DVector& rNewVPN) +{ + aVPN = rNewVPN; + CalcOrientation(); +} + +void B3dViewport::SetVUV(const basegfx::B3DVector& rNewVUV) +{ + aVUV = rNewVUV; + CalcOrientation(); +} + +void B3dViewport::SetViewportValues( + const basegfx::B3DPoint& rNewVRP, + const basegfx::B3DVector& rNewVPN, + const basegfx::B3DVector& rNewVUV) +{ + aVRP = rNewVRP; + aVPN = rNewVPN; + aVUV = rNewVUV; + CalcOrientation(); +} + +void B3dViewport::CalcOrientation() +{ + SetOrientation(aVRP, aVPN, aVUV); +} + +/************************************************************************* +|* +|* Konstruktor B3dViewport +|* +\************************************************************************/ + +B3dCamera::B3dCamera( + const basegfx::B3DPoint& rPos, const basegfx::B3DVector& rLkAt, + double fFocLen, double fBnkAng, sal_Bool bUseFocLen) +: B3dViewport(), + aPosition(rPos), + aCorrectedPosition(rPos), + aLookAt(rLkAt), + fFocalLength(fFocLen), + fBankAngle(fBnkAng), + bUseFocalLength(bUseFocLen) +{ + CalcNewViewportValues(); +} + +B3dCamera::~B3dCamera() +{ +} + +void B3dCamera::SetPosition(const basegfx::B3DPoint& rNewPos) +{ + if(rNewPos != aPosition) + { + // Zuweisen + aCorrectedPosition = aPosition = rNewPos; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetLookAt(const basegfx::B3DVector& rNewLookAt) +{ + if(rNewLookAt != aLookAt) + { + // Zuweisen + aLookAt = rNewLookAt; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetPositionAndLookAt(const basegfx::B3DPoint& rNewPos, const basegfx::B3DVector& rNewLookAt) +{ + if(rNewPos != aPosition || rNewLookAt != aLookAt) + { + // Zuweisen + aPosition = rNewPos; + aLookAt = rNewLookAt; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetFocalLength(double fLen) +{ + if(fLen != fFocalLength) + { + // Zuweisen + if(fLen < 5.0) + fLen = 5.0; + fFocalLength = fLen; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetBankAngle(double fAngle) +{ + if(fAngle != fBankAngle) + { + // Zuweisen + fBankAngle = fAngle; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetUseFocalLength(sal_Bool bNew) +{ + if(bNew != (sal_Bool)bUseFocalLength) + { + // Zuweisen + bUseFocalLength = bNew; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::DeviceRectangleChange() +{ + // call parent + B3dViewport::DeviceRectangleChange(); + + // Auf Aenderung reagieren + CalcNewViewportValues(); +} + +void B3dCamera::CalcNewViewportValues() +{ + basegfx::B3DVector aViewVector(aPosition - aLookAt); + basegfx::B3DVector aNewVPN(aViewVector); + + basegfx::B3DVector aNewVUV(0.0, 1.0, 0.0); + if(aNewVPN.getLength() < aNewVPN.getY()) + aNewVUV.setX(0.5); + + aNewVUV.normalize(); + aNewVPN.normalize(); + + basegfx::B3DVector aNewToTheRight = aNewVPN; + aNewToTheRight = aNewToTheRight.getPerpendicular(aNewVUV); + aNewToTheRight.normalize(); + aNewVUV = aNewToTheRight.getPerpendicular(aNewVPN); + aNewVUV.normalize(); + + SetViewportValues(aPosition, aNewVPN, aNewVUV); + if(CalcFocalLength()) + SetViewportValues(aCorrectedPosition, aNewVPN, aNewVUV); + + if(fBankAngle != 0.0) + { + basegfx::B3DHomMatrix aRotMat; + aRotMat.rotate(0.0, 0.0, fBankAngle); + basegfx::B3DVector aUp(0.0, 1.0, 0.0); + aUp *= aRotMat; + aUp = EyeToWorldCoor(aUp); + aUp.normalize(); + SetVUV(aUp); + } +} + +sal_Bool B3dCamera::CalcFocalLength() +{ + double fWidth = GetDeviceRectangleWidth(); + sal_Bool bRetval = sal_False; + + if(bUseFocalLength) + { + // Position aufgrund der FocalLength korrigieren + aCorrectedPosition = basegfx::B3DPoint(0.0, 0.0, fFocalLength * fWidth / 35.0); + aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition); + bRetval = sal_True; + } + else + { + // FocalLength anhand der Position anpassen + basegfx::B3DPoint aOldPosition; + aOldPosition = WorldToEyeCoor(aOldPosition); + if(fWidth != 0.0) + fFocalLength = aOldPosition.getZ() / fWidth * 35.0; + if(fFocalLength < 5.0) + fFocalLength = 5.0; + } + return bRetval; +} + +// eof diff --git a/tools/source/generic/makefile.mk b/tools/source/generic/makefile.mk index 6340e4daae08..6661d917051c 100644 --- a/tools/source/generic/makefile.mk +++ b/tools/source/generic/makefile.mk @@ -44,6 +44,7 @@ TARGET=gen EXCEPTIONSFILES = $(SLO)$/poly.obj $(OBJ)$/poly.obj SLOFILES= $(SLO)$/toolsin.obj \ + $(SLO)$/b3dtrans.obj \ $(SLO)$/link.obj \ $(SLO)$/bigint.obj \ $(SLO)$/fract.obj \ @@ -56,6 +57,7 @@ SLOFILES= $(SLO)$/toolsin.obj \ $(SLO)$/line.obj OBJFILES= $(OBJ)$/toolsin.obj \ + $(OBJ)$/b3dtrans.obj \ $(OBJ)$/link.obj \ $(OBJ)$/bigint.obj \ $(OBJ)$/fract.obj \ |