Commit 0ef1056e authored by rogerborg's avatar rogerborg

https://sourceforge.net/tracker2/index.php?func=detail&aid=2472420&group_id=74339&atid=540676

Merge fix for CTerrainSceneNode::preRenderLODCalculations() to trunk; take the camera's up vector into account when determining whether terrain scene node visibility needs to be rechecked.  New test added; thanks to Travis for another great test case.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2003 dfc29bdd-3216-0410-991c-e03cc46cb475
parent c9d7d28b
...@@ -39,6 +39,7 @@ namespace scene ...@@ -39,6 +39,7 @@ namespace scene
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false), OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false),
OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
OldCameraRotation(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), OldCameraRotation(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
OldCameraUp(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
CameraMovementDelta(10.0f), CameraRotationDelta(1.0f),CameraFOVDelta(0.1f), CameraMovementDelta(10.0f), CameraRotationDelta(1.0f),CameraFOVDelta(0.1f),
TCoordScale1(1.0f), TCoordScale2(1.0f), FileSystem(fs) TCoordScale1(1.0f), TCoordScale2(1.0f), FileSystem(fs)
{ {
...@@ -552,25 +553,32 @@ namespace scene ...@@ -552,25 +553,32 @@ namespace scene
void CTerrainSceneNode::preRenderLODCalculations() void CTerrainSceneNode::preRenderLODCalculations()
{ {
scene::ICameraSceneNode * camera = SceneManager->getActiveCamera();
if(!camera)
return;
SceneManager->registerNodeForRendering(this); SceneManager->registerNodeForRendering(this);
// Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children // Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children
// Determine the camera rotation, based on the camera direction. // Determine the camera rotation, based on the camera direction.
const core::vector3df cameraPosition = SceneManager->getActiveCamera()->getAbsolutePosition(); const core::vector3df cameraPosition = camera->getAbsolutePosition();
const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, SceneManager->getActiveCamera()->getTarget()).getVector().getHorizontalAngle(); const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, camera->getTarget()).getVector().getHorizontalAngle();
core::vector3df cameraUp = camera->getUpVector();
cameraUp.normalize();
const f32 CameraFOV = SceneManager->getActiveCamera()->getFOV(); const f32 CameraFOV = SceneManager->getActiveCamera()->getFOV();
// Only check on the Camera's Y Rotation // Only check on the Camera's Y Rotation
if (!ForceRecalculation) if (!ForceRecalculation)
{ {
if (( fabs(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) && if ((fabsf(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) &&
( fabs(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta)) (fabsf(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta))
{ {
if ((fabs(cameraPosition.X - OldCameraPosition.X) < CameraMovementDelta) && if ((fabs(cameraPosition.X - OldCameraPosition.X) < CameraMovementDelta) &&
(fabs(cameraPosition.Y - OldCameraPosition.Y) < CameraMovementDelta) && (fabs(cameraPosition.Y - OldCameraPosition.Y) < CameraMovementDelta) &&
(fabs(cameraPosition.Z - OldCameraPosition.Z) < CameraMovementDelta)) (fabs(cameraPosition.Z - OldCameraPosition.Z) < CameraMovementDelta))
{ {
if (fabs(CameraFOV-OldCameraFOV) < CameraFOVDelta) if (fabs(CameraFOV-OldCameraFOV) < CameraFOVDelta &&
cameraUp.dotProduct(OldCameraUp) > (1.f - (cos(core::DEGTORAD * CameraRotationDelta))))
{ {
return; return;
} }
...@@ -580,6 +588,7 @@ namespace scene ...@@ -580,6 +588,7 @@ namespace scene
OldCameraPosition = cameraPosition; OldCameraPosition = cameraPosition;
OldCameraRotation = cameraRotation; OldCameraRotation = cameraRotation;
OldCameraUp = cameraUp;
OldCameraFOV = CameraFOV; OldCameraFOV = CameraFOV;
const SViewFrustum* frustum = SceneManager->getActiveCamera()->getViewFrustum(); const SViewFrustum* frustum = SceneManager->getActiveCamera()->getViewFrustum();
......
...@@ -323,6 +323,7 @@ namespace scene ...@@ -323,6 +323,7 @@ namespace scene
core::vector3df OldCameraPosition; core::vector3df OldCameraPosition;
core::vector3df OldCameraRotation; core::vector3df OldCameraRotation;
core::vector3df OldCameraUp;
f32 OldCameraFOV; f32 OldCameraFOV;
f32 CameraMovementDelta; f32 CameraMovementDelta;
f32 CameraRotationDelta; f32 CameraRotationDelta;
......
...@@ -48,8 +48,8 @@ int main(int argumentCount, char * arguments[]) ...@@ -48,8 +48,8 @@ int main(int argumentCount, char * arguments[])
// Note that to interactively debug a test, you will generally want to move it // Note that to interactively debug a test, you will generally want to move it
// (temporarily) to the beginning of the list, since each test runs in its own // (temporarily) to the beginning of the list, since each test runs in its own
// process. // process.
TEST(vectorPositionDimension2d);
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory. TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
TEST(vectorPositionDimension2d);
TEST(irrCoreEquals); TEST(irrCoreEquals);
TEST(sceneNodeAnimator); TEST(sceneNodeAnimator);
TEST(sceneCollisionManager); TEST(sceneCollisionManager);
...@@ -66,6 +66,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -66,6 +66,7 @@ int main(int argumentCount, char * arguments[])
TEST(guiDisabledMenu); TEST(guiDisabledMenu);
TEST(softwareDevice); TEST(softwareDevice);
TEST(b3dAnimation); TEST(b3dAnimation);
TEST(terrainSceneNode);
const unsigned int numberOfTests = tests.size(); const unsigned int numberOfTests = tests.size();
...@@ -105,7 +106,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -105,7 +106,7 @@ int main(int argumentCount, char * arguments[])
{ {
closeTestLog(); closeTestLog();
char runNextTest[256]; char runNextTest[256];
(void)sprintf(runNextTest, "%s %d %d", arguments[0], testToRun, fails); (void)sprintf(runNextTest, "\"%s\" %d %d", arguments[0], testToRun, fails);
fails = system(runNextTest); fails = system(runNextTest);
} }
......
#include "testUtils.h"
#include "irrlicht.h"
#include <assert.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
bool terrainSceneNode(void)
{
IrrlichtDevice *device =
createDevice(video::EDT_OPENGL, dimension2di(160, 120), 32);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../media/terrain-heightmap.bmp");
terrain->setScale(core::vector3df(40.f, .1f, 40.f));
terrain->setMaterialFlag(video::EMF_LIGHTING, false);
terrain->setMaterialTexture(0, driver->getTexture("../media/terrain-texture.jpg"));
terrain->setDebugDataVisible(scene::EDS_FULL);
ICameraSceneNode* camera = smgr->addCameraSceneNode();
const core::vector3df center (terrain->getBoundingBox().getCenter());
camera->setTarget (center);
// yes, Y is intentionally being set to X here
const core::vector3df above (center.X, center.X, center.Z);
camera->setPosition (above);
camera->setUpVector(vector3df(1.f, 0.f, 0.f));
camera->setFarValue(above.Y);
device->run();
smgr->drawAll();
// This shouldn't cause a recalc
camera->setUpVector(vector3df(1.f, 0.f, .01f).normalize());
device->run();
driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
bool result = takeScreenshotAndCompareAgainstReference(driver, "-terrainSceneNode-1.png");
if(!result)
{
logTestString("Small camera up rotation caused bad recalc.\n");
assert(false);
}
// This is big enough to cause a recalc
camera->setUpVector(vector3df(1.f, 0.f, .1f).normalize());
device->run();
driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
result &= takeScreenshotAndCompareAgainstReference(driver, "-terrainSceneNode-2.png");
if(!result)
{
logTestString("Large camera up rotation caused bad recalc.\n");
assert(false);
}
device->drop();
return result;
}
\ No newline at end of file
Test suite pass at GMT Mon Dec 29 16:29:44 2008 Test suite pass at GMT Mon Dec 29 19:37:38 2008
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
<Unit filename="sceneCollisionManager.cpp" /> <Unit filename="sceneCollisionManager.cpp" />
<Unit filename="sceneNodeAnimator.cpp" /> <Unit filename="sceneNodeAnimator.cpp" />
<Unit filename="softwareDevice.cpp" /> <Unit filename="softwareDevice.cpp" />
<Unit filename="terrainSceneNode.cpp" />
<Unit filename="testDimension2d.cpp" /> <Unit filename="testDimension2d.cpp" />
<Unit filename="testUtils.cpp" /> <Unit filename="testUtils.cpp" />
<Unit filename="testVector2d.cpp" /> <Unit filename="testVector2d.cpp" />
......
...@@ -229,6 +229,10 @@ ...@@ -229,6 +229,10 @@
RelativePath=".\softwareDevice.cpp" RelativePath=".\softwareDevice.cpp"
> >
</File> </File>
<File
RelativePath=".\terrainSceneNode.cpp"
>
</File>
<File <File
RelativePath=".\testDimension2d.cpp" RelativePath=".\testDimension2d.cpp"
> >
......
...@@ -226,6 +226,10 @@ ...@@ -226,6 +226,10 @@
RelativePath=".\softwareDevice.cpp" RelativePath=".\softwareDevice.cpp"
> >
</File> </File>
<File
RelativePath=".\terrainSceneNode.cpp"
>
</File>
<File <File
RelativePath=".\testDimension2d.cpp" RelativePath=".\testDimension2d.cpp"
> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment