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
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false),
OldCameraPosition(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),
TCoordScale1(1.0f), TCoordScale2(1.0f), FileSystem(fs)
{
......@@ -552,25 +553,32 @@ namespace scene
void CTerrainSceneNode::preRenderLODCalculations()
{
scene::ICameraSceneNode * camera = SceneManager->getActiveCamera();
if(!camera)
return;
SceneManager->registerNodeForRendering(this);
// Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children
// Determine the camera rotation, based on the camera direction.
const core::vector3df cameraPosition = SceneManager->getActiveCamera()->getAbsolutePosition();
const core::vector3df cameraRotation = core::line3d<f32>(cameraPosition, SceneManager->getActiveCamera()->getTarget()).getVector().getHorizontalAngle();
const core::vector3df cameraPosition = camera->getAbsolutePosition();
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();
// Only check on the Camera's Y Rotation
if (!ForceRecalculation)
{
if (( fabs(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) &&
( fabs(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta))
if ((fabsf(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) &&
(fabsf(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta))
{
if ((fabs(cameraPosition.X - OldCameraPosition.X) < CameraMovementDelta) &&
(fabs(cameraPosition.Y - OldCameraPosition.Y) < 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;
}
......@@ -580,6 +588,7 @@ namespace scene
OldCameraPosition = cameraPosition;
OldCameraRotation = cameraRotation;
OldCameraUp = cameraUp;
OldCameraFOV = CameraFOV;
const SViewFrustum* frustum = SceneManager->getActiveCamera()->getViewFrustum();
......
......@@ -323,6 +323,7 @@ namespace scene
core::vector3df OldCameraPosition;
core::vector3df OldCameraRotation;
core::vector3df OldCameraUp;
f32 OldCameraFOV;
f32 CameraMovementDelta;
f32 CameraRotationDelta;
......
......@@ -48,8 +48,8 @@ int main(int argumentCount, char * arguments[])
// 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
// process.
TEST(vectorPositionDimension2d);
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
TEST(vectorPositionDimension2d);
TEST(irrCoreEquals);
TEST(sceneNodeAnimator);
TEST(sceneCollisionManager);
......@@ -66,6 +66,7 @@ int main(int argumentCount, char * arguments[])
TEST(guiDisabledMenu);
TEST(softwareDevice);
TEST(b3dAnimation);
TEST(terrainSceneNode);
const unsigned int numberOfTests = tests.size();
......@@ -105,7 +106,7 @@ int main(int argumentCount, char * arguments[])
{
closeTestLog();
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);
}
......
#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 @@
<Unit filename="sceneCollisionManager.cpp" />
<Unit filename="sceneNodeAnimator.cpp" />
<Unit filename="softwareDevice.cpp" />
<Unit filename="terrainSceneNode.cpp" />
<Unit filename="testDimension2d.cpp" />
<Unit filename="testUtils.cpp" />
<Unit filename="testVector2d.cpp" />
......
......@@ -229,6 +229,10 @@
RelativePath=".\softwareDevice.cpp"
>
</File>
<File
RelativePath=".\terrainSceneNode.cpp"
>
</File>
<File
RelativePath=".\testDimension2d.cpp"
>
......
......@@ -226,6 +226,10 @@
RelativePath=".\softwareDevice.cpp"
>
</File>
<File
RelativePath=".\terrainSceneNode.cpp"
>
</File>
<File
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