| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 |