(Sorry for the double post. I forgot to attach the patch in the last message.)
As many of you may know we have been running into problems with the
lack of double precision in OpenSG. After many months of putting it
off I have started looking into a solution that will have a minimal
affect on current code. I have come up with a first pass at a working
solution. The concept behind the attached patch is to make the
MatrixStore in OSGRenderPartition store matrix accumulations in double
precision. This is mainly because our scene graph is set up like the
following with our camera always located at the origin of the scene.
Root
|
Navigation (Very large) - Actually the inverse of the normal
'camera' position.
/ | \
LandTile ... LandTile (Very large)
As you can see the final position of the geometry is very close to the
camera. We only need the matrix accumulation from the geometry to be
in double precision. The attached patch contains the following high
level changes:
1) Add the ability to multiply two matrices with different value
types. (Matrix4f * Matrix4d)
2) Change RenderTraversalAction::pushMatrix() and
RenderPartition::pushMatrix() to have a template that allows
accumulating matrices of different value types.
3) Store accumulated matrices in MatrixStack as double precision.
4) Convert back to floating point when creating each RenderTreeNode
What do people think about these changes? Is there a better method to
double precision without changing a *lot* of code?
Thanks,
Aron
P.S. It is worth noting that these changes are for the
fcptr_stable_jun07 branch. If we can all come to a conclusion I can
merge the changes to trunk.
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.inl
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.inl (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.inl (working copy)
@@ -85,6 +85,13 @@
/*---------------------------- properties ---------------------------------*/
+template<class MatrixType> inline
+void RenderTraversalAction::pushMatrix(const MatrixType &matrix)
+{
+ _pActivePartition->pushMatrix(matrix);
+}
+
+
inline
void RenderTraversalAction::setKeyGen(UInt32 uiKeyGen)
{
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.cpp (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.cpp (working copy)
@@ -708,11 +708,6 @@
_pActivePartition->releaseLightIndex();
}
-void RenderTraversalAction::pushMatrix(const Matrix &matrix)
-{
- _pActivePartition->pushMatrix(matrix);
-}
-
void RenderTraversalAction::popMatrix(void)
{
_pActivePartition->popMatrix();
Index: System/Action/RenderTraversal/OSGRenderPartition.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.cpp (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.cpp (working copy)
@@ -555,14 +555,32 @@
Pnt3f objPos;
actNode->getVolume().getCenter(objPos);
-
+
+#ifndef DOUBLE_MATRIX_STORE
_currMatrix.second.mult(objPos);
+#else
+ Pnt3d temp(objPos[0], objPos[1], objPos[2]);
+ _currMatrix.second.mult(temp);
+#endif
pNewElem->setNode (&*actNode);
pNewElem->setFunctor ( func );
+
+#ifndef DOUBLE_MATRIX_STORE
pNewElem->setMatrixStore(_currMatrix);
+ pNewElem->setScalar ( objPos[2] );
+#else
+ // Now that we have accumulated all transformations we can convert back
+ // to a floating point matrix.
+ Matrix4f tempMat;
+ tempMat.convertFrom(_currMatrix.second);
+ std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+
+ pNewElem->setMatrixStore(temp_ms);
+ pNewElem->setScalar ( temp[2] );
+#endif
+
pNewElem->setState ( pState );
- pNewElem->setScalar ( objPos[2] );
if(_sStateOverrides.top()->empty() == false)
{
@@ -600,8 +618,12 @@
}
RenderTreeNode *pNewElem = _pNodePool->create();
-
+
+#ifndef DOUBLE_MATRIX_STORE
Pnt3f objPos;
+#else
+ Pnt3d objPos;
+#endif
//_oDrawEnv.getRTAction()->getActNode()->getVolume().getCenter(objPos);
@@ -615,7 +637,11 @@
objVol.getBounds(min,max);
+#ifndef DOUBLE_MATRIX_STORE
Pnt3r p[8];
+#else
+ Pnt3d p[8];
+#endif
p[0].setValues(min[0],min[1],min[2]);
p[1].setValues(max[0],min[1],min[2]);
p[2].setValues(min[0],max[1],min[2]);
@@ -646,7 +672,18 @@
pNewElem->setNode (&*actNode );
pNewElem->setFunctor ( func );
+
+#ifndef DOUBLE_MATRIX_STORE
pNewElem->setMatrixStore(_currMatrix );
+#else
+ // Now that we have accumulated all transformations we can convert back
+ // to a floating point matrix.
+ Matrix4f tempMat;
+ tempMat.convertFrom(_currMatrix.second);
+ std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+ pNewElem->setMatrixStore(temp_ms );
+#endif
+
pNewElem->setState ( pState );
// Normalize scalar to 0..1 for bucket sorting
@@ -692,7 +729,17 @@
pNewElem->setNode (&* actNode );
pNewElem->setFunctor ( func );
+
+#ifndef DOUBLE_MATRIX_STORE
pNewElem->setMatrixStore( _currMatrix);
+#else
+ // Now that we have accumulated all transformations we can convert back
+ // to a floating point matrix.
+ Matrix4f tempMat;
+ tempMat.convertFrom(_currMatrix.second);
+ std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+ pNewElem->setMatrixStore( temp_ms);
+#endif
if(_sStateOverrides.top()->empty() == false)
{
@@ -989,16 +1036,6 @@
_accMatrix.mult(_currMatrix.second);
}
-void RenderPartition::pushMatrix(const Matrix &matrix)
-{
- _vMatrixStack.push_back(_currMatrix);
-
- _currMatrix.first = ++_uiMatrixId;
- _currMatrix.second.mult(matrix);
-
- updateTopMatrix();
-}
-
void RenderPartition::popMatrix(void )
{
_currMatrix.first = _vMatrixStack.back().first;
Index: System/Action/RenderTraversal/OSGRenderPartition.inl
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.inl (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.inl (working copy)
@@ -226,11 +226,28 @@
{
_oDrawEnv.setupViewing(matrix);
- _currMatrix.second = matrix;
+#ifndef DOUBLE_MATRIX_STORE
+ _currMatrix.second = matrix
+#else
+ Matrix4d temp;
+ temp.convertFrom(matrix);
+ _currMatrix.second = temp;
+#endif
updateTopMatrix();
}
+template<class MatrixType> inline
+void RenderPartition::pushMatrix(const MatrixType &matrix)
+{
+ _vMatrixStack.push_back(_currMatrix);
+
+ _currMatrix.first = ++_uiMatrixId;
+ _currMatrix.second.mult(matrix);
+
+ updateTopMatrix();
+}
+
inline
const Matrix4f &RenderPartition::getViewing(void)
{
Index: System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp (working copy)
@@ -60,6 +60,7 @@
#include "OSGDistanceLOD.h"
#include "OSGMaterialGroup.h"
#include "OSGSwitch.h"
+#include "OSGDoubleTransform.h"
#include "OSGTransform.h"
#include "OSGDirectionalLight.h"
#include "OSGPointLight.h"
@@ -337,6 +338,42 @@
return ActionBase::Continue;
}
+ActionBase::ResultE DoubleTransformRenderEnter(const NodeCorePtr &pCore,
+ Action *action)
+{
+#ifdef OSG_DUMP_TRAVERSAL
+ FDEBUG_GV(("Enter DoubleTransform %p\n", &(*pCore)));
+#endif
+
+ DoubleTransformPtr pThis = cast_dynamic<DoubleTransformPtr>(pCore);
+
+ RenderTraversalAction *pAction =
+ dynamic_cast<RenderTraversalAction *>(action);
+
+ pAction->pushVisibility();
+
+ pAction->pushMatrix(pThis->getMatrix());
+
+ return ActionBase::Continue;
+}
+
+ActionBase::ResultE DoubleTransformRenderLeave(const NodeCorePtr &pCore,
+ Action *action)
+{
+#ifdef OSG_DUMP_TRAVERSAL
+ FDEBUG_GV(("Leave DoubleTransform %p\n", &(*pCore)));
+#endif
+
+ RenderTraversalAction *pAction =
+ dynamic_cast<RenderTraversalAction *>(action);
+
+ pAction->popVisibility();
+
+ pAction->popMatrix();
+
+ return ActionBase::Continue;
+}
+
ActionBase::ResultE MaterialGroupRenderEnter(const NodeCorePtr &pCore,
Action *action)
{
@@ -1154,6 +1191,15 @@
Transform::getClassType(),
TransformRenderLeave);
+ RenderTraversalAction::registerEnterDefault(
+ DoubleTransform::getClassType(),
+ DoubleTransformRenderEnter);
+
+ RenderTraversalAction::registerLeaveDefault(
+ DoubleTransform::getClassType(),
+ DoubleTransformRenderLeave);
+
+
RenderTraversalAction::registerEnterDefault(
DirectionalLight::getClassType(),
DirectionalLightRenderEnter);
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.h
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.h (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.h (working copy)
@@ -163,7 +163,8 @@
/*--------------------------- matrix ------------------------------------*/
- void pushMatrix (const Matrix &matrix);
+ template<class MatrixType>
+ void pushMatrix (const MatrixType &matrix);
void popMatrix ( void );
const Matrix &topMatrix ( void );
Index: System/Action/RenderTraversal/OSGRenderPartition.h
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.h (revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.h (working copy)
@@ -61,6 +61,9 @@
#include <stack>
+
+#define DOUBLE_MATRIX_STORE
+
OSG_BEGIN_NAMESPACE
//---------------------------------------------------------------------------
@@ -150,6 +153,9 @@
to compare actual matrix elements.
*/
typedef std::pair<UInt32, Matrix> MatrixStore;
+#ifdef DOUBLE_MATRIX_STORE
+ typedef std::pair<UInt32, Matrix4d> DoubleMatrixStore;
+#endif
/*! DrawFunctor is the signature for the methods that are called
from within the draw tree
@@ -182,7 +188,11 @@
typedef std::stack<StateOverride *> OverrideStack;
/*! MatrixStack keeps track of matrices during traversal */
+#ifdef DOUBLE_MATRIX_STORE
+ typedef std::vector<DoubleMatrixStore> MatrixStack;
+#else
typedef std::vector<MatrixStore> MatrixStack;
+#endif
typedef std::vector<RenderPartition *> GroupStore;
@@ -291,8 +301,9 @@
void execute(void);
/*------------------------- assignment ----------------------------------*/
-
- void pushMatrix(const Matrix &matrix);
+
+ template<class MatrixType>
+ void pushMatrix(const MatrixType &matrix);
void popMatrix ( void );
const Matrix &topMatrix ( void );
@@ -405,7 +416,11 @@
UInt32 _uiMatrixId;
+#ifdef DOUBLE_MATRIX_STORE
+ DoubleMatrixStore _currMatrix;
+#else
MatrixStore _currMatrix;
+#endif
Matrix _accMatrix;
MatrixStack _vMatrixStack;
Index: Base/Base/OSGMatrix.inl
===================================================================
--- Base/Base/OSGMatrix.inl (revision 1247)
+++ Base/Base/OSGMatrix.inl (working copy)
@@ -433,10 +433,11 @@
/*-------------------------------------------------------------------------*/
/* Helper */
-template<class ValueTypeT> inline
-ValueTypeT TransformationMatrix<ValueTypeT>::rowMulCol4(
- const TransformationMatrix &gRowMat, UInt32 iRow,
- const TransformationMatrix &gColMat, UInt32 iColumn) const
+template<class ValueTypeT>
+template<class ValueTypeR, class ValueTypeS> inline
+ ValueTypeT TransformationMatrix<ValueTypeT>::rowMulCol4(
+ const TransformationMatrix<ValueTypeR> &gRowMat, UInt32 iRow,
+ const TransformationMatrix<ValueTypeS> &gColMat, UInt32 iColumn) const
{
return
gRowMat[0][iRow] * gColMat[iColumn][0] +
@@ -1997,8 +1998,9 @@
return true;
}
-template<class ValueTypeT> inline
-void TransformationMatrix<ValueTypeT>::mult(const TransformationMatrix &matrix)
+template<class ValueTypeT>
+template<class ValueTypeR> inline
+void TransformationMatrix<ValueTypeT>::mult(const TransformationMatrix<ValueTypeR> &matrix)
{
ValueTypeT rTmpMat[4][4];
@@ -2043,9 +2045,10 @@
_matrix[3][3] = rTmpMat[3][3];
}
-template<class ValueTypeT> inline
+template<class ValueTypeT>
+template<class ValueTypeR> inline
void TransformationMatrix<ValueTypeT>::multLeft(
- const TransformationMatrix &matrix)
+ const TransformationMatrix<ValueTypeR> &matrix)
{
ValueTypeT rTmpMat[4][4];
Index: Base/Base/OSGMatrix.h
===================================================================
--- Base/Base/OSGMatrix.h (revision 1247)
+++ Base/Base/OSGMatrix.h (working copy)
@@ -354,8 +354,10 @@
bool transpose ( void );
bool transposeFrom(const TransformationMatrix &matrix);
- void mult (const TransformationMatrix &matrix);
- void multLeft (const TransformationMatrix &matrix);
+ template<class ValueTypeR>
+ void mult (const TransformationMatrix<ValueTypeR>& mat);
+ template<class ValueTypeR>
+ void multLeft (const TransformationMatrix<ValueTypeR>& mat);
void add (const TransformationMatrix &matrix);
void scale ( ValueTypeT s );
@@ -416,10 +418,11 @@
/*! \name Internal Math */
/*! \{ */
- ValueTypeT rowMulCol4(const TransformationMatrix &gRowMat,
- UInt32 iRow,
- const TransformationMatrix &gColMat,
- UInt32 iColumn) const;
+ template<class ValueTypeR, class ValueTypeS>
+ ValueTypeT rowMulCol4(const TransformationMatrix<ValueTypeR> &gRowMat,
+ UInt32 iRow,
+ const TransformationMatrix<ValueTypeS> &gColMat,
+ UInt32 iColumn) const;
ValueTypeT det2_calc (const ValueTypeT a1,
const ValueTypeT a2,
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core