Hi everyone,
I have a situation which I don't understand: I am trying to control the
projection's fovx and fovy myself. But I see a difference in behaviour
when I change fovx and fovy when applying them to
camera->setProjectionMatrixAsPerspective(). Could someone try the
attached example with animated fovx and fovy, look at the effect, and
give me a solution?
Thanks a lot!
Regards
Raymond
#include <iostream>
#include <osg/Material>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osgViewer/Viewer>
// I use single threaded in my main app so force here
#define USE_SINGLE_THREADED_MODEL
osg::ref_ptr<osg::Group> CreateScene(void);
class CameraUpdateCallback : public osg::NodeCallback {
bool _animateFovx;
public:
CameraUpdateCallback(void) : _animateFovx(true) {
}
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) {
osg::Camera *camera = dynamic_cast<osg::Camera *>(node);
if(camera) {
double currFovy, currAspectRatio, currZNear, currZFar;
camera->getProjectionMatrixAsPerspective(currFovy, currAspectRatio,
currZNear, currZFar);
double currFovx = currAspectRatio * currFovy;
double newFovx;
double newFovy;
if(_animateFovx) {
newFovx = currFovx + 0.5;
// use range 30.0 - 100.0
if(newFovx > 100.0) {
newFovx = 30.0;
_animateFovx = false;
}
newFovy = currFovy;
}
else { // animate fovy
newFovx = currFovx;
newFovy = currFovy + 0.5;
if(newFovy > 100.0) {
newFovy = 30.0;
_animateFovx = true;
}
}
double newAspectRatio = newFovx / newFovy;
camera->setProjectionMatrixAsPerspective(newFovy, newAspectRatio,
currZNear, currZFar);
}
traverse(node, nv);
}
};
int main(int argc, char **argv) {
osg::ref_ptr<osg::Group> scene = CreateScene();
osgViewer::Viewer viewer;
#ifdef USE_SINGLE_THREADED_MODEL
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
#endif
viewer.getCamera()->setUpdateCallback(new CameraUpdateCallback());
viewer.setSceneData(scene.get());
return viewer.run();
}
osg::ref_ptr<osg::MatrixTransform> CreateSphere(const osg::Vec3 &translation) {
osg::ref_ptr<osg::MatrixTransform> transform;
osg::Matrix *matrix;
osg::ref_ptr<osg::Geode> geode;
const float radius = 0.8f;
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
hints->setDetailRatio(2.0f);
osg::ref_ptr<osg::ShapeDrawable> shape;
transform = new osg::MatrixTransform;
matrix = new osg::Matrix;
matrix->makeIdentity();
matrix->setTrans(osg::Vec3f(translation));
transform->setMatrix(*matrix);
geode = new osg::Geode;
transform->addChild(geode.get());
shape = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f),
radius * 2), hints.get());
geode->addDrawable(shape.get());
shape->setColor(osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
return transform.get();
}
osg::ref_ptr<osg::Group> CreateScene(void) {
osg::ref_ptr<osg::Group> scene = new osg::Group;
scene = new osg::Group;
// upper left sphere
scene->addChild(CreateSphere(osg::Vec3(-10.0, 10.0, 10.0)).get());
// upper right sphere
scene->addChild(CreateSphere(osg::Vec3( 10.0, 10.0, 10.0)).get());
// lower left sphere
scene->addChild(CreateSphere(osg::Vec3(-10.0, 10.0, -10.0)).get());
// lower right sphere
scene->addChild(CreateSphere(osg::Vec3( 10.0, 10.0, -10.0)).get());
// material
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setColorMode(osg::Material::DIFFUSE);
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
material->setShininess(osg::Material::FRONT_AND_BACK, 64.0f);
scene->getOrCreateStateSet()->setAttributeAndModes(material.get(),
osg::StateAttribute::ON);
return scene.get();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org