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
This commit is contained in:
engineer_apple 2022-05-01 01:11:45 +00:00
parent e08e37fc0f
commit 3285a0147a
15 changed files with 156 additions and 23 deletions

View File

@ -291,6 +291,7 @@ int main()
// disable mouse cursor // disable mouse cursor
device->getCursorControl()->setVisible(false); device->getCursorControl()->setVisible(false);
switchToMayaCamera(device);
s32 lastFPS = -1; s32 lastFPS = -1;

View File

@ -212,6 +212,8 @@ int main()
// disable mouse cursor // disable mouse cursor
device->getCursorControl()->setVisible(false); device->getCursorControl()->setVisible(false);
switchToMayaCamera(device);
/* /*
Because we want the whole scene to look a little bit scarier, we add 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 some fog to it. This is done by a call to IVideoDriver::setFog(). There

View File

@ -450,6 +450,12 @@ void CMaterialControl::init(IrrlichtDevice * device, const core::position2d<s32>
TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d<s32>(pos.X, top), true, guiEnv->getRootGUIElement()); TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d<s32>(pos.X, top), true, guiEnv->getRootGUIElement());
top += 300; top += 300;
guiEnv->addStaticText(L"Shininess", core::rect<s32>(pos.X, top, pos.X + 150, top + 15), true, false, 0, -1, true);
top += 15;
ShininessControl = guiEnv->addScrollBar(true, core::rect<s32>(pos.X, top, pos.X + 150, top + 15));
ShininessControl->setMax(10000);
top += 20;
// Controls for selecting the material textures // Controls for selecting the material textures
guiEnv->addStaticText(L"Textures", core::rect<s32>(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true); guiEnv->addStaticText(L"Textures", core::rect<s32>(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true);
top += 15; top += 15;
@ -475,6 +481,9 @@ void CMaterialControl::setMaterial(const irr::video::SMaterial & material)
TypicalColorsControl->setColorsToMaterialColors(material); TypicalColorsControl->setColorsToMaterialColors(material);
for (irr::u32 i=0; i<TextureControls.size(); ++i) for (irr::u32 i=0; i<TextureControls.size(); ++i)
TextureControls[i]->setDirty(); TextureControls[i]->setDirty();
if (ShininessControl)
ShininessControl->setPos((int)(material.Shininess*100.f));
} }
void CMaterialControl::update(scene::IMeshSceneNode* sceneNode, scene::IMeshSceneNode* sceneNode2T, scene::IMeshSceneNode* sceneNodeTangents) 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.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->setAlignment(irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_LOWERRIGHT, irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT);
ComboMeshType->addItem(L"cube"); ComboMeshType->addItem(L"cube");
ComboMeshType->addItem(L"sphere"); ComboMeshType->addItem(L"sphere");
ComboMeshType->addItem(L"sphere highres");
ControlVertexColors = new CColorControl( guiEnv, core::position2d<s32>(440, controlsTop+30), L"Vertex colors", guiEnv->getRootGUIElement()); ControlVertexColors = new CColorControl( guiEnv, core::position2d<s32>(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->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)); ControlVertexColors->setColor(irr::video::SColor(255,255,255,255));
@ -817,8 +828,8 @@ bool CApp::update()
GlobalAmbient->resetDirty(); GlobalAmbient->resetDirty();
} }
const float zoomSpeed = 10.f * deltaTime; const float zoomSpeed = (KeysPressed[KEY_LSHIFT] ? 40.f : 10.f) * deltaTime;
const float rotationSpeed = 100.f * deltaTime; const float rotationSpeed = (KeysPressed[KEY_LSHIFT] ? 20.f : 100.f) * deltaTime;
// Let the user move the light around // Let the user move the light around
irr::gui::IGUIElement* focus=guiEnv->getFocus(); // some checks to prevent interfering with UI input 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 // Let the user move the camera around
if (MousePressed) if (MousePressed && !focus)
{ {
gui::ICursorControl* cursorControl = Device->getCursorControl(); gui::ICursorControl* cursorControl = Device->getCursorControl();
const core::position2d<s32>& mousePos = cursorControl->getPosition (); const core::position2d<s32>& mousePos = cursorControl->getPosition ();
@ -1051,7 +1062,7 @@ void CApp::setActiveMeshNodeType(ENodeType nodeType)
// add the nodes which are used to show the materials // add the nodes which are used to show the materials
const irr::f32 size = 35.f; const irr::f32 size = 35.f;
if ( nodeType == ENT_CUBE) if ( nodeType == ENT_CUBE )
{ {
SceneNode = smgr->addCubeSceneNode (size, 0, -1, SceneNode = smgr->addCubeSceneNode (size, 0, -1,
core::vector3df(0, 0, 0), core::vector3df(0, 0, 0),
@ -1067,8 +1078,14 @@ void CApp::setActiveMeshNodeType(ENodeType nodeType)
} }
else 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->getMaterial(0) = defaultMaterial;
// SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on // SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on

View File

@ -146,6 +146,7 @@ public:
CMaterialControl() CMaterialControl()
: Initialized(false), Driver(0) : Initialized(false), Driver(0)
, TypicalColorsControl(0), ButtonLighting(0), InfoLighting(0), ComboMaterial(0) , TypicalColorsControl(0), ButtonLighting(0), InfoLighting(0), ComboMaterial(0)
, ShininessControl(0)
{} {}
// Destructor // Destructor
@ -183,6 +184,8 @@ protected:
irr::gui::IGUIStaticText* InfoLighting; irr::gui::IGUIStaticText* InfoLighting;
irr::gui::IGUIComboBox * ComboMaterial; irr::gui::IGUIComboBox * ComboMaterial;
irr::core::array<CTextureControl*> TextureControls; irr::core::array<CTextureControl*> TextureControls;
irr::gui::IGUIScrollBar* ShininessControl;
}; };
/* /*
@ -302,7 +305,8 @@ protected:
enum ENodeType enum ENodeType
{ {
ENT_CUBE, ENT_CUBE,
ENT_SPHERE ENT_SPHERE,
ENT_SPHERE_HIGHRES,
}; };
void setActiveMeshNodeType(ENodeType nodeType); void setActiveMeshNodeType(ENodeType nodeType);

View File

@ -17,11 +17,10 @@ written in HLSL and GLSL.
We include all headers and define necessary variables as we have done before. We include all headers and define necessary variables as we have done before.
*/ */
#include <irrlicht.h>
#include "driverChoice.h" #include "driverChoice.h"
#include "exampleHelper.h" #include "exampleHelper.h"
#include <irrlicht.h>
using namespace irr; using namespace irr;
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -616,7 +616,9 @@ namespace scene
virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0,
f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f,
f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.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). //! 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 /** This FPS camera is intended to provide a demonstration of a

