Add option to allow nodes to ignore the scale/rotation parts of their parents transformation.

ISceneNode::setUpdateAbsolutePosBehavior can now control what ISceneNode::updateAbsolutePosition really does.
Having only the position and not the rotation/scale of a child node affected by the parent transformation was previously impossible inside the scene-graph. So people always had to break the scene-graph and code it themselves.
Old behaviour is default. 
Extra check for new variable has a small cost, thought new behaviour can actually be faster when it's used.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6432 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-09-29 16:34:37 +00:00
parent 91f281229b
commit b627ce805d
8 changed files with 82 additions and 10 deletions

@ -1,6 +1,7 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Add ISceneNode::UpdateAbsolutePosBehavior variable to allow nodes to ignore the scale/rotation parts of their parents transformation.
- Add IGUISpinBox functions getValueFor and getOldValue - Add IGUISpinBox functions getValueFor and getOldValue
- Bugfix: IGUIElement::getNextElement now passing includeInvisible and includeDisabled flags recursively instead of disabling those for children. - Bugfix: IGUIElement::getNextElement now passing includeInvisible and includeDisabled flags recursively instead of disabling those for children.
This fixes problems that elements sometimes didn't get a tab order because some parent was invisible and so tab'ing for them failed completely. This fixes problems that elements sometimes didn't get a tab order because some parent was invisible and so tab'ing for them failed completely.

@ -0,0 +1,34 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef IRR_E_SCENE_NODE_UPDATE_ABS_H_INCLUDED
#define IRR_E_SCENE_NODE_UPDATE_ABS_H_INCLUDED
namespace irr
{
namespace scene
{
//! Options how ISceneNode::updateAbsolutePosition calculates the AbsoluteTransformation
enum ESCENE_NODE_UPDATE_ABS
{
//! Node and parent transformation matrices are multiplied (default)
ESNUA_TRANSFORM_MATRIX,
//! Only transform the position of the node transformation matrix
//! by the parent transformation matrix.
//! Parent will not affect the rotation/scale of the node transformation.
ESNUA_TRANSFORM_POSITION
};
//! Names for culling type
const c8* const SceneNodeUpdateAbsNames[] =
{
"matrix",
"pos",
0
};
} // end namespace scene
} // end namespace irr
#endif

@ -7,6 +7,7 @@
#include "IAttributeExchangingObject.h" #include "IAttributeExchangingObject.h"
#include "ESceneNodeTypes.h" #include "ESceneNodeTypes.h"
#include "ESceneNodeUpdateAbs.h"
#include "ECullingTypes.h" #include "ECullingTypes.h"
#include "EDebugSceneTypes.h" #include "EDebugSceneTypes.h"
#include "ISceneNodeAnimator.h" #include "ISceneNodeAnimator.h"
@ -29,6 +30,7 @@ namespace scene
//! Typedef for list of scene node animators //! Typedef for list of scene node animators
typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList; typedef core::list<ISceneNodeAnimator*> ISceneNodeAnimatorList;
//! Scene node interface. //! Scene node interface.
/** A scene node is a node in the hierarchical scene graph. Every scene /** A scene node is a node in the hierarchical scene graph. Every scene
node may have children, which are also scene nodes. Children move node may have children, which are also scene nodes. Children move
@ -48,7 +50,8 @@ namespace scene
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)) const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f))
: RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale), : RelativeTranslation(position), RelativeRotation(rotation), RelativeScale(scale),
Parent(0), SceneManager(mgr), TriangleSelector(0), ID(id), Parent(0), SceneManager(mgr), TriangleSelector(0), ID(id),
AutomaticCullingState(EAC_BOX), DebugDataVisible(EDS_OFF), AutomaticCullingState(EAC_BOX), UpdateAbsolutePosBehavior(ESNUA_TRANSFORM_MATRIX),
DebugDataVisible(EDS_OFF),
IsVisible(true), IsDebugObject(false) IsVisible(true), IsDebugObject(false)
{ {
if (parent) if (parent)
@ -558,6 +561,18 @@ namespace scene
return AutomaticCullingState; return AutomaticCullingState;
} }
//! Set how updateAbsolutePosition calculates the absolute transformation matrix
void setUpdateAbsolutePosBehavior(ESCENE_NODE_UPDATE_ABS behavior)
{
UpdateAbsolutePosBehavior = behavior;
}
//! Get how updateAbsolutePosition calculates the absolute transformation matrix
ESCENE_NODE_UPDATE_ABS getUpdateAbsolutePosBehavior() const
{
return UpdateAbsolutePosBehavior;
}
//! Sets if debug data like bounding boxes should be drawn. //! Sets if debug data like bounding boxes should be drawn.
/** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE. /** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE.
@ -659,15 +674,24 @@ namespace scene
} }
//! Updates the absolute position based on the relative and the parents position //! Updates the absolute tranformation or position based on the relative and the parents transformation
/** Note: This does not recursively update the parents absolute positions, so if you have a deeper /** It's exact behavior can be controlled by setUpdateAbsolutePosBehavior.
Note: This does not recursively update the parents absolute positions, so if you have a deeper
hierarchy you might want to update the parents first.*/ hierarchy you might want to update the parents first.*/
virtual void updateAbsolutePosition() virtual void updateAbsolutePosition()
{ {
if (Parent) if (Parent)
{ {
AbsoluteTransformation = if ( UpdateAbsolutePosBehavior == ESNUA_TRANSFORM_MATRIX )
Parent->getAbsoluteTransformation() * getRelativeTransformation(); {
AbsoluteTransformation =
Parent->getAbsoluteTransformation() * getRelativeTransformation();
}
else if ( UpdateAbsolutePosBehavior == ESNUA_TRANSFORM_POSITION )
{
AbsoluteTransformation = getRelativeTransformation();
Parent->getAbsoluteTransformation().transformVect(reinterpret_cast<irr::core::vector3df&>(AbsoluteTransformation[12]));
}
} }
else else
AbsoluteTransformation = getRelativeTransformation(); AbsoluteTransformation = getRelativeTransformation();
@ -709,6 +733,7 @@ namespace scene
out->addVector3d("Scale", getScale() ); out->addVector3d("Scale", getScale() );
out->addBool("Visible", IsVisible ); out->addBool("Visible", IsVisible );
out->addEnum("AbsPosUpdate", (s32)UpdateAbsolutePosBehavior, SceneNodeUpdateAbsNames);
out->addInt("AutomaticCulling", AutomaticCullingState); out->addInt("AutomaticCulling", AutomaticCullingState);
out->addInt("DebugDataVisible", DebugDataVisible ); out->addInt("DebugDataVisible", DebugDataVisible );
out->addBool("IsDebugObject", IsDebugObject ); out->addBool("IsDebugObject", IsDebugObject );
@ -734,13 +759,17 @@ namespace scene
setScale(in->getAttributeAsVector3d("Scale", RelativeScale)); setScale(in->getAttributeAsVector3d("Scale", RelativeScale));
IsVisible = in->getAttributeAsBool("Visible", IsVisible); IsVisible = in->getAttributeAsBool("Visible", IsVisible);
UpdateAbsolutePosBehavior = (ESCENE_NODE_UPDATE_ABS)in->getAttributeAsEnumeration("AbsPosUpdate", SceneNodeUpdateAbsNames, (s32)UpdateAbsolutePosBehavior);
if (in->existsAttribute("AutomaticCulling")) if (in->existsAttribute("AutomaticCulling"))
{ {
// compatibility for older version, new one uses int's
const s32 tmpState = in->getAttributeAsEnumeration("AutomaticCulling", const s32 tmpState = in->getAttributeAsEnumeration("AutomaticCulling",
scene::AutomaticCullingNames); scene::AutomaticCullingNames);
if (tmpState != -1) if (tmpState != -1)
AutomaticCullingState = (u32)tmpState; AutomaticCullingState = (u32)tmpState;
else else
AutomaticCullingState = in->getAttributeAsInt("AutomaticCulling"); AutomaticCullingState = in->getAttributeAsInt("AutomaticCulling");
} }
@ -779,6 +808,7 @@ namespace scene
RelativeScale = toCopyFrom->RelativeScale; RelativeScale = toCopyFrom->RelativeScale;
ID = toCopyFrom->ID; ID = toCopyFrom->ID;
setTriangleSelector(toCopyFrom->TriangleSelector); setTriangleSelector(toCopyFrom->TriangleSelector);
UpdateAbsolutePosBehavior = toCopyFrom->UpdateAbsolutePosBehavior;
AutomaticCullingState = toCopyFrom->AutomaticCullingState; AutomaticCullingState = toCopyFrom->AutomaticCullingState;
DebugDataVisible = toCopyFrom->DebugDataVisible; DebugDataVisible = toCopyFrom->DebugDataVisible;
IsVisible = toCopyFrom->IsVisible; IsVisible = toCopyFrom->IsVisible;
@ -853,6 +883,9 @@ namespace scene
//! ID of the node. //! ID of the node.
s32 ID; s32 ID;
//! How updateAbsolutePosition calculates AbsoluteTransformation
ESCENE_NODE_UPDATE_ABS UpdateAbsolutePosBehavior;
//! Automatic culling state //! Automatic culling state
u32 AutomaticCullingState; u32 AutomaticCullingState;

@ -846,6 +846,7 @@
<ClInclude Include="..\..\include\EMaterialTypes.h" /> <ClInclude Include="..\..\include\EMaterialTypes.h" />
<ClInclude Include="..\..\include\EMeshBufferTypes.h" /> <ClInclude Include="..\..\include\EMeshBufferTypes.h" />
<ClInclude Include="..\..\include\EReadFileType.h" /> <ClInclude Include="..\..\include\EReadFileType.h" />
<ClInclude Include="..\..\include\ESceneNodeUpdateAbs.h" />
<ClInclude Include="..\..\include\EShaderTypes.h" /> <ClInclude Include="..\..\include\EShaderTypes.h" />
<ClInclude Include="..\..\include\fast_atof.h" /> <ClInclude Include="..\..\include\fast_atof.h" />
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h" /> <ClInclude Include="..\..\include\IAnimatedMeshMD3.h" />

@ -1441,6 +1441,9 @@
<ClInclude Include="..\..\include\EMeshBufferTypes.h"> <ClInclude Include="..\..\include\EMeshBufferTypes.h">
<Filter>include\scene</Filter> <Filter>include\scene</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\include\ESceneNodeUpdateAbs.h">
<Filter>include\scene</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\changes.txt"> <None Include="..\..\changes.txt">

Binary file not shown.

Binary file not shown.

@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed. Tests finished. 72 tests of 72 passed.
Compiled as DEBUG Compiled as DEBUG
Test suite pass at GMT Sat Sep 24 13:51:42 2022 Test suite pass at GMT Thu Sep 29 16:32:30 2022