Hi Robert,

I've attached a small example, where I try to set the view matrix in a way, the camera always faces a certain direction. Unfortunately it seems, the view matrix I supply is applied one frame too late.

(The camera should always face the geometry, so there should be a cross made of blue and a green line)

Is there something wrong with the way I supply the view matrix?

Cheers
Sebastian
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Array>
#include <osgGA/CameraManipulator>
#include <osgGA/TrackballManipulator>
#include <osg/Drawable>
#include <osg/LineWidth>



class SetCameraManipulator : public osgGA::CameraManipulator
{
public:
        SetCameraManipulator() 
                : osgGA::CameraManipulator()
        {
        }

        void setByMatrix( const osg::Matrixd& matrix )                  
        {
                mMatrix  = matrix;
        }

        void setByInverseMatrix( const osg::Matrixd& matrix )   
        { 
                setByMatrix( osg::Matrixd::inverse(matrix) );
        }

        osg::Matrixd getMatrix() const                  
        { 
                return mMatrix;
        }

        osg::Matrixd getInverseMatrix() const
        { 
                return osg::Matrixd::inverse(mMatrix);
        } 

        bool handle( const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& 
aa )
        {
                return false;
        }

        void computePosition( const osg::Vec3& eye,const osg::Vec3& 
center,const osg::Vec3& up )
        {
                //empty
        }

private:
        osg::Matrixd mMatrix;
};


osg::Vec3 findPerpendicular(const osg::Vec3& v)
{
        osg::Vec3 p1(v.z(), v.z(), -v.x()-v.y());
        osg::Vec3 p2(-v.y()-v.z(), v.x(), v.x());
        if (osg::equivalent(p2.length(), 0))
        {
                p1.normalize();
                return p1;
        }
        p2.normalize();
        return p2;
}




osg::ref_ptr<osg::Geode> createCross()
{
        osg::ref_ptr<osg::Geode> normal_vis = new osg::Geode;
        osg::Vec3Array* vec3_array = new osg::Vec3Array(6);
        (*vec3_array)[0] = osg::Vec3(0,0,0);
        (*vec3_array)[1] = osg::Vec3(0,0,1);
        (*vec3_array)[2] = osg::Vec3(0,-1,1);
        (*vec3_array)[3] = osg::Vec3(0,1,1);
        (*vec3_array)[4] = osg::Vec3(-1,0,1);
        (*vec3_array)[5] = osg::Vec3(1,0,1);
        osg::Vec4Array* col_array = new osg::Vec4Array(6);
        (*col_array)[0] = osg::Vec4(1,0,0,1);
        (*col_array)[1] = osg::Vec4(1,0,0,1);
        (*col_array)[2] = osg::Vec4(0,1,0,1);
        (*col_array)[3] = osg::Vec4(0,1,0,1);
        (*col_array)[4] = osg::Vec4(0,0,1,1);
        (*col_array)[5] = osg::Vec4(0,0,1,1);
        osg::Geometry* mesh_geometry = new osg::Geometry;
        normal_vis->addDrawable(mesh_geometry);
        mesh_geometry->addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 6));
        mesh_geometry->setVertexArray(vec3_array);
        mesh_geometry->setColorArray(col_array, osg::Array::BIND_PER_VERTEX);
        mesh_geometry->setUseVertexBufferObjects(true); 
        normal_vis->getOrCreateStateSet()->setAttributeAndModes(new 
osg::LineWidth(5));
        normal_vis->getOrCreateStateSet()->setMode(GL_LIGHTING, 
osg::StateAttribute::OFF);
        return normal_vis;
}
/// retrieve a random vector in the unit cube. 
osg::Vec3 randomVec()
{
        return osg::Vec3(static_cast<float>(rand()) / RAND_MAX, 
static_cast<float>(rand()) / RAND_MAX, static_cast<float>(rand()) /RAND_MAX);
}

int main(int argc, char** argv)
{
        osgViewer::Viewer viewer;
        
        viewer.setUpViewInWindow(110,110,256,256,0);
        
        osg::Group* root = new osg::Group;
        viewer.setSceneData(root);

        osg::ref_ptr<osg::Geode> normal_vis = createCross();
        root->addChild(normal_vis);
        ///set out matrix-camera manipulator
        SetCameraManipulator* scm = new SetCameraManipulator;
        viewer.setCameraManipulator(scm);
        //viewer.setCameraManipulator(new osgGA::TrackballManipulator);
        viewer.getCamera()->setProjectionMatrixAsPerspective(45.0,1,0.01, 
1000.0);


        std::vector<osg::Vec3> random_points;
        std::vector<osg::Vec3> random_normals;
        
        for (unsigned int i = 0; i < 100; ++i)
        {
                random_points.push_back(randomVec());
                osg::Vec3d normal = randomVec();
                normal.normalize();
                random_normals.push_back(normal);
        }

        osg::Matrix mat;

        viewer.realize();
        while (!viewer.done())
        {
        
                for(unsigned int i = 0; i < random_points.size(); ++i)
                {
                        osg::Vec3d normal = random_normals[i];
                        osg::Vec3d pos    = random_points[i];
                                
                                
                        osg::Vec3 perp = findPerpendicular(normal);

                        //set the camera manipulator to look at the pos with 
the given direction
                        mat.makeLookAt(pos + normal * 2, pos, perp);
                        scm->setByInverseMatrix(mat);
                        //viewer.getCamera()->setViewMatrixAsLookAt(pos, pos + 
normal, perp);
                                
                        //update the normal;
                        osg::Vec3Array* vec3_array = 
dynamic_cast<osg::Vec3Array*>(normal_vis->getDrawable(0)->asGeometry()->getVertexArray());
                        (*vec3_array)[0] = pos;
                        (*vec3_array)[1] = pos + normal;

                        (*vec3_array)[2] = pos  + perp;
                        (*vec3_array)[3] = pos  - perp;
                                
                        osg::Vec3 cross = (perp ^ normal);
                        (*vec3_array)[4] = pos + cross;
                        (*vec3_array)[5] = pos - cross;
                                
                        vec3_array->dirty();
                        normal_vis->dirtyBound();
                        
                                
                        //if we do this, we get the correct view every like 2 
frames
                        //with only one frame call, we seem to lag behind. I.e. 
the view matrix is applied the frame after the current-
                        viewer.frame();
                        viewer.frame();
                        
                }
                
        }
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to