View File

@ -862,4 +862,11 @@ precision will be lower but speed higher. currently X86 only
#endif #endif
#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 #endif // IRR_COMPILE_CONFIG_H_INCLUDED

View File

@ -50,6 +50,42 @@ namespace irr
#endif #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 } // end namespace irr
#endif #endif

View File

@ -1908,10 +1908,10 @@ namespace core
const vector3df& upVector) const vector3df& upVector)
{ {
vector3df zaxis = target - position; vector3df zaxis = target - position;
zaxis.normalize(); zaxis.normalize_z();
vector3df xaxis = upVector.crossProduct(zaxis); vector3df xaxis = normalize_y(upVector).crossProduct(zaxis);
xaxis.normalize(); xaxis.normalize_x();
vector3df yaxis = zaxis.crossProduct(xaxis); vector3df yaxis = zaxis.crossProduct(xaxis);

View File

@ -195,6 +195,36 @@ namespace core
return (*this *= newlength); return (*this *= newlength);
} }
#if defined(_IRR_COMPILE_WITH_90_DEGREE_CAMERA)
vector3d<T>& normalize_camera_direction(const vector3d<T>& 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. //! Inverts the vector.
vector3d<T>& invert() vector3d<T>& invert()
{ {

View File

@ -265,6 +265,9 @@ void CCameraSceneNode::render()
//! update //! update
void CCameraSceneNode::updateMatrices() 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 pos = getAbsolutePosition();
core::vector3df tgtv = Target - pos; core::vector3df tgtv = Target - pos;
tgtv.normalize(); tgtv.normalize();
@ -282,6 +285,7 @@ void CCameraSceneNode::updateMatrices()
} }
ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up); ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up);
#endif
ViewArea.getTransform(video::ETS_VIEW) *= Affector; ViewArea.getTransform(video::ETS_VIEW) *= Affector;
recalculateViewArea(); recalculateViewArea();
} }

