Hi,

so here is a little update on my current progress. I have a working solution, 
but im not 100% happy with it as it is pretty messy and offers bad performance.

The basic idea is to assign a uniform variable to each and every transform node 
of the scene graph, storing its total modelMatrix so it can be accessed by the 
shader.

1) After building the scene graph, traverse through all nodes. Once a transform 
node is found, create a uniform and attach it to it. Also add an entry into a 
global map variable, linking the created uniform with a list of transform nodes 
(all parents of the current node).
2) Then, with every frame, iterate through the uniform map and calculate the 
current model matrices based on the matrix transform list.

This works, but there are several drawbacks:

1) If the scene graph is modified in any way after buidling the map, it will 
yield wrong results. So with every change of the scene graph, the map needs to 
be rebuilt.
2) If multiple parents share the same transform node and it is not an identity 
matrix transform (with no effect), the approach wont work at all because there 
is no unique stateset for that transform.
3) Somewhat bad performance, lots of CPU load and bottlenecking.

If anyone has a better idea about how to obtain the model matrix of the 
PREVIOUS frame in the vertex shader, please let me know.


Code:
void MDRT::MotionDeskRT::updatePreviousFrameModelMatrices(
                const osg::Matrix &viewMatrix) {
        if (modelMatrixUniformMap.empty()) {
                buildModelMatrixUniformMap(sceneRoot,
                                std::vector<osg::MatrixTransform*>());
        }

        osg::Matrix modelMatrix;

        for (const auto & pair : modelMatrixUniformMap) {
                osg::Uniform *mmUniform = pair.first;
                const auto &mtList = pair.second;
                const size_t mtListLen = mtList.size();

                modelMatrix = mtList[0]->getMatrix();
                for (size_t i = 1; i < mtListLen; ++i) {
                        modelMatrix = mtList[i]->getMatrix() * modelMatrix;
                }
                //modelViewMatrix = modelViewMatrix * viewMatrix;

                mmUniform->set(modelMatrix);
        }
}

void MDRT::MotionDeskRT::buildModelMatrixUniformMap(osg::Node* root,
                const std::vector<osg::MatrixTransform*> &matrixTransforms) {

        //all of the below only works if no matrix transforms with a matrix != 
identity are shared.
        //otherwise, all use the same state set, which will make it impossible
        //to have a unique uniform storing the individual overall transform of 
a MT node.
        osg::Group *group = dynamic_cast<osg::Group*>(root);
        if (!group) {
                return; //is leaf and not MT
        }

        const unsigned int childCount = group->getNumChildren();
        osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(group);

        if (mt && mt->getMatrix() != osg::Matrix::identity()) {
                //is matrix transform, update modelview matrix
                auto modifiedMatrixTransforms = matrixTransforms;
                if (mt->getReferenceFrame()
                                != osg::Transform::ReferenceFrame::RELATIVE_RF) 
{
                        //this mt doesnt use relative reference frame, and 
therefore ignores all parent MTs when calculating the final model matrix.
                        modifiedMatrixTransforms.clear();
                }
                modifiedMatrixTransforms.push_back(mt);

                osg::Uniform *mmUniform = 
mt->getOrCreateStateSet()->getOrCreateUniform(
                                "oldModelMatrix", 
osg::Uniform::Type::FLOAT_MAT4, 1);

                modelMatrixUniformMap[mmUniform] = modifiedMatrixTransforms;

                for (unsigned int cid = 0; cid < childCount; ++cid) {
                        buildModelMatrixUniformMap(group->getChild(cid),
                                        modifiedMatrixTransforms);
                }

                return;
        }

        for (unsigned int cid = 0; cid < childCount; ++cid) {
                buildModelMatrixUniformMap(group->getChild(cid), 
matrixTransforms);
        }

}




Thank you!

Cheers,
Philipp

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=67747#67747





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to