summaryrefslogtreecommitdiff
path: root/basegfx/source/matrix/b3dhommatrix.cxx
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2006-11-14 13:06:55 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2006-11-14 13:06:55 +0000
commit454bb4b57884b6cc216dfa64c3240e04459aa341 (patch)
treea846ff2fbefc23fac9817e4e6a26c3a38b1d4386 /basegfx/source/matrix/b3dhommatrix.cxx
parent8216aa020555748d67e5cf54d9acb40db5a0de73 (diff)
INTEGRATION: CWS aw024 (1.7.6); FILE MERGED
2006/10/27 12:09:09 aw 1.7.6.7: #i70938# added frustum, ortho and orientation methods 2006/09/21 20:59:05 aw 1.7.6.6: RESYNC: (1.10-1.11); FILE MERGED 2006/08/03 16:01:50 aw 1.7.6.5: RESYNC: (1.9-1.10); FILE MERGED 2006/07/11 09:37:39 iha 1.7.6.4: #i39528# correct matrix decompose for rotation 2005/09/19 21:45:48 aw 1.7.6.3: RESYNC: (1.7-1.8); FILE MERGED 2005/05/12 16:35:13 aw 1.7.6.2: #i39529# 2005/04/26 14:48:48 aw 1.7.6.1: #i39528#
Diffstat (limited to 'basegfx/source/matrix/b3dhommatrix.cxx')
-rw-r--r--basegfx/source/matrix/b3dhommatrix.cxx168
1 files changed, 153 insertions, 15 deletions
diff --git a/basegfx/source/matrix/b3dhommatrix.cxx b/basegfx/source/matrix/b3dhommatrix.cxx
index 4a17e1986025..ecb319752d87 100644
--- a/basegfx/source/matrix/b3dhommatrix.cxx
+++ b/basegfx/source/matrix/b3dhommatrix.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: b3dhommatrix.cxx,v $
*
- * $Revision: 1.11 $
+ * $Revision: 1.12 $
*
- * last change: $Author: obo $ $Date: 2006-09-17 07:59:09 $
+ * last change: $Author: ihi $ $Date: 2006-11-14 14:06:55 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -339,6 +339,119 @@ namespace basegfx
}
}
+ void B3DHomMatrix::frustum(double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
+ {
+ const double fZero(0.0);
+ const double fOne(1.0);
+
+ if(!fTools::more(fNear, fZero))
+ {
+ fNear = 0.001;
+ }
+
+ if(!fTools::more(fFar, fZero))
+ {
+ fFar = fOne;
+ }
+
+ if(fTools::equal(fNear, fFar))
+ {
+ fFar = fNear + fOne;
+ }
+
+ if(fTools::equal(fLeft, fRight))
+ {
+ fLeft -= fOne;
+ fRight += fOne;
+ }
+
+ if(fTools::equal(fTop, fBottom))
+ {
+ fBottom -= fOne;
+ fTop += fOne;
+ }
+
+ Impl3DHomMatrix aFrustumMat;
+
+ aFrustumMat.set(0, 0, 2.0 * fNear / (fRight - fLeft));
+ aFrustumMat.set(1, 1, 2.0 * fNear / (fTop - fBottom));
+ aFrustumMat.set(0, 2, (fRight + fLeft) / (fRight - fLeft));
+ aFrustumMat.set(1, 2, (fTop + fBottom) / (fTop - fBottom));
+ aFrustumMat.set(2, 2, -fOne * ((fFar + fNear) / (fFar - fNear)));
+ aFrustumMat.set(3, 2, -fOne);
+ aFrustumMat.set(2, 3, -fOne * ((2.0 * fFar * fNear) / (fFar - fNear)));
+ aFrustumMat.set(3, 3, fZero);
+
+ mpImpl->doMulMatrix(aFrustumMat);
+ }
+
+ void B3DHomMatrix::ortho(double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
+ {
+ if(fTools::equal(fNear, fFar))
+ {
+ fFar = fNear + 1.0;
+ }
+
+ if(fTools::equal(fLeft, fRight))
+ {
+ fLeft -= 1.0;
+ fRight += 1.0;
+ }
+
+ if(fTools::equal(fTop, fBottom))
+ {
+ fBottom -= 1.0;
+ fTop += 1.0;
+ }
+
+ Impl3DHomMatrix aOrthoMat;
+
+ aOrthoMat.set(0, 0, 2.0 / (fRight - fLeft));
+ aOrthoMat.set(1, 1, 2.0 / (fTop - fBottom));
+ aOrthoMat.set(2, 2, -1.0 * (2.0 / (fFar - fNear)));
+ aOrthoMat.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft)));
+ aOrthoMat.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom)));
+ aOrthoMat.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear)));
+
+ mpImpl->doMulMatrix(aOrthoMat);
+ }
+
+ void B3DHomMatrix::orientation(B3DPoint aVRP, B3DVector aVPN, B3DVector aVUV)
+ {
+ Impl3DHomMatrix aOrientationMat;
+
+ // translate -VRP
+ aOrientationMat.set(0, 3, -aVRP.getX());
+ aOrientationMat.set(1, 3, -aVRP.getY());
+ aOrientationMat.set(2, 3, -aVRP.getZ());
+
+ // build rotation
+ aVUV.normalize();
+ aVPN.normalize();
+
+ // build x-axis as peroendicular fron aVUV and aVPN
+ B3DVector aRx(aVUV.getPerpendicular(aVPN));
+ aRx.normalize();
+
+ // y-axis perpendicular to that
+ B3DVector aRy(aVPN.getPerpendicular(aRx));
+ aRy.normalize();
+
+ // the calculated normals are the line vectors of the rotation matrix,
+ // set them to create rotation
+ aOrientationMat.set(0, 0, aRx.getX());
+ aOrientationMat.set(0, 1, aRx.getY());
+ aOrientationMat.set(0, 2, aRx.getZ());
+ aOrientationMat.set(1, 0, aRy.getX());
+ aOrientationMat.set(1, 1, aRy.getY());
+ aOrientationMat.set(1, 2, aRy.getZ());
+ aOrientationMat.set(2, 0, aVPN.getX());
+ aOrientationMat.set(2, 1, aVPN.getY());
+ aOrientationMat.set(2, 2, aVPN.getZ());
+
+ mpImpl->doMulMatrix(aOrientationMat);
+ }
+
bool B3DHomMatrix::decompose(B3DTuple& rScale, B3DTuple& rTranslate, B3DTuple& rRotate, B3DTuple& rShear) const
{
// when perspective is used, decompose is not made here
@@ -457,21 +570,46 @@ namespace basegfx
rScale.correctValues(1.0);
// Get rotations
- rRotate.setY(asin(-aCol0.getZ()));
-
- if(::basegfx::fTools::equalZero(cos(rRotate.getY())))
{
- rRotate.setX(atan2(aCol1.getX(), aCol1.getY()));
- rRotate.setZ(0.0);
- }
- else
- {
- rRotate.setX(atan2(aCol1.getZ(), aCol2.getZ()));
- rRotate.setZ(atan2(aCol0.getY(), aCol0.getX()));
- }
+ double fy=0;
+ double cy=0;
- // corrcet rotate values
- rRotate.correctValues();
+ if( ::basegfx::fTools::equal( aCol0.getZ(), 1.0 )
+ || aCol0.getZ() > 1.0 )
+ {
+ fy = -F_PI/2.0;
+ cy = 0.0;
+ }
+ else if( ::basegfx::fTools::equal( aCol0.getZ(), -1.0 )
+ || aCol0.getZ() < -1.0 )
+ {
+ fy = F_PI/2.0;
+ cy = 0.0;
+ }
+ else
+ {
+ fy = asin( -aCol0.getZ() );
+ cy = cos(fy);
+ }
+
+ rRotate.setY(fy);
+ if( ::basegfx::fTools::equalZero( cy ) )
+ {
+ if( aCol0.getZ() > 0.0 )
+ rRotate.setX(atan2(-1.0*aCol1.getX(), aCol1.getY()));
+ else
+ rRotate.setX(atan2(aCol1.getX(), aCol1.getY()));
+ rRotate.setZ(0.0);
+ }
+ else
+ {
+ rRotate.setX(atan2(aCol1.getZ(), aCol2.getZ()));
+ rRotate.setZ(atan2(aCol0.getY(), aCol0.getX()));
+ }
+
+ // corrcet rotate values
+ rRotate.correctValues();
+ }
return true;
}