From 3285a0147a8d818b20b7c93d2d78b0b134315a2a Mon Sep 17 00:00:00 2001 From: engineer_apple Date: Sun, 1 May 2022 01:11:45 +0000 Subject: [PATCH] a) debug Camera Matrices. enable with _IRR_COMPILE_WITH_90_DEGREE_CAMERA. - allow ICameraSceneNode to accept any values and correct in buildCameraLookAtMatrixLH with normalize_camera_direction. if disabled defaults to the current v1.9 normalize b) add initial Rotation to MayaCamera Constructor default 0,0 c) switchToMayaCamera in Examples. Clones FPSCamera default disabled git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6366 dfc29bdd-3216-0410-991c-e03cc46cb475 --- examples/08.SpecialFX/main.cpp | 1 + examples/11.PerPixelLighting/main.cpp | 2 ++ examples/22.MaterialViewer/main.cpp | 29 +++++++++++---- examples/22.MaterialViewer/main.h | 6 +++- examples/27.PostProcessing/main.cpp | 3 +- include/ISceneManager.h | 4 ++- include/IrrCompileConfig.h | 7 ++++ include/driverChoice.h | 36 +++++++++++++++++++ include/matrix4.h | 6 ++-- include/vector3d.h | 30 ++++++++++++++++ source/Irrlicht/CCameraSceneNode.cpp | 4 +++ source/Irrlicht/CSceneManager.cpp | 6 ++-- source/Irrlicht/CSceneManager.h | 29 +++++++++++++-- .../Irrlicht/CSceneNodeAnimatorCameraMaya.cpp | 12 ++++--- .../Irrlicht/CSceneNodeAnimatorCameraMaya.h | 4 ++- 15 files changed, 156 insertions(+), 23 deletions(-) diff --git a/examples/08.SpecialFX/main.cpp b/examples/08.SpecialFX/main.cpp index c72674b..7e3d80b 100644 --- a/examples/08.SpecialFX/main.cpp +++ b/examples/08.SpecialFX/main.cpp @@ -291,6 +291,7 @@ int main() // disable mouse cursor device->getCursorControl()->setVisible(false); + switchToMayaCamera(device); s32 lastFPS = -1; diff --git a/examples/11.PerPixelLighting/main.cpp b/examples/11.PerPixelLighting/main.cpp index afa59cb..77c48a0 100644 --- a/examples/11.PerPixelLighting/main.cpp +++ b/examples/11.PerPixelLighting/main.cpp @@ -212,6 +212,8 @@ int main() // disable mouse cursor device->getCursorControl()->setVisible(false); + switchToMayaCamera(device); + /* Because we want the whole scene to look a little bit scarier, we add some fog to it. This is done by a call to IVideoDriver::setFog(). There diff --git a/examples/22.MaterialViewer/main.cpp b/examples/22.MaterialViewer/main.cpp index d814d4f..37490b9 100755 --- a/examples/22.MaterialViewer/main.cpp +++ b/examples/22.MaterialViewer/main.cpp @@ -450,6 +450,12 @@ void CMaterialControl::init(IrrlichtDevice * device, const core::position2d TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d(pos.X, top), true, guiEnv->getRootGUIElement()); top += 300; + guiEnv->addStaticText(L"Shininess", core::rect(pos.X, top, pos.X + 150, top + 15), true, false, 0, -1, true); + top += 15; + ShininessControl = guiEnv->addScrollBar(true, core::rect(pos.X, top, pos.X + 150, top + 15)); + ShininessControl->setMax(10000); + top += 20; + // Controls for selecting the material textures guiEnv->addStaticText(L"Textures", core::rect(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true); top += 15; @@ -475,6 +481,9 @@ void CMaterialControl::setMaterial(const irr::video::SMaterial & material) TypicalColorsControl->setColorsToMaterialColors(material); for (irr::u32 i=0; isetDirty(); + + if (ShininessControl) + ShininessControl->setPos((int)(material.Shininess*100.f)); } void CMaterialControl::update(scene::IMeshSceneNode* sceneNode, scene::IMeshSceneNode* sceneNode2T, scene::IMeshSceneNode* sceneNodeTangents) @@ -558,6 +567,7 @@ void CMaterialControl::updateMaterial(video::SMaterial & material) material.TextureLayer[i].Texture = Driver->findTexture( io::path(TextureControls[i]->getSelectedTextureName()) ); } } + material.Shininess = ShininessControl->getPos() * 0.01f; } /* @@ -765,6 +775,7 @@ bool CApp::init(int argc, char *argv[]) ComboMeshType->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT); ComboMeshType->addItem(L"cube"); ComboMeshType->addItem(L"sphere"); + ComboMeshType->addItem(L"sphere highres"); ControlVertexColors = new CColorControl( guiEnv, core::position2d(440, controlsTop+30), L"Vertex colors", guiEnv->getRootGUIElement()); ControlVertexColors->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT); ControlVertexColors->setColor(irr::video::SColor(255,255,255,255)); @@ -817,8 +828,8 @@ bool CApp::update() GlobalAmbient->resetDirty(); } - const float zoomSpeed = 10.f * deltaTime; - const float rotationSpeed = 100.f * deltaTime; + const float zoomSpeed = (KeysPressed[KEY_LSHIFT] ? 40.f : 10.f) * deltaTime; + const float rotationSpeed = (KeysPressed[KEY_LSHIFT] ? 20.f : 100.f) * deltaTime; // Let the user move the light around irr::gui::IGUIElement* focus=guiEnv->getFocus(); // some checks to prevent interfering with UI input @@ -843,7 +854,7 @@ bool CApp::update() } // Let the user move the camera around - if (MousePressed) + if (MousePressed && !focus) { gui::ICursorControl* cursorControl = Device->getCursorControl(); const core::position2d& mousePos = cursorControl->getPosition (); @@ -1051,13 +1062,13 @@ void CApp::setActiveMeshNodeType(ENodeType nodeType) // add the nodes which are used to show the materials const irr::f32 size = 35.f; - if ( nodeType == ENT_CUBE) + if ( nodeType == ENT_CUBE ) { SceneNode = smgr->addCubeSceneNode (size, 0, -1, core::vector3df(0, 0, 0), core::vector3df(0.f, 45.f, 0.f), core::vector3df(1.0f, 1.0f, 1.0f), - scene::ECMT_1BUF_24VTX_NP); + scene::ECMT_1BUF_24VTX_NP); // avoid wrong colored lines at cube-borders (uv's go from 0-1 currently, which does not work well with interpolation) for ( u32 i=0; i < irr::video::MATERIAL_MAX_TEXTURES_USED; ++i) { @@ -1067,8 +1078,14 @@ void CApp::setActiveMeshNodeType(ENodeType nodeType) } else { - SceneNode = smgr->addSphereSceneNode(size*0.5f); + SceneNode = smgr->addSphereSceneNode(size * 0.5f, nodeType == ENT_SPHERE_HIGHRES ? 128 : 16); } + // off center to test shader + //SceneNode->setPosition(core::vector3df(20.f, -4.f, 10.f)); + //SceneNode->setScale(core::vector3df(1.f, 0.2f, 1.5f)); + //SceneNode->setRotation(core::vector3df(0.f, 30.f, -10.f)); + //defaultMaterial.NormalizeNormals = true; + SceneNode->getMaterial(0) = defaultMaterial; // SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on diff --git a/examples/22.MaterialViewer/main.h b/examples/22.MaterialViewer/main.h index dc121cd..8bbaefc 100644 --- a/examples/22.MaterialViewer/main.h +++ b/examples/22.MaterialViewer/main.h @@ -146,6 +146,7 @@ public: CMaterialControl() : Initialized(false), Driver(0) , TypicalColorsControl(0), ButtonLighting(0), InfoLighting(0), ComboMaterial(0) + , ShininessControl(0) {} // Destructor @@ -183,6 +184,8 @@ protected: irr::gui::IGUIStaticText* InfoLighting; irr::gui::IGUIComboBox * ComboMaterial; irr::core::array TextureControls; + + irr::gui::IGUIScrollBar* ShininessControl; }; /* @@ -302,7 +305,8 @@ protected: enum ENodeType { ENT_CUBE, - ENT_SPHERE + ENT_SPHERE, + ENT_SPHERE_HIGHRES, }; void setActiveMeshNodeType(ENodeType nodeType); diff --git a/examples/27.PostProcessing/main.cpp b/examples/27.PostProcessing/main.cpp index ae4d6c4..1c9df3f 100644 --- a/examples/27.PostProcessing/main.cpp +++ b/examples/27.PostProcessing/main.cpp @@ -17,11 +17,10 @@ written in HLSL and GLSL. We include all headers and define necessary variables as we have done before. */ +#include #include "driverChoice.h" #include "exampleHelper.h" -#include - using namespace irr; #ifdef _MSC_VER diff --git a/include/ISceneManager.h b/include/ISceneManager.h index 8c4cd32..f333d16 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -616,7 +616,9 @@ namespace scene virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.f, - bool makeActive=true) =0; + bool makeActive=true + , f32 rotX = 0.f, f32 rotY = 0.f + ) =0; //! Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for first person shooters (FPS). /** This FPS camera is intended to provide a demonstration of a diff --git a/include/IrrCompileConfig.h b/include/IrrCompileConfig.h index 45b5892..11f890c 100644 --- a/include/IrrCompileConfig.h +++ b/include/IrrCompileConfig.h @@ -862,4 +862,11 @@ precision will be lower but speed higher. currently X86 only #endif #endif +//! Solve Camera errors - Debug Feature +/* - Allow Camera 90 degree up, Target==Position,buildCameraLookAtMatrixLH + - pre v1.9 CCameraSceneNode moved the up non-particular in the positive x-Direction. not compatible + - Enabled is not compatible with Irrlicht Collision and Response. +*/ +//#define _IRR_COMPILE_WITH_90_DEGREE_CAMERA + #endif // IRR_COMPILE_CONFIG_H_INCLUDED diff --git a/include/driverChoice.h b/include/driverChoice.h index 402e71c..334553c 100644 --- a/include/driverChoice.h +++ b/include/driverChoice.h @@ -50,6 +50,42 @@ namespace irr #endif } + /* + For using an alternative camera in the examples. + Try to translate the viewpoint (Maya internal CameraRotation) + */ + static inline void switchToMayaCamera(IrrlichtDevice* device) + { +#if 1 + return; +#else + if (!device) return; + + scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera(); + if (!camera || camera->getID() == 54321) return; + + + core::vector3df target = camera->getTarget() - camera->getPosition(); + core::vector3df relativeRotation = target.getHorizontalAngle(); + + scene::ICameraSceneNode* maya = device->getSceneManager()->addCameraSceneNodeMaya( + 0, -1500, 1000, 1500, + 54321, + target.getLength(), + true, + relativeRotation.X + 90, relativeRotation.Y + ); + if (maya) + { + maya->setNearValue(camera->getNearValue()); + maya->setFarValue(camera->getFarValue()); + } + + device->getCursorControl()->setVisible(true); + device->setResizable(true); +#endif + } + } // end namespace irr #endif diff --git a/include/matrix4.h b/include/matrix4.h index f39de7d..26a3306 100644 --- a/include/matrix4.h +++ b/include/matrix4.h @@ -1908,10 +1908,10 @@ namespace core const vector3df& upVector) { vector3df zaxis = target - position; - zaxis.normalize(); + zaxis.normalize_z(); - vector3df xaxis = upVector.crossProduct(zaxis); - xaxis.normalize(); + vector3df xaxis = normalize_y(upVector).crossProduct(zaxis); + xaxis.normalize_x(); vector3df yaxis = zaxis.crossProduct(xaxis); diff --git a/include/vector3d.h b/include/vector3d.h index dfc35b5..dc2e955 100644 --- a/include/vector3d.h +++ b/include/vector3d.h @@ -195,6 +195,36 @@ namespace core return (*this *= newlength); } +#if defined(_IRR_COMPILE_WITH_90_DEGREE_CAMERA) + vector3d& normalize_camera_direction(const vector3d& def) + { + f64 l = (f64)X * X + (f64)Y * Y + (f64)Z * Z; + if (::fabs(l) < 0.000000001) + { + X = def.X; + Y = def.Y; + Z = def.Z; + } + else + { + l = 1.0 / ::sqrt(l); + f64 v; + v = X * l; X = ::fabs(v) < 0.00000001 ? (T)0 : (T)v; + v = Y * l; Y = ::fabs(v) < 0.00000001 ? (T)0 : (T)v; + v = Z * l; Z = ::fabs(v) < 0.00000001 ? (T)0 : (T)v; + } + return *this; + } +#define normalize_x() normalize_camera_direction(core::vector3df(1.f, 0.f, 0.f)) +#define normalize_z() normalize_camera_direction(core::vector3df(0.f, 0.f, 1.f)) +#define normalize_y(v) core::vector3df(v).normalize_camera_direction(core::vector3df(0.f, 1.f, 0.f)) +#else +#define normalize_x() normalize() +#define normalize_z() normalize() +#define normalize_y(v) v +#endif + + //! Inverts the vector. vector3d& invert() { diff --git a/source/Irrlicht/CCameraSceneNode.cpp b/source/Irrlicht/CCameraSceneNode.cpp index e0b68fc..34c6689 100644 --- a/source/Irrlicht/CCameraSceneNode.cpp +++ b/source/Irrlicht/CCameraSceneNode.cpp @@ -265,6 +265,9 @@ void CCameraSceneNode::render() //! update void CCameraSceneNode::updateMatrices() { +#if defined(_IRR_COMPILE_WITH_90_DEGREE_CAMERA) + ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(getAbsolutePosition(), Target, UpVector); +#else core::vector3df pos = getAbsolutePosition(); core::vector3df tgtv = Target - pos; tgtv.normalize(); @@ -282,6 +285,7 @@ void CCameraSceneNode::updateMatrices() } ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up); +#endif ViewArea.getTransform(video::ETS_VIEW) *= Affector; recalculateViewArea(); } diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index b860182..d921cca 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -775,14 +775,16 @@ ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent, //! The returned pointer must not be dropped. ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent, f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id, f32 distance, - bool makeActive) + bool makeActive + , f32 rotX, f32 rotY) { ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(), core::vector3df(0,0,100), id, makeActive); if (node) { ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya(CursorControl, - rotateSpeed, zoomSpeed, translationSpeed, distance); + rotateSpeed, zoomSpeed, translationSpeed, distance + ,rotX,rotY); node->addAnimator(anm); anm->drop(); diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 5051ecc..7314e1b 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -147,7 +147,9 @@ namespace scene virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.f, - bool makeActive=true) IRR_OVERRIDE; + bool makeActive=true + , f32 rotX = 0.f, f32 rotY = 0.f + ) IRR_OVERRIDE; //! Adds a camera scene node which is able to be controled with the mouse and keys //! like in most first person shooters (FPS): @@ -565,13 +567,36 @@ namespace scene void* TextureValue; }; + /* + const core::aabbox3d box = Node->getTransformedBoundingBox(); + Distance = core::min_(camera.getDistanceFromSQ(box.MinEdge), camera.getDistanceFromSQ(box.MaxEdge)); + */ + static inline f32 estimatedSphereDistance(const ISceneNode* node, const core::vector3df& camera) + { + const core::aabbox3d& box = node->getBoundingBox(); + const f32* m = node->getAbsoluteTransformation().pointer(); + + f32 p[4]; + p[0] = camera.X - (box.MinEdge.X * m[0] + box.MinEdge.Y * m[4] + box.MinEdge.Z * m[8] + m[12]); + p[1] = camera.Y - (box.MinEdge.X * m[1] + box.MinEdge.Y * m[5] + box.MinEdge.Z * m[9] + m[13]); + p[2] = camera.Z - (box.MinEdge.X * m[2] + box.MinEdge.Y * m[6] + box.MinEdge.Z * m[10] + m[14]); + f32 l0 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]); + + p[0] = camera.X - (box.MaxEdge.X * m[0] + box.MaxEdge.Y * m[4] + box.MaxEdge.Z * m[8] + m[12]); + p[1] = camera.Y - (box.MaxEdge.X * m[1] + box.MaxEdge.Y * m[5] + box.MaxEdge.Z * m[9] + m[13]); + p[2] = camera.Z - (box.MaxEdge.X * m[2] + box.MaxEdge.Y * m[6] + box.MaxEdge.Z * m[10] + m[14]); + f32 l1 = (p[0] * p[0]) + (p[1] * p[1]) + (p[2] * p[2]); + return core::min_(l0, l1); + } + //! sort on distance (center) to camera struct TransparentNodeEntry { TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera) : Node(n) { - Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); + //Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); + Distance = estimatedSphereDistance(n, camera); } bool operator < (const TransparentNodeEntry& other) const diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp index a7d2b21..45b8edb 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp @@ -15,11 +15,13 @@ namespace scene //! constructor CSceneNodeAnimatorCameraMaya::CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, - f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance) + f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance + , f32 rotX, f32 rotY +) : CursorControl(cursor), OldCamera(0), MousePos(0.5f, 0.5f), TargetMinDistance(0.f), ZoomSpeed(zoomSpeed), RotateSpeed(rotateSpeed), TranslateSpeed(translateSpeed), - CurrentZoom(distance), RotX(0.0f), RotY(0.0f), + CurrentZoom(distance), RotX(rotX), RotY(rotY), Zooming(false), Rotating(false), Moving(false), Translating(false) { #ifdef _DEBUG @@ -171,18 +173,18 @@ void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs) // Translation --------------------------------- core::vector3df translate(OldTarget); - const core::vector3df upVector(camera->getUpVector()); + const core::vector3df upVector(normalize_y(camera->getUpVector())); const core::vector3df target = camera->getTarget(); core::vector3df pos = camera->getPosition(); core::vector3df tvectX = pos - target; tvectX = tvectX.crossProduct(upVector); - tvectX.normalize(); + tvectX.normalize_z(); const SViewFrustum* const va = camera->getViewFrustum(); core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown()); tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos); - tvectY.normalize(); + tvectY.normalize_x(); if (isMouseKeyDown(2) && !Zooming) { diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h b/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h index e103123..9b3993d 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h +++ b/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h @@ -29,7 +29,9 @@ namespace scene public: //! Constructor CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, f32 rotateSpeed = -1500.f, - f32 zoomSpeed = 200.f, f32 translationSpeed = 1500.f, f32 distance=70.f); + f32 zoomSpeed = 200.f, f32 translationSpeed = 1500.f, f32 distance=70.f + , f32 rotX = 0.f, f32 rotY = 0.f + ); //! Destructor virtual ~CSceneNodeAnimatorCameraMaya();