Thank you Carsten!
I tried to specify the eye point in local coordinates, in global, or
in random positions, but the result is never the correct one...
I made an update to my little test program, now you can also use and
move the eye point.
You can see what I mean if you:
- start the test program,
- press '1' to set the camera in the origin and the terrain in
(-15,15-30) in order to be seen by the camera
- press '3' to start using the eye point for the terrain
- play with 'j,l,i,k,u,o' to move the eye point and see how the
terrain rendering changes.
The weirdest thing (to me) is that the terrain starts to show all its
patches when the sum of the absolute x,y,z of the eye point exceed
2000~2100...
Best regards,
Christian Bar
Below the code:
"
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSolidBackground.h>
#include <OSGDirectionalLight.h>
#include <OSGPerspectiveCamera.h>
#include <OSGTransform.h>
#include <OSGRenderAction.h>
#include <OSGViewport.h>
#include <OSGGradientBackground.h>
#include <OSGTextureBackground.h>
#include <OSGTextureObjChunk.h>
#include <OSGImage.h>
#include <OSGImageForeground.h>
#include <OSGFileGrabForeground.h>
#include "OSGQuadTreeTerrain.h"
#include "OSGImageFileHandler.h"
#include "OSGChunkMaterial.h"
#include "OSGMaterialChunk.h"
#include "OSGTextureObjChunk.h"
#include "OSGTextureEnvChunk.h"
#define ROT 0.1f;
#define TRASL 1.f;
bool updateCameraPos=false;
bool eye=false;
float tx=-15.f;
float ty=15.f;
float tz=-30.f;
float rx=3.1415f/2.f;
float ry=0.f;
float rz=0.f;
float tex=0.f,tey=0.f,tez=0.f;
OSG::TransformRecPtr terrainTransCore;
OSG::NodeRecPtr scene;
OSG::QuadTreeTerrainUnrecPtr terrain;
OSG::PerspectiveCameraRecPtr camera;
OSG::TransformRecPtr camTrans;
OSG::ViewportRecPtr viewport;
OSG::WindowRecPtr window;
OSG::NodeRecPtr camBeacon, lightBeacon, lightNode;
OSG::RenderActionRefPtr renderAction;
int setupGLUT(int *argc, char *argv[]);
OSG::MaterialTransitPtr makeTexture (const char* texname)
{
OSG::ImageUnrecPtr image = OSG::ImageFileHandler::the()->read(texname);
SLOG << "Create ChunkMaterial" << std::endl;
OSG::ChunkMaterialUnrecPtr texMatPtr = OSG::ChunkMaterial
::create();
OSG::TextureObjChunkUnrecPtr texChunkPtr =
OSG::TextureObjChunk::create();
OSG::TextureEnvChunkUnrecPtr texEnvChunkPtr =
OSG::TextureEnvChunk::create();
OSG::MaterialChunkUnrecPtr phongChunk = OSG::MaterialChunk
::create();
phongChunk->setDiffuse (OSG::Color4f(1.0f, 1.0f, 1.0f, 1.0f));
phongChunk->setAmbient (OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
phongChunk->setSpecular(OSG::Color4f(0.2f, 0.2f, 0.2f, 1.0f));
phongChunk->setShininess(6);
texChunkPtr->setImage ( image);
texChunkPtr->setWrapS ( GL_CLAMP );
texChunkPtr->setWrapT ( GL_CLAMP );
texChunkPtr->setWrapR ( GL_CLAMP );
texChunkPtr->setMinFilter ( GL_LINEAR );
texChunkPtr->setMagFilter ( GL_LINEAR );
texEnvChunkPtr->setEnvMode(GL_MODULATE);
texMatPtr->addChunk(texChunkPtr, 0);
texMatPtr->addChunk(texEnvChunkPtr, 0);
texMatPtr->addChunk(phongChunk);
return OSG::MaterialTransitPtr(texMatPtr);
}
OSG::NodeTransitPtr createScenegraph(void)
{
OSG::NodeRecPtr torus = OSG::makeTorus(1,5,8,16);
// create the terrain
OSG::ImageUnrecPtr height;
OSG::MaterialUnrecPtr mat;
mat = makeTexture("Default_TexMap.png");
height = OSG::ImageFileHandler::the()->read("Default_HeightMap.png");
terrain = OSG::QuadTreeTerrain::create();
terrain->setHeightData(height);
terrain->setMaterial(mat);
terrain->setVertexSpacing(30.0f/256.0f);
terrain->setHeightScale (5.0f);
terrain->setGeoMorphing(true);
terrain->setDetail (25.0f);
OSG::NodeRecPtr scenet = OSG::Node::create();
scenet->setCore(terrain);
terrainTransCore = OSG::Transform::create();
OSG::NodeRecPtr terrTrans = OSG::makeNodeFor(terrainTransCore);
torus->addChild(terrTrans);
OSG::Matrix terrainMat;
terrainMat.setTransform(OSG::Vec3f( 0, 0, 0),
OSG::Quaternion(OSG::Vec3f(0,1,0),0));
terrainTransCore->setMatrix(terrainMat);
terrTrans->addChild(scenet);
//create transformations & beacons for cameras & light
camBeacon = OSG::Node::create();
lightBeacon = OSG::Node::create();
OSG::TransformRecPtr lightTrans;
camTrans = OSG::Transform::create();
lightTrans = OSG::Transform::create();
OSG::Matrix camMat, lightM;
camMat.setIdentity();
lightM.setIdentity();
camTrans->setMatrix(camMat);
lightTrans->setMatrix(lightM);
camBeacon->setCore(camTrans);
lightBeacon->setCore(lightTrans );
//create the light source
OSG::DirectionalLightRecPtr dLight = OSG::DirectionalLight::create();
dLight->setDirection(OSG::Vec3f(0,1,2));
dLight->setDiffuse(OSG::Color4f(1,1,1,1));
dLight->setAmbient(OSG::Color4f(0.2f,0.2f,0.2f,1.f));
dLight->setSpecular(OSG::Color4f(1,1,1,1));
dLight->setBeacon(lightBeacon);
lightNode = OSG::Node::create();
lightNode->setCore(dLight);
lightNode->addChild(torus);
// now create the root and add all children
OSG::NodeRecPtr root = OSG::Node::create();
root->setCore(OSG::Group::create());
root->addChild(lightNode);
root->addChild(camBeacon);
root->addChild(lightBeacon);
return OSG::NodeTransitPtr(root);
}
int main(int argc, char **argv)
{
OSG::preloadSharedObject("OSGFileIO");
OSG::preloadSharedObject("OSGImageFileIO");
OSG::osgInit(argc,argv);
int winid = setupGLUT(&argc, argv);
scene = createScenegraph();
//create camera, background, viewport, render action, window
camera = OSG::PerspectiveCamera::create();
camera->setBeacon(camBeacon);
camera->setFov(OSG::osgDegree2Rad(90.0f));
camera->setNear(0.1f);
camera->setFar(100.f);
OSG::GradientBackgroundRecPtr bkg = OSG::GradientBackground::create();
bkg->addLine(OSG::Color3f(0.5f,0.5f,0.5f),0);
bkg->addLine(OSG::Color3f(1,1,1),1);
viewport = OSG::Viewport::create();
viewport->setCamera(camera);
viewport->setBackground(bkg);
viewport->setRoot(scene);
viewport->setSize(0,0,1,1);
renderAction = OSG::RenderAction::create();
OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
gwin->setGlutId(winid);
gwin->setSize(300,300);
window = gwin;
window->addPort(viewport);
window->init();
printf_s("Now moving terrain, camera is in 0,0,0\n");
OSG::commitChanges();
glutMainLoop();
return 0;
}
void reshape(int w, int h)
{
window->resize(w, h);
glutPostRedisplay();
}
void display(void)
{
OSG::commitChanges();
OSG::Matrix mat;
OSG::Quaternion q;
q.setValue(rx,ry,rz);
mat.setTransform(OSG::Vec3f(tx,ty,tz),q);
if(updateCameraPos)
camTrans->setMatrix(mat); // 15 30 15
-1.57
else
terrainTransCore->setMatrix(mat); // -15 15 -30 1.57
if(eye)
terrain->setEyePoint(OSG::Pnt3f(tex,tey,tez));
//float e = 100.f;
//terrain->setEyePoint(OSG::Pnt3f(OSG::osgRand()*e-e/2.f,
OSG::osgRand()*e-e/2.f, OSG::osgRand()*e-e/2.f));
window->render(renderAction);
}
void mouse(int button, int state, int x, int y)
{
glutPostRedisplay();
}
void motion(int x, int y)
{
glutPostRedisplay();
}
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
{
terrain = NULL;
terrainTransCore=NULL;
scene = NULL;
window = NULL;
camera = NULL;
viewport = NULL;
camBeacon = NULL;
lightBeacon = NULL;
lightNode = NULL;
renderAction= NULL;
camTrans = NULL;
OSG::osgExit();
exit(1);
}
break;
case 'a':
tx-=TRASL;
break;
case 'd':
tx+=TRASL;
break;
case 'w':
ty+=TRASL;
break;
case 's':
ty-=TRASL;
break;
case 'q':
tz+=TRASL;
break;
case 'e':
tz-=TRASL;
break;
case 'f':
rx-=ROT;
break;
case 'h':
rx+=ROT;
break;
case 't':
ry+=ROT;
break;
case 'g':
ry-=ROT;
break;
case 'r':
rz+=ROT;
break;
case 'y':
rz-=ROT;
break;
case 'j':
tex-=10.f*TRASL;
break;
case 'l':
tex+=10.f*TRASL;
break;
case 'i':
tey+=10.f*TRASL;
break;
case 'k':
tey-=10.f*TRASL;
break;
case 'u':
tez+=10.f*TRASL;
break;
case 'o':
tez-=10.f*TRASL;
break;
case '1': // move the terrain and put the camera in 0,0,0
{
tx=-15.f;
ty=15.f;
tz=-30.f;
rx=3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=false;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving terrain, camera is in 0,0,0\n");
}
break;
case '2': // move the camera and put the terrain in 0,0,0
{
tx=15.f;
ty=30.f;
tz=15.f;
rx=-3.1415f/2.f;
ry=0.f;
rz=0.f;
updateCameraPos=true;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
printf_s("Now moving camera, terrain is in 0,0,0\n");
}
break;
case '3': // use the terrain->setEyePoint() to update the terrain
{
eye=!eye;
if(eye)
{
terrain->setEyePointValid(true);
printf_s("Now moving eye...\n");
}
else
{
terrain->setEyePointValid(false);
printf_s("Now NOT moving eye...\n");
}
tex=0.f;
tey=0.f;
tez=0.f;
}
break;
case '0': // reset camera and terrain transformations
{
rx=ry=rz=tx=ty=tz=0.f;
OSG::Matrix mat; mat.setIdentity();
camTrans->setMatrix(mat);
terrainTransCore->setMatrix(mat);
}
break;
}
printf_s("%.1f %.1f %.1f, %.1f %.1f %.1f, %.1f %.1f %.1f\n",
tx,ty,tz,rx,ry,rz,tex,tey,tez);
}
int setupGLUT(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
int winid = glutCreateWindow("QuadTreeTerrain without SSM problem");
glutDisplayFunc(display);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);
return winid;
}
"
--------------------------------------------------------------
On 2014-07-16 15:06, Christian Bar wrote:
> Hello! I am experiencing a problem with the QuadTreeTerrain rendering.
> With the test project everything works, but when I tried to implement it
> inside my project the terrain shows just some little parts of it (also
> with wrong triangles, this one seems like an indexing problem).
> After lot of trials, it seems to me that the quadtree algorithm does not
> work properly when the terrain is not in the origin of the world
> coordinates.
hmm, possible, it may never have been located anywhere but at the origin.
[snip]
> I also tried to use the 'terrain->setEyePoint()' and
> 'terrain->setEyePointValid()', but it works (again) only if the terrain
> is in the origin.
In which coordinate system did you specify the eye point? For example
was the eye point you set in the terrain's local coordinate system or in
world coordinates?
> What can I do to solve my problem? Thank you!
My guess would be that the camera position (either the one derived from
the active camera or the one set explicitly) are not transformed to
local coordinates. I don't have the code in front of me right now (can
take a look tomorrow), but my hope would be that the eye position is
calculate only in one (or very few) places and only needs to be
multiplied with the inverse transform of the current node.
Cheers,
Carsten
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users