View File

@ -775,14 +775,16 @@ ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent,
//! The returned pointer must not be dropped. //! The returned pointer must not be dropped.
ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent, ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent,
f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id, f32 distance, f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id, f32 distance,
bool makeActive) bool makeActive
, f32 rotX, f32 rotY)
{ {
ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(), ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(),
core::vector3df(0,0,100), id, makeActive); core::vector3df(0,0,100), id, makeActive);
if (node) if (node)
{ {
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya(CursorControl, ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya(CursorControl,
rotateSpeed, zoomSpeed, translationSpeed, distance); rotateSpeed, zoomSpeed, translationSpeed, distance
,rotX,rotY);
node->addAnimator(anm); node->addAnimator(anm);
anm->drop(); anm->drop();

View File

@ -147,7 +147,9 @@ namespace scene
virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0,
f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f,
f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.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 //! Adds a camera scene node which is able to be controled with the mouse and keys
//! like in most first person shooters (FPS): //! like in most first person shooters (FPS):
@ -565,13 +567,36 @@ namespace scene
void* TextureValue; void* TextureValue;
}; };
/*
const core::aabbox3d<f32> 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<f32>& 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 //! sort on distance (center) to camera
struct TransparentNodeEntry struct TransparentNodeEntry
{ {
TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera) TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera)
: Node(n) : Node(n)
{ {
Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); //Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera);
Distance = estimatedSphereDistance(n, camera);
} }
bool operator < (const TransparentNodeEntry& other) const bool operator < (const TransparentNodeEntry& other) const

View File

@ -15,11 +15,13 @@ namespace scene
//! constructor //! constructor
CSceneNodeAnimatorCameraMaya::CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, 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), : CursorControl(cursor), OldCamera(0), MousePos(0.5f, 0.5f),
TargetMinDistance(0.f), TargetMinDistance(0.f),
ZoomSpeed(zoomSpeed), RotateSpeed(rotateSpeed), TranslateSpeed(translateSpeed), 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) Zooming(false), Rotating(false), Moving(false), Translating(false)
{ {
#ifdef _DEBUG #ifdef _DEBUG
@ -171,18 +173,18 @@ void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs)
// Translation --------------------------------- // Translation ---------------------------------
core::vector3df translate(OldTarget); core::vector3df translate(OldTarget);
const core::vector3df upVector(camera->getUpVector()); const core::vector3df upVector(normalize_y(camera->getUpVector()));
const core::vector3df target = camera->getTarget(); const core::vector3df target = camera->getTarget();
core::vector3df pos = camera->getPosition(); core::vector3df pos = camera->getPosition();
core::vector3df tvectX = pos - target; core::vector3df tvectX = pos - target;
tvectX = tvectX.crossProduct(upVector); tvectX = tvectX.crossProduct(upVector);
tvectX.normalize(); tvectX.normalize_z();
const SViewFrustum* const va = camera->getViewFrustum(); const SViewFrustum* const va = camera->getViewFrustum();
core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown()); core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown());
tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos); tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos);
tvectY.normalize(); tvectY.normalize_x();
if (isMouseKeyDown(2) && !Zooming) if (isMouseKeyDown(2) && !Zooming)
{ {

View File

@ -29,7 +29,9 @@ namespace scene
public: public:
//! Constructor //! Constructor
CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, f32 rotateSpeed = -1500.f, 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 //! Destructor
virtual ~CSceneNodeAnimatorCameraMaya(); virtual ~CSceneNodeAnimatorCameraMaya();