# ifndef Magnum_Trade_SceneData_h
# define Magnum_Trade_SceneData_h
/*
This file is part of Magnum .
Copyright © 2010 , 2011 , 2012 , 2013 , 2014 , 2015 , 2016 , 2017 , 2018 , 2019 ,
2020 , 2021 Vladimír Vondruš < mosra @ centrum . cz >
Permission is hereby granted , free of charge , to any person obtaining a
copy of this software and associated documentation files ( the " Software " ) ,
to deal in the Software without restriction , including without limitation
the rights to use , copy , modify , merge , publish , distribute , sublicense ,
and / or sell copies of the Software , and to permit persons to whom the
Software is furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE .
*/
/** @file
* @ brief Class @ ref Magnum : : Trade : : SceneData , @ ref Magnum : : Trade : : SceneFieldData , enum @ ref Magnum : : Trade : : SceneMappingType , @ ref Magnum : : Trade : : SceneField , @ ref Magnum : : Trade : : SceneFieldType , @ ref Magnum : : Trade : : SceneFieldFlag , enum set @ ref Magnum : : Trade : : SceneFieldFlags , function @ ref Magnum : : sceneMappingTypeSize ( ) , @ ref Magnum : : sceneMappingTypeAlignment ( ) , @ ref Magnum : : sceneFieldTypeSize ( ) , @ ref Magnum : : sceneFieldTypeAlignment ( ) , @ ref Magnum : : Trade : : isSceneFieldCustom ( ) , @ ref Magnum : : sceneFieldCustom ( )
*/
# include <Corrade/Containers/Array.h>
# include <Corrade/Containers/StridedArrayView.h>
# include "Magnum/Trade/Data.h"
# include "Magnum/Trade/Trade.h"
# include "Magnum/Trade/visibility.h"
# ifdef MAGNUM_BUILD_DEPRECATED
# include <Corrade/Utility/StlForwardVector.h>
# include <Corrade/Utility/Macros.h>
# endif
namespace Magnum { namespace Trade {
/**
@ brief Scene object mapping type
@ m_since_latest
Type used for mapping fields to corresponding objects . Unlike
@ ref SceneFieldType that is different for different fields , the object mapping
type is the same for all fields , and is guaranteed to be large enough to fit
@ ref SceneData : : mappingBound ( ) objects .
@ see @ ref SceneData : : mappingType ( ) , @ ref sceneMappingTypeSize ( ) ,
@ ref sceneMappingTypeAlignment ( )
*/
enum class SceneMappingType : UnsignedByte {
/* Zero used for an invalid value */
UnsignedByte = 1 , /**< @relativeref{Magnum,UnsignedByte} */
UnsignedShort , /**< @relativeref{Magnum,UnsignedShort} */
UnsignedInt , /**< @relativeref{Magnum,UnsignedInt} */
UnsignedLong /**< @relativeref{Magnum,UnsignedLong} */
} ;
/**
@ debugoperatorenum { SceneMappingType }
@ m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug & operator < < ( Debug & debug , SceneMappingType value ) ;
/**
@ brief Size of given scene object mapping type
@ m_since_latest
@ see @ ref sceneMappingTypeAlignment ( )
*/
MAGNUM_TRADE_EXPORT UnsignedInt sceneMappingTypeSize ( SceneMappingType type ) ;
/**
@ brief Alignment of given scene object mapping type
@ m_since_latest
Returns the same value as @ ref sceneMappingTypeSize ( ) .
*/
MAGNUM_TRADE_EXPORT UnsignedInt sceneMappingTypeAlignment ( SceneMappingType type ) ;
/**
@ brief Scene field name
@ m_since_latest
See @ ref SceneData for more information .
@ see @ ref SceneFieldData , @ ref SceneFieldType ,
@ ref AbstractImporter : : sceneFieldForName ( ) ,
@ ref AbstractImporter : : sceneFieldName ( )
*/
enum class SceneField : UnsignedInt {
/* Zero used for an invalid value */
/**
Trade: remove the useless indirection from SceneField::Parent.
This got originally added as some sort of a kludge to make it easy to go
to the parent transformation, assuming Parent and Transformation share
the same object mapping:
parentTransformation = transformations[parents[i]]
But after some ACTUAL REAL WORLD use, I realized that there's often a
set of objects that have a Parent defined, and then another, completely
disjoint, set of objects that have a transformation (for example certain
nodes having no transformation at all because it's an identity). And so
this parent indirection is not only useless, but in fact an additional
complication. Let's say we make a map of the transformations, where
transformationMap[i] is a transformation for object i:
transformationMap = {}
for j in range(len(transformations)):
transformationMap[transformationObject[j]] = transformation[j]
Then, with *no* assumptions about shared object mapping, the indirection
would cause parent transformation retrieval to look like this:
parentTransformation = transformationMap[parentObjects[parents[i]]
While *without* the indirection, it'd be just
parentTransformation = transformationMap[parents[i]]
5 years ago
* Parent object . Type is usually @ ref SceneFieldType : : Int , but can be also
* any of @ relativeref { SceneFieldType , Byte } ,
* @ relativeref { SceneFieldType , Short } or a
* @ relativeref { SceneFieldType , Long } . A value of @ cpp - 1 @ ce means there ' s
* no parent . An object should have only one parent , altough this isn ' t
* enforced in any way , and which of the duplicate fields gets used is not
* defined .
* @ see @ ref SceneData : : parentsAsArray ( ) , @ ref SceneData : : parentFor ( ) ,
* @ ref SceneData : : childrenFor ( )
*/
Parent = 1 ,
/**
* Transformation . Type is usually @ ref SceneFieldType : : Matrix3x3 for 2 D
* and @ ref SceneFieldType : : Matrix4x4 for 3 D , but can be also any of
* @ relativeref { SceneFieldType , Matrix3x3d } ,
* @ relativeref { SceneFieldType , Matrix3x2 } or
* @ relativeref { SceneFieldType , Matrix3x2d } ( with the bottom row implicitly
* assumed to be @ f $ \ begin { pmatrix } 0 & 0 & 1 \ end { pmatrix } @ f $ ) ,
* @ relativeref { SceneFieldType , DualComplex } or
* @ relativeref { SceneFieldType , DualComplexd } for 2 D and
* @ relativeref { SceneFieldType , Matrix4x4d } ,
* @ relativeref { SceneFieldType , Matrix4x3 } or
* @ relativeref { SceneFieldType , Matrix4x3d } ( with the bottom row implicitly
* assumed to be @ f $ \ begin { pmatrix } 0 & 0 & 0 & 1 \ end { pmatrix } @ f $ ) ,
* @ relativeref { SceneFieldType , DualQuaternion } or
* @ relativeref { SceneFieldType , DualQuaterniond } for 3 D . An object should
* have only one transformation , altough this isn ' t enforced in any way ,
* and which of the duplicate fields gets used is not defined .
*
* The transformation can be also represented by separate
* @ ref SceneField : : Translation , @ ref SceneField : : Rotation and
* @ ref SceneField : : Scaling fields . All present transformation - related
* fields are expected to have the same dimensionality - - - either all 2 D or
* all 3 D . If both @ ref SceneField : : Transformation and TRS fields are
* specified , it ' s expected that all objects that have TRS fields have a
* combined transformation field as well , and
* @ ref SceneData : : transformations2DAsArray ( ) /
* @ ref SceneData : : transformations3DAsArray ( ) then takes into account only
* the combined transformation field . TRS fields can however be specified
* only for a subset of transformed objects , useful for example when only
* certain objects have these properties animated .
* @ see @ ref SceneData : : is2D ( ) , @ ref SceneData : : is3D ( ) ,
* @ ref SceneData : : transformations2DAsArray ( ) ,
* @ ref SceneData : : transformations3DAsArray ( ) ,
* @ ref SceneData : : transformation2DFor ( ) ,
* @ ref SceneData : : transformation3DFor ( )
*/
Transformation ,
/**
* Translation . Type is usually @ ref SceneFieldType : : Vector2 for 2 D and
* @ ref SceneFieldType : : Vector3 for 3 D , but can be also any of
* @ relativeref { SceneFieldType , Vector2d } for 2 D and
* @ relativeref { SceneFieldType , Vector3d } for 3 D . An object should
* have only one translation , altough this isn ' t enforced in any way ,
* and which of the duplicate fields gets used is not defined .
*
* The translation field usually is ( but doesn ' t have to be ) complemented
* by a @ ref SceneField : : Rotation and @ ref SceneField : : Scaling , which , if
* present , are expected to all share the same object mapping view and have
* the same dimensionality , either all 2 D or all 3 D . The TRS
* components can either completely replace @ ref SceneField : : Transformation
* or be provided just for a subset of it - - - see its documentation for
* details .
* @ see @ ref SceneData : : is2D ( ) , @ ref SceneData : : is3D ( ) ,
* @ ref SceneData : : transformations2DAsArray ( ) ,
* @ ref SceneData : : transformations3DAsArray ( ) ,
* @ ref SceneData : : transformation2DFor ( ) ,
* @ ref SceneData : : transformation3DFor ( ) ,
* @ ref SceneData : : translationsRotationsScalings2DAsArray ( ) ,
* @ ref SceneData : : translationsRotationsScalings3DAsArray ( ) ,
* @ ref SceneData : : translationRotationScaling2DFor ( ) ,
* @ ref SceneData : : translationRotationScaling3DFor ( )
*/
Translation ,
/**
* Rotation . Type is usually @ ref SceneFieldType : : Complex for 2 D and
* @ ref SceneFieldType : : Quaternion for 3 D , but can be also any of
* @ relativeref { SceneFieldType , Complexd } for 2 D and
* @ relativeref { SceneFieldType , Quaterniond } for 3 D . An object should have
* only one rotation , altough this isn ' t enforced in any way , and which of
* the duplicate fields gets used is not defined .
*
* The rotation field usually is ( but doesn ' t have to be ) complemented by a
* @ ref SceneField : : Translation and @ ref SceneField : : Scaling , which , if
* present , are expected to all share the same object mapping view and have
* the same dimensionality , either all 2 D or all 3 D . The TRS
* components can either completely replace @ ref SceneField : : Transformation
* or be provided just for a subset of it - - - see its documentation for
* details .
* @ see @ ref SceneData : : is2D ( ) , @ ref SceneData : : is3D ( ) ,
* @ ref SceneData : : transformations2DAsArray ( ) ,
* @ ref SceneData : : transformations3DAsArray ( ) ,
* @ ref SceneData : : transformation2DFor ( ) ,
* @ ref SceneData : : transformation3DFor ( ) ,
* @ ref SceneData : : translationsRotationsScalings2DAsArray ( ) ,
* @ ref SceneData : : translationsRotationsScalings3DAsArray ( ) ,
* @ ref SceneData : : translationRotationScaling2DFor ( ) ,
* @ ref SceneData : : translationRotationScaling3DFor ( )
*/
Rotation ,
/**
* Scaling . Type is usually @ ref SceneFieldType : : Vector2 for 2 D and
* @ ref SceneFieldType : : Vector3 for 3 D , but can be also any of
* @ relativeref { SceneFieldType , Vector2d } for 2 D and
* @ relativeref { SceneFieldType , Vector3d } for 3 D . An object should
* have only one scaling , altough this isn ' t enforced in any way , and which
* of the duplicate fields gets used is not defined .
*
* The scaling field usually is ( but doesn ' t have to be ) complemented by a
* @ ref SceneField : : Translation and @ ref SceneField : : Rotation , which , if
* present , are expected to all share the same object mapping view and have
* the same dimensionality , either all 2 D or all 3 D . The TRS
* components can either completely replace @ ref SceneField : : Transformation
* or be provided just for a subset of it - - - see its documentation for
* details .
* @ see @ ref SceneData : : is2D ( ) , @ ref SceneData : : is3D ( ) ,
* @ ref SceneData : : transformations2DAsArray ( ) ,
* @ ref SceneData : : transformations3DAsArray ( ) ,
* @ ref SceneData : : transformation2DFor ( ) ,
* @ ref SceneData : : transformation3DFor ( ) ,
* @ ref SceneData : : translationsRotationsScalings2DAsArray ( ) ,
* @ ref SceneData : : translationsRotationsScalings3DAsArray ( ) ,
* @ ref SceneData : : translationRotationScaling2DFor ( ) ,
* @ ref SceneData : : translationRotationScaling3DFor ( )
*/
Scaling ,
/**
* ID of a mesh associated with this object , corresponding to the ID passed
* to @ ref AbstractImporter : : mesh ( ) . Type is usually
* @ ref SceneFieldType : : UnsignedInt , but can be also any of
* @ relativeref { SceneFieldType , UnsignedByte } or
* @ relativeref { SceneFieldType , UnsignedShort } . An object can have multiple
* meshes associated .
*
* Usually complemented with a @ ref SceneField : : MeshMaterial , although not
* required . If present , both should share the same object mapping view .
* Objects with multiple meshes then have the Nth mesh associated with the
* Nth material .
* @ see @ ref SceneData : : meshesMaterialsAsArray ( ) ,
* @ ref SceneData : : meshesMaterialsFor ( )
*/
Mesh ,
/**
* ID of a material for a @ ref SceneField : : Mesh , corresponding to the ID
* passed to @ ref AbstractImporter : : material ( ) or @ cpp - 1 @ ce if the mesh
* has no material associated . Type is usually @ ref SceneFieldType : : Int ,
* but can be also any of @ relativeref { SceneFieldType , Byte } or
* @ relativeref { SceneFieldType , Short } . Expected to share the
* object mapping view with @ ref SceneField : : Mesh .
* @ see @ ref SceneData : : meshesMaterialsAsArray ( ) ,
* @ ref SceneData : : meshesMaterialsFor ( )
*/
MeshMaterial ,
/**
* ID of a light associated with this object , corresponding to the ID
* passed to @ ref AbstractImporter : : light ( ) . Type is usually
* @ ref SceneFieldType : : UnsignedInt , but can be also any of
* @ relativeref { SceneFieldType , UnsignedByte } or
* @ relativeref { SceneFieldType , UnsignedShort } . An object can have multiple
* lights associated .
* @ see @ ref SceneData : : lightsAsArray ( ) , @ ref SceneData : : lightsFor ( )
*/
Light ,
/**
* ID of a camera associated with this object , corresponding to the ID
* passed to @ ref AbstractImporter : : camera ( ) . Type is usually
* @ ref SceneFieldType : : UnsignedInt , but can be also any of
* @ relativeref { SceneFieldType , UnsignedByte } or
* @ relativeref { SceneFieldType , UnsignedShort } . An object can have multiple
* cameras associated .
* @ see @ ref SceneData : : camerasAsArray ( ) , @ ref SceneData : : camerasFor ( )
*/
Camera ,
/**
* ID of a skin associated with this object , corresponding to the ID
* passed to @ ref AbstractImporter : : skin2D ( ) or
* @ ref AbstractImporter : : skin3D ( ) , depending on whether the scene has a 2 D
* or 3 D transformation . Type is usually @ ref SceneFieldType : : UnsignedInt ,
* but can be also any of @ relativeref { SceneFieldType , UnsignedByte } or
* @ relativeref { SceneFieldType , UnsignedShort } . An object can have multiple
* skins associated .
* @ see @ ref SceneData : : is2D ( ) , @ ref SceneData : : is3D ( ) ,
* @ ref SceneData : : skinsAsArray ( ) , @ ref SceneData : : skinsFor ( )
*/
Skin ,
/**
* Importer state for given object , per - object counterpart to
* scene - specific @ ref SceneData : : importerState ( ) . Type is usually
* @ ref SceneFieldType : : Pointer but can be also
* @ ref SceneFieldType : : MutablePointer . An object should have only one
* importer state , altough this isn ' t enforced in any way , and which of the
* duplicate fields gets used is not defined .
* @ see @ ref SceneData : : importerStateAsArray ( ) ,
* @ ref SceneData : : importerStateFor ( )
*/
ImporterState ,
/**
* This and all higher values are for importer - specific fields . Can be
* of any type . See documentation of a particular importer for details .
*
* While it ' s unlikely to have billions of custom fields , the enum
* intentionally reserves a full 31 - bit range to avoid the need to remap
* field identifiers coming from 3 rd party ECS frameworks , for example .
* @ see @ ref isSceneFieldCustom ( ) , @ ref sceneFieldCustom ( SceneField ) ,
* @ ref sceneFieldCustom ( UnsignedInt )
*/
Custom = 0x80000000u
} ;
/**
@ debugoperatorenum { SceneField }
@ m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug & operator < < ( Debug & debug , SceneField value ) ;
/**
@ brief Whether a scene field is custom
@ m_since_latest
Returns @ cpp true @ ce if @ p name has a value larger or equal to
@ ref SceneField : : Custom , @ cpp false @ ce otherwise .
@ see @ ref sceneFieldCustom ( UnsignedInt ) , @ ref sceneFieldCustom ( SceneField )
*/
constexpr bool isSceneFieldCustom ( SceneField name ) {
return UnsignedInt ( name ) > = UnsignedInt ( SceneField : : Custom ) ;
}
/**
@ brief Create a custom scene field
@ m_since_latest
Returns a custom scene field with index @ p id . The index is expected to be less
than the value of @ ref SceneField : : Custom . Use @ ref sceneFieldCustom ( SceneField )
to get the index back .
*/
/* Constexpr so it's usable for creating compile-time SceneFieldData
instances */
constexpr SceneField sceneFieldCustom ( UnsignedInt id ) {
return CORRADE_CONSTEXPR_ASSERT ( id < UnsignedInt ( SceneField : : Custom ) ,
" Trade::sceneFieldCustom(): index " < < id < < " too large " ) ,
SceneField ( UnsignedInt ( SceneField : : Custom ) + id ) ;
}
/**
@ brief Get index of a custom scene field
@ m_since_latest
Inverse to @ ref sceneFieldCustom ( UnsignedInt ) . Expects that the field is
custom .
@ see @ ref isSceneFieldCustom ( )
*/
constexpr UnsignedInt sceneFieldCustom ( SceneField name ) {
return CORRADE_CONSTEXPR_ASSERT ( isSceneFieldCustom ( name ) ,
" Trade::sceneFieldCustom(): " < < name < < " is not custom " ) ,
UnsignedInt ( name ) - UnsignedInt ( SceneField : : Custom ) ;
}
/**
@ brief Scene field type
@ m_since_latest
A type in which a @ ref SceneField is stored . See @ ref SceneData for more
information .
@ see @ ref SceneFieldData , @ ref sceneFieldTypeSize ( ) ,
@ ref sceneFieldTypeAlignment ( )
*/
enum class SceneFieldType : UnsignedShort {
/* Zero used for an invalid value */
/* 1 reserved for Bool (Bit?), which needs [Strided]BitArray[View] first */
Float = 2 , /**< @relativeref{Magnum,Float} */
Half , /**< @relativeref{Magnum,Half} */
Double , /**< @relativeref{Magnum,Double} */
UnsignedByte , /**< @relativeref{Magnum,UnsignedByte} */
Byte , /**< @relativeref{Magnum,Byte} */
UnsignedShort , /**< @relativeref{Magnum,UnsignedShort} */
Short , /**< @relativeref{Magnum,Short} */
UnsignedInt , /**< @relativeref{Magnum,UnsignedInt} */
Int , /**< @relativeref{Magnum,Int} */
UnsignedLong , /**< @relativeref{Magnum,UnsignedLong} */
Long , /**< @relativeref{Magnum,Long} */
Vector2 , /**< @relativeref{Magnum,Vector2} */
Vector2h , /**< @relativeref{Magnum,Vector2h} */
Vector2d , /**< @relativeref{Magnum,Vector2d} */
Vector2ub , /**< @relativeref{Magnum,Vector2ub} */
Vector2b , /**< @relativeref{Magnum,Vector2b} */
Vector2us , /**< @relativeref{Magnum,Vector2us} */
Vector2s , /**< @relativeref{Magnum,Vector2s} */
Vector2ui , /**< @relativeref{Magnum,Vector2ui} */
Vector2i , /**< @relativeref{Magnum,Vector2i} */
Vector3 , /**< @relativeref{Magnum,Vector3} */
Vector3h , /**< @relativeref{Magnum,Vector3h} */
Vector3d , /**< @relativeref{Magnum,Vector3d} */
Vector3ub , /**< @relativeref{Magnum,Vector3ub} */
Vector3b , /**< @relativeref{Magnum,Vector3b} */
Vector3us , /**< @relativeref{Magnum,Vector3us} */
Vector3s , /**< @relativeref{Magnum,Vector3s} */
Vector3ui , /**< @relativeref{Magnum,Vector3ui} */
Vector3i , /**< @relativeref{Magnum,Vector3i} */
Vector4 , /**< @relativeref{Magnum,Vector4} */
Vector4h , /**< @relativeref{Magnum,Vector4h} */
Vector4d , /**< @relativeref{Magnum,Vector4d} */
Vector4ub , /**< @relativeref{Magnum,Vector4ub} */
Vector4b , /**< @relativeref{Magnum,Vector4b} */
Vector4us , /**< @relativeref{Magnum,Vector4us} */
Vector4s , /**< @relativeref{Magnum,Vector4s} */
Vector4ui , /**< @relativeref{Magnum,Vector4ui} */
Vector4i , /**< @relativeref{Magnum,Vector4i} */
Matrix2x2 , /**< @relativeref{Magnum,Matrix2x2} */
Matrix2x2h , /**< @relativeref{Magnum,Matrix2x2h} */
Matrix2x2d , /**< @relativeref{Magnum,Matrix2x2d} */
Matrix2x3 , /**< @relativeref{Magnum,Matrix2x3} */
Matrix2x3h , /**< @relativeref{Magnum,Matrix2x3h} */
Matrix2x3d , /**< @relativeref{Magnum,Matrix2x3d} */
Matrix2x4 , /**< @relativeref{Magnum,Matrix2x4} */
Matrix2x4h , /**< @relativeref{Magnum,Matrix2x4h} */
Matrix2x4d , /**< @relativeref{Magnum,Matrix2x4d} */
Matrix3x2 , /**< @relativeref{Magnum,Matrix3x2} */
Matrix3x2h , /**< @relativeref{Magnum,Matrix3x2h} */
Matrix3x2d , /**< @relativeref{Magnum,Matrix3x2d} */
Matrix3x3 , /**< @relativeref{Magnum,Matrix3x3} */
Matrix3x3h , /**< @relativeref{Magnum,Matrix3x3h} */
Matrix3x3d , /**< @relativeref{Magnum,Matrix3x3d} */
Matrix3x4 , /**< @relativeref{Magnum,Matrix3x4} */
Matrix3x4h , /**< @relativeref{Magnum,Matrix3x4h} */
Matrix3x4d , /**< @relativeref{Magnum,Matrix3x4d} */
Matrix4x2 , /**< @relativeref{Magnum,Matrix4x2} */
Matrix4x2h , /**< @relativeref{Magnum,Matrix4x2h} */
Matrix4x2d , /**< @relativeref{Magnum,Matrix4x2d} */
Matrix4x3 , /**< @relativeref{Magnum,Matrix4x3} */
Matrix4x3h , /**< @relativeref{Magnum,Matrix4x3h} */
Matrix4x3d , /**< @relativeref{Magnum,Matrix4x3d} */
Matrix4x4 , /**< @relativeref{Magnum,Matrix4x4} */
Matrix4x4h , /**< @relativeref{Magnum,Matrix4x4h} */
Matrix4x4d , /**< @relativeref{Magnum,Matrix4x4d} */
Range1D , /**< @relativeref{Magnum,Range1D} */
Range1Dh , /**< @relativeref{Magnum,Range1Dh} */
Range1Dd , /**< @relativeref{Magnum,Range1Dd} */
Range1Di , /**< @relativeref{Magnum,Range1Di} */
Range2D , /**< @relativeref{Magnum,Range2D} */
Range2Dh , /**< @relativeref{Magnum,Range2Dh} */
Range2Dd , /**< @relativeref{Magnum,Range2Dd} */
Range2Di , /**< @relativeref{Magnum,Range2Di} */
Range3D , /**< @relativeref{Magnum,Range3D} */
Range3Dh , /**< @relativeref{Magnum,Range3Dh} */
Range3Dd , /**< @relativeref{Magnum,Range3Dd} */
Range3Di , /**< @relativeref{Magnum,Range3Di} */
Complex , /**< @relativeref{Magnum,Complex} */
Complexd , /**< @relativeref{Magnum,Complexd} */
DualComplex , /**< @relativeref{Magnum,DualComplex} */
DualComplexd , /**< @relativeref{Magnum,DualComplexd} */
Quaternion , /**< @relativeref{Magnum,Quaternion} */
Quaterniond , /**< @relativeref{Magnum,Quaterniond} */
DualQuaternion , /**< @relativeref{Magnum,DualQuaternion} */
DualQuaterniond , /**< @relativeref{Magnum,DualQuaterniond} */
Deg , /**< @relativeref{Magnum,Deg} */
Degh , /**< @relativeref{Magnum,Degh} */
Degd , /**< @relativeref{Magnum,Degh} */
Rad , /**< @relativeref{Magnum,Rad} */
Radh , /**< @relativeref{Magnum,Radh} */
Radd , /**< @relativeref{Magnum,Radd} */
/**
* @ cpp const void * @ ce , type is not preserved . For convenience it ' s
* possible to retrieve the value by calling @ cpp field < const T * > ( ) @ ce
* with an arbitrary ` T ` but the user has to ensure the type is correct .
*/
Pointer ,
/**
* @ cpp void * @ ce , type is not preserved . For convenience it ' s possible to
* retrieve the value by calling @ cpp field < T * > ( ) @ ce with an arbitrary ` T `
* but the user has to ensure the type is correct .
*/
MutablePointer ,
} ;
/**
@ debugoperatorenum { SceneFieldType }
@ m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug & operator < < ( Debug & debug , SceneFieldType value ) ;
/**
@ brief Size of given scene field type
@ m_since_latest
@ see @ ref sceneFieldTypeAlignment ( )
*/
MAGNUM_TRADE_EXPORT UnsignedInt sceneFieldTypeSize ( SceneFieldType type ) ;
/**
@ brief Alignment of given scene field type
@ m_since_latest
@ see @ ref sceneFieldTypeSize ( )
*/
MAGNUM_TRADE_EXPORT UnsignedInt sceneFieldTypeAlignment ( SceneFieldType type ) ;
/**
@ brief Scene field flag
@ m_since_latest
@ see @ ref SceneFieldFlags , @ ref SceneFieldData , @ ref SceneFieldData : : flags ( ) ,
@ ref SceneData : : fieldFlags ( )
*/
enum class SceneFieldFlag : UnsignedByte {
/**
* The field is offset - only , i . e . doesn ' t contain the data views directly
* but referes to unspecified external data . Set implicitly by
* the @ ref SceneFieldData : : SceneFieldData ( SceneField , std : : size_t , SceneMappingType , std : : size_t , std : : ptrdiff_t , SceneFieldType , std : : size_t , std : : ptrdiff_t , UnsignedShort , SceneFieldFlags )
* constructor , can ' t be used for any other constructor .
* @ see @ ref SceneFieldData : : mappingData ( Containers : : ArrayView < const void > ) const ,
* @ ref SceneFieldData : : fieldData ( Containers : : ArrayView < const void > ) const
*/
OffsetOnly = 1 < < 0 ,
/**
* The field has an ordered object mapping , i . e . a monotonically increasing
* sequence . Object IDs in fields marked with this flag can be looked up
* with an @ f $ \ mathcal { O } ( \ log { } n ) @ f $ complexity , gaps and duplicates
* are possible .
*
* Note that validity of the object mapping data isn ' t checked in any way
* and if the data doesn ' t correspond to rules of the flag , queries such
* as @ ref SceneData : : findFieldObjectOffset ( ) may return a wrong value .
*
* If a field has neither this nor the @ ref SceneFieldFlag : : ImplicitMapping
* flag , it ' s assumed to be unordered , with an
* @ f $ \ mathcal { O } ( n ) @ f $ lookup complexity .
*/
OrderedMapping = 1 < < 1 ,
/**
* The field has an implicit object mapping , i . e . a contiguous sequence
* from 0 up to size of the field . A superset of
* @ ref SceneFieldFlag : : OrderedMapping . Object IDs in fields marked with
* this flag can be looked up with an @ f $ \ mathcal { O } ( 1 ) @ f $ complexity ,
* but the field is restricted to exactly one value for each object .
*
* Note that validity of the object mapping data isn ' t checked in any way
* and if the data doesn ' t correspond to rules of the flag , queries such
* as @ ref SceneData : : findFieldObjectOffset ( ) may return a wrong value .
*
* If a field has neither this nor the @ ref SceneFieldFlag : : OrderedMapping
* flag , it ' s assumed to be unordered , with an
* @ f $ \ mathcal { O } ( n ) @ f $ lookup complexity .
*/
ImplicitMapping = ( 1 < < 2 ) | OrderedMapping ,
} ;
/**
@ debugoperatorenum { SceneFieldFlag }
@ m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug & operator < < ( Debug & debug , SceneFieldFlag value ) ;
/**
@ brief Scene field flags
@ m_since_latest
@ see @ ref SceneFieldData : : flags ( ) , @ ref SceneData : : fieldFlags ( )
*/
typedef Containers : : EnumSet < SceneFieldFlag > SceneFieldFlags ;
CORRADE_ENUMSET_OPERATORS ( SceneFieldFlags )
/**
@ debugoperatorenum { SceneFieldFlags }
@ m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug & operator < < ( Debug & debug , SceneFieldFlags value ) ;
/**
@ brief Scene field data
@ m_since_latest
Convenience type for populating @ ref SceneData , see its documentation for an
introduction .
@ section Trade - SceneFieldData - usage Usage
The most straightforward usage is constructing an instance from a
@ ref SceneField and a strided view for the field data and object mapping . The
@ ref SceneMappingType and @ ref SceneFieldType get inferred from the view types :
@ snippet MagnumTrade . cpp SceneFieldData - usage
Alternatively , you can pass typeless @ cpp const void @ ce or 2 D views and supply
@ ref SceneMappingType and @ ref SceneFieldType explicitly .
@ subsection Trade - SceneFieldData - usage - offset - only Offset - only field data
If the actual field / object data location is not known yet , the instance can
be created as " offset-only " , meaning the actual view gets created only later
when passed to a @ ref SceneData instance with a concrete data array . This is
useful mainly to avoid pointer patching during data serialization , less so when
the data layout is static ( and thus can be defined at compile time ) , but the
actual data is allocated / populated at runtime :
@ snippet MagnumTrade . cpp SceneFieldData - usage - offset - only
Offset - only fields are marked with @ ref SceneFieldFlag : : OffsetOnly in
@ ref flags ( ) .
@ subsection Trade - SceneFieldData - usage - object - mapping Ordered and implicit object mapping
If you can guarantee the object mapping field is monotonically non - decreasing ,
it ' s recommended to annotate it with @ ref SceneFieldFlag : : OrderedMapping . This
makes certain convenience APIs such as @ ref SceneData : : findFieldObjectOffset ( )
or e . g . @ relativeref { SceneData , transformation3DFor ( ) } perform the lookup in
@ f $ \ mathcal { O } ( \ log { } n ) @ f $ instead of @ f $ \ mathcal { O } ( n ) @ f $ . Data consuming
algorithms on the application side can then also adapt based on what flags are
present in @ ref SceneData : : fieldFlags ( ) .
In some cases the object mapping is even implicit , i . e . the first entry of the
field specifying data for object @ cpp 0 @ ce , second entry for object
@ cpp 1 @ ce , third for object @ cpp 2 @ ce and so on . You can annotate such fields
with @ ref SceneFieldFlag : : ImplicitMapping , which is a superset of
@ relativeref { SceneFieldFlag , OrderedMapping } .
*/
class MAGNUM_TRADE_EXPORT SceneFieldData {
public :
/**
* @ brief Default constructor
*
* Leaves contents at unspecified values . Provided as a convenience for
* initialization of the field array for @ ref SceneData , expected to be
* replaced with concrete values later .
*/
constexpr explicit SceneFieldData ( ) noexcept : _size { } , _name { } , _flags { } , _mappingType { } , _mappingStride { } , _mappingData { } , _fieldType { } , _fieldStride { } , _fieldArraySize { } , _fieldData { } { }
/**
* @ brief Type - erased constructor
* @ param name Field name
* @ param mappingType Object mapping type
* @ param mappingData Object mapping data
* @ param fieldType Field type
* @ param fieldData Field data
* @ param fieldArraySize Field array size . Use @ cpp 0 @ ce for
* non - array fields .
* @ param flags Field flags .
* @ ref SceneFieldFlag : : OffsetOnly is not allowed here .
*
* Expects that @ p mappingData and @ p fieldData have the same size ,
* @ p fieldType corresponds to @ p name and @ p fieldArraySize is zero
* for builtin fields .
*/
constexpr explicit SceneFieldData ( SceneField name , SceneMappingType mappingType , const Containers : : StridedArrayView1D < const void > & mappingData , SceneFieldType fieldType , const Containers : : StridedArrayView1D < const void > & fieldData , UnsignedShort fieldArraySize = 0 , SceneFieldFlags flags = { } ) noexcept ;
/** @overload */
constexpr explicit SceneFieldData ( SceneField name , SceneMappingType mappingType , const Containers : : StridedArrayView1D < const void > & mappingData , SceneFieldType fieldType , const Containers : : StridedArrayView1D < const void > & fieldData , SceneFieldFlags flags ) noexcept : SceneFieldData { name , mappingType , mappingData , fieldType , fieldData , 0 , flags } { }
/**
* @ brief Constructor
* @ param name Field name
* @ param mappingData Object mapping data
* @ param fieldType Field type
* @ param fieldData Field data
* @ param fieldArraySize Field array size . Use @ cpp 0 @ ce for
* non - array fields .
* @ param flags Field flags .
* @ ref SceneFieldFlag : : OffsetOnly is not allowed here .
*
* Expects that @ p mappingData and @ p fieldData have the same size in
* the first dimension , that the second dimension of @ p mappingData is
* contiguous and its size is either 1 , 2 , 4 or 8 , corresponding to one
* of the @ ref SceneMappingType values , that the second dimension of
* @ p fieldData is contiguous and its size matches @ p fieldType and
* @ p fieldArraySize and that @ p fieldType corresponds to @ p name and
* @ p fieldArraySize is zero for builtin attributes .
*/
explicit SceneFieldData ( SceneField name , const Containers : : StridedArrayView2D < const char > & mappingData , SceneFieldType fieldType , const Containers : : StridedArrayView2D < const char > & fieldData , UnsignedShort fieldArraySize = 0 , SceneFieldFlags flags = { } ) noexcept ;
/** @overload */
explicit SceneFieldData ( SceneField name , const Containers : : StridedArrayView2D < const char > & mappingData , SceneFieldType fieldType , const Containers : : StridedArrayView2D < const char > & fieldData , SceneFieldFlags flags ) noexcept : SceneFieldData { name , mappingData , fieldType , fieldData , 0 , flags } { }
/**
* @ brief Constructor
* @ param name Field name
* @ param mappingData Object mapping data
* @ param fieldData Field data
* @ param flags Field flags . @ ref SceneFieldFlag : : OffsetOnly is
* not allowed here .
*
* Detects @ ref SceneMappingType based on @ p T and @ ref SceneFieldType
* based on @ p U and calls @ ref SceneFieldData ( SceneField , SceneMappingType , const Containers : : StridedArrayView1D < const void > & , SceneFieldType , const Containers : : StridedArrayView1D < const void > & , UnsignedShort , SceneFieldFlags ) .
* For all types known by Magnum , the detected @ ref SceneFieldType is
* of the same name as the type ( so e . g . @ relativeref { Magnum , Vector3ui }
* gets recognized as @ ref SceneFieldType : : Vector3ui ) .
*/
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : StridedArrayView1D < T > & mappingData , const Containers : : StridedArrayView1D < U > & fieldData , SceneFieldFlags flags = { } ) noexcept ;
/** @overload */
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : StridedArrayView1D < T > & mappingData , const Containers : : ArrayView < U > & fieldData , SceneFieldFlags flags = { } ) noexcept : SceneFieldData { name , mappingData , Containers : : stridedArrayView ( fieldData ) , flags } { }
/** @overload */
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : ArrayView < T > & mappingData , const Containers : : StridedArrayView1D < U > & fieldData , SceneFieldFlags flags = { } ) noexcept : SceneFieldData { name , Containers : : stridedArrayView ( mappingData ) , fieldData , flags } { }
/** @overload */
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : ArrayView < T > & mappingData , const Containers : : ArrayView < U > & fieldData , SceneFieldFlags flags = { } ) noexcept : SceneFieldData { name , Containers : : stridedArrayView ( mappingData ) , Containers : : stridedArrayView ( fieldData ) , flags } { }
/**
* @ brief Construct an array field
* @ param name Field name
* @ param mappingData Object mapping data
* @ param fieldData Field data
* @ param flags Field flags . @ ref SceneFieldFlag : : OffsetOnly is
* not allowed here .
*
* Detects @ ref SceneMappingType based on @ p T and @ ref SceneFieldType
* based on @ p U and calls @ ref SceneFieldData ( SceneField , SceneMappingType , const Containers : : StridedArrayView1D < const void > & , SceneFieldType , const Containers : : StridedArrayView1D < const void > & , UnsignedShort , SceneFieldFlags )
* with the @ p fieldData second dimension size passed to
* @ p fieldArraySize . Expects that the second dimension of @ p fieldData
* is contiguous . At the moment only custom fields can be arrays , which
* means this function can ' t be used with a builtin @ p name . See
* @ ref SceneFieldData ( SceneField , const Containers : : StridedArrayView1D < T > & , const Containers : : StridedArrayView1D < U > & , SceneFieldFlags )
* for details about @ ref SceneMappingType and @ ref SceneFieldType
* detection .
*/
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : StridedArrayView1D < T > & mappingData , const Containers : : StridedArrayView2D < U > & fieldData , SceneFieldFlags flags = { } ) noexcept ;
/** @overload */
template < class T , class U > constexpr explicit SceneFieldData ( SceneField name , const Containers : : ArrayView < T > & mappingData , const Containers : : StridedArrayView2D < U > & fieldData , SceneFieldFlags flags = { } ) noexcept : SceneFieldData { name , Containers : : stridedArrayView ( mappingData ) , fieldData , flags } { }
/**
* @ brief Construct an offset - only field
* @ param name Field name
* @ param size Number of entries
* @ param mappingType Object mapping type
* @ param mappingOffset Object mapping data offset
* @ param mappingStride Object mapping data stride
* @ param fieldType Field type
* @ param fieldOffset Field data offset
* @ param fieldStride Field data stride
* @ param fieldArraySize Field array size . Use @ cpp 0 @ ce for
* non - array fields .
* @ param flags Field flags .
* @ ref SceneFieldFlag : : OffsetOnly is set implicitly .
*
* Instances created this way refer to offsets in unspecified
* external scene data instead of containing the data views directly .
* Useful when the location of the scene data array is not known at
* field construction time . Expects that @ p fieldType corresponds to
* @ p name and @ p fieldArraySize is zero for builtin attributes .
*
* Note that due to the @ cpp constexpr @ ce nature of this constructor ,
* no @ p mappingType checks against @ p mappingStride or
* @ p fieldType / @ p fieldArraySize checks against @ p fieldStride can
* be done . You ' re encouraged to use the @ ref SceneFieldData ( SceneField , SceneMappingType , const Containers : : StridedArrayView1D < const void > & , SceneFieldType , const Containers : : StridedArrayView1D < const void > & , UnsignedShort , SceneFieldFlags )
* constructor if you want additional safeguards .
* @ see @ ref flags ( ) , @ ref fieldArraySize ( ) ,
* @ ref mappingData ( Containers : : ArrayView < const void > ) const ,
* @ ref fieldData ( Containers : : ArrayView < const void > ) const
*/
explicit constexpr SceneFieldData ( SceneField name , std : : size_t size , SceneMappingType mappingType , std : : size_t mappingOffset , std : : ptrdiff_t mappingStride , SceneFieldType fieldType , std : : size_t fieldOffset , std : : ptrdiff_t fieldStride , UnsignedShort fieldArraySize = 0 , SceneFieldFlags flags = { } ) noexcept ;
/** @overload */
explicit constexpr SceneFieldData ( SceneField name , std : : size_t size , SceneMappingType mappingType , std : : size_t mappingOffset , std : : ptrdiff_t mappingStride , SceneFieldType fieldType , std : : size_t fieldOffset , std : : ptrdiff_t fieldStride , SceneFieldFlags flags ) noexcept : SceneFieldData { name , size , mappingType , mappingOffset , mappingStride , fieldType , fieldOffset , fieldStride , 0 , flags } { }
/** @brief Field flags */
constexpr SceneFieldFlags flags ( ) const { return _flags ; }
/** @brief Field name */
constexpr SceneField name ( ) const { return _name ; }
/** @brief Number of entries */
constexpr UnsignedLong size ( ) const { return _size ; }
/** @brief Object mapping type */
constexpr SceneMappingType mappingType ( ) const { return _mappingType ; }
/**
* @ brief Type - erased object mapping data
*
* Expects that the field does not have @ ref SceneFieldFlag : : OffsetOnly
* set , in that case use the @ ref mappingData ( Containers : : ArrayView < const void > ) const
* overload instead .
* @ see @ ref flags ( )
*/
constexpr Containers : : StridedArrayView1D < const void > mappingData ( ) const {
return Containers : : StridedArrayView1D < const void > {
/* We're *sure* the view is correct, so faking the view size */
/** @todo better ideas for the StridedArrayView API? */
{ _mappingData . pointer , ~ std : : size_t { } } , _size ,
( CORRADE_CONSTEXPR_ASSERT ( ! ( _flags & SceneFieldFlag : : OffsetOnly ) , " Trade::SceneFieldData::mappingData(): the field is offset-only, supply a data array " ) , _mappingStride ) } ;
}
/**
* @ brief Type - erased object mapping data for an offset - only attribute
*
* If the field does not have @ ref SceneFieldFlag : : OffsetOnly set , the
* @ p data parameter is ignored .
* @ see @ ref flags ( ) , @ ref mappingData ( ) const
*/
Containers : : StridedArrayView1D < const void > mappingData ( Containers : : ArrayView < const void > data ) const {
return Containers : : StridedArrayView1D < const void > {
/* We're *sure* the view is correct, so faking the view size */
/** @todo better ideas for the StridedArrayView API? */
data , _flags & SceneFieldFlag : : OffsetOnly ? reinterpret_cast < const char * > ( data . data ( ) ) + _mappingData . offset : _mappingData . pointer , _size , _mappingStride } ;
}
/** @brief Field type */
constexpr SceneFieldType fieldType ( ) const { return _fieldType ; }
/** @brief Field array size */
constexpr UnsignedShort fieldArraySize ( ) const { return _fieldArraySize ; }
/**
* @ brief Type - erased field data
*
* Expects that the field does not have @ ref SceneFieldFlag : : OffsetOnly
* set , in that case use the @ ref fieldData ( Containers : : ArrayView < const void > ) const
* overload instead .
* @ see @ ref flags ( )
*/
constexpr Containers : : StridedArrayView1D < const void > fieldData ( ) const {
return Containers : : StridedArrayView1D < const void > {
/* We're *sure* the view is correct, so faking the view size */
/** @todo better ideas for the StridedArrayView API? */
{ _fieldData . pointer , ~ std : : size_t { } } , _size ,
( CORRADE_CONSTEXPR_ASSERT ( ! ( _flags & SceneFieldFlag : : OffsetOnly ) , " Trade::SceneFieldData::fieldData(): the field is offset-only, supply a data array " ) , _fieldStride ) } ;
}
/**
* @ brief Type - erased field data for an offset - only attribute
*
* If the field does not have @ ref SceneFieldFlag : : OffsetOnly set , the
* @ p data parameter is ignored .
* @ see @ ref flags ( ) , @ ref fieldData ( ) const
*/
Containers : : StridedArrayView1D < const void > fieldData ( Containers : : ArrayView < const void > data ) const {
return Containers : : StridedArrayView1D < const void > {
/* We're *sure* the view is correct, so faking the view size */
/** @todo better ideas for the StridedArrayView API? */
data , _flags & SceneFieldFlag : : OffsetOnly ? reinterpret_cast < const char * > ( data . data ( ) ) + _fieldData . offset : _fieldData . pointer , _size , _fieldStride } ;
}
private :
friend SceneData ;
union Data {
/* FFS C++ why this doesn't JUST WORK goddamit?! It's already past
the End Of Times AND YET this piece of complex shit can ' t do the
obvious ! */
constexpr Data ( const void * pointer = nullptr ) : pointer { pointer } { }
constexpr Data ( std : : size_t offset ) : offset { offset } { }
const void * pointer ;
std : : size_t offset ;
} ;
UnsignedLong _size ;
SceneField _name ;
SceneFieldFlags _flags ;
SceneMappingType _mappingType ;
Short _mappingStride ;
Data _mappingData ;
SceneFieldType _fieldType ;
Short _fieldStride ;
UnsignedShort _fieldArraySize ;
/* 2 bytes free */
Data _fieldData ;
} ;
/** @relatesalso SceneFieldData
@ brief Create a non - owning array of @ ref SceneFieldData items
@ m_since_latest
Useful when you have the field definitions statically defined ( for example when
the data themselves are already defined at compile time ) and don ' t want to
allocate just to pass those to @ ref SceneData .
*/
Containers : : Array < SceneFieldData > MAGNUM_TRADE_EXPORT sceneFieldDataNonOwningArray ( Containers : : ArrayView < const SceneFieldData > view ) ;
/**
@ brief Scene data
Contains scene node hierarchy , transformations , resource assignment as well as
any other data associated with the scene . Populated instances of this class are
returned from @ ref AbstractImporter : : scene ( ) .
@ section Trade - SceneData - representation Data representation and terminology
@ m_div { m - container - inflate m - col - l - 9 m - left - l }
@ htmlinclude scenedata - tree . svg
@ m_enddiv
The usual mental image of a scene is a tree hierarchy with varying amount of
data attached to each node , like shown in the first diagram . The @ ref SceneData
however decouples the hierarchy from the data and stores everything in linear
arrays , like in the second diagram .
This allows for a more efficient storage , as only the actually needed
information is stored . For example , three nodes in the tree have an implicit
transformation , which we can simply omit , or because there might be way less
materials than meshes , their references can be in a smaller type . It ' s also
more flexible - - - having multiple meshes per node is just about having multiple
entries associated with the same node .
@ m_div { m - clearfix - l } @ m_enddiv
@ m_div { m - container - inflate m - col - l - 8 m - right - l }
@ htmlinclude scenedata - dod . svg
@ m_enddiv
From a high - level perspective , the scene data storage can thought of as a set
of * Fields * , with field entries mapped to * Objects * . Scene * Nodes * are a
special case of * Objects * .
An * Object * is an arbitrary numeric identifier , not containing anything on its
own . All objects referenced by a particular scene are contained in a range from
@ cpp 0 @ ce up to @ ref mappingBound ( ) minus one . The range is allowed to be
sparse .
A * Field * is a list of data - - - for example transformations , mesh IDs , or
parent objects . The @ ref SceneField enum lists all predefined fields together
with possible restrictions and the expected @ ref SceneFieldType they ' re
expected to be in . Custom fields are supported as well . Field entries are
mapped to objects with the same 8 - , 16 - , 32 - or 64 - bit type for all fields ,
indicated with @ ref SceneMappingType . Generally there ' s a 1 : N mapping between
objects and fields ( not all objects need to have a transformation , a single
object can reference multiple meshes . . . ) , but certain field types expect
various restrictions ( such as an object allowed to only have one parent or
transformation ) .
Finally , scene * Nodes * are * Objects * that have the @ ref SceneField : : Parent
field associated . An * Object * thus doesn ' t have to represent just a node in the
hierarchy . For example , a scene can also contain an alternative representation
in the form of an octree , and thus some objects would be nodes and some octree
cells .
@ subsection Trade - SceneData - representation - multi - scene Object identifiers and multiple scenes
For a standalone scene , a common case is that the object identifiers form a
contigous range of numbers , and each of the objects has at least one field
assigned .
The @ ref AbstractImporter supports files with multiple scenes . All imported
scenes share a single object range , from @ cpp 0 @ ce to
@ ref AbstractImporter : : objectCount ( ) . A particular object can be part of any of
the scenes , causing the @ ref SceneData : : mappingBound ( ) ranges to be sparse - - -
a particular scene having certain object IDs that have no fields assigned . This
is something to be aware of when consuming the scene data , that not all objects
identifiers in the mapping range may actually exist .
It ' s also possible for a single object identifier to be contained in multiple
scenes at the same time - - - for example , when two scenes are variants of the
same model , with most data shared but certain textures or colors different .
Another theoretical use case is that an object could identify a building in a
3 D scene and a corresponding area on a map in a 2 D scene . There ' s no set of
rules the objects should follow , but such identifier reusal should not be
abused for completely unrelated objects .
@ todoc mention handles and how they would affect the basic use below ( aaaa ! )
@ section Trade - SceneData - usage Basic usage
A simple goal could be to populate a @ ref SceneGraph with a node hierarchy
and attach drawables for meshes where appropriate . First we check if the scene
is 3 D with @ ref is3D ( ) , because if it ' s not , it could mean it ' s either 2 D or
that it has no transformation field altogether , suggesting a need for
specialized handling . It ' s also of no use for this example if there ' s no node
hierarchy , or if there are no meshes we could draw .
Then we create the scene instance and an array of pointers that will act as a
map from object identifiers to live objects . The @ ref mappingBound ( ) is an
upper bound to all object identifiers referenced by the scene , but as mentioned
above , not all of them may be actual nodes so we don ' t allocate actual scene
graph object instances for them yet . Alternatively , for very sparse ranges , a hashmap could be also used here .
@ snippet MagnumTrade . cpp SceneData - usage1
< b > < / b >
@ m_class { m - noindent }
Next we go through objects that have an associated parent using
@ ref parentsAsArray ( ) . Those are the actual nodes we want , so we allocate a
scene graph object for each . . .
@ snippet MagnumTrade . cpp SceneData - usage2
@ m_class { m - noindent }
< b > < / b >
. . . and then we assign a proper parent , or add it directly to the scene if the
parent is @ cpp - 1 @ ce . We do this in a separate pass to ensure the parent
object is already allocated by the time we pass it to
@ ref SceneGraph : : Object : : setParent ( ) - - - generally there ' s no guarantee that a
parent appears in the field before its children .
@ snippet MagnumTrade . cpp SceneData - usage3
With the hierarchy done , we assign transformations . The transformation field
can be present for only a subset of the nodes , with the rest implicitly having
an indentity transformation , but it can also be present for objects that aren ' t
nodes , so we only set it for objects present in our hierarchy . The
@ ref transformations3DAsArray ( ) function also conveniently converts separate
transformation / rotation / scaling fields into a matrix for us , if the scene
contains only those .
@ snippet MagnumTrade . cpp SceneData - usage4
Finally , assuming there ' s a ` Drawable ` class derived from
@ ref SceneGraph : : Drawable that accepts a mesh and material ID ( retrieving them
subsequently from @ ref AbstractImporter : : mesh ( ) /
@ relativeref { AbstractImporter , material ( ) } , for example ) , the process of
assigning actual meshes to corresponding scene nodes is just another
@ cpp for @ ce loop over @ ref meshesMaterialsAsArray ( ) :
@ snippet MagnumTrade . cpp SceneData - usage5
< b > < / b >
@ m_class { m - note m - success }
@ par
The full process of importing a scene including meshes , materials and
textures is shown in the @ ref examples - viewer example .
@ section Trade - SceneData - usage - advanced Advanced usage
The @ ref parentsAsArray ( ) , . . . functions shown above always return a
newly - allocated @ relativeref { Corrade , Containers : : Array } instance in a
well - defined canonical type . While that ' s convenient and fine at a smaller
scale , it may prove problematic with huge scenes . Or maybe the internal
representation is already optimized for best processing efficiency and the
convenience functions would ruin that . The @ ref SceneData class thus provides
access directly to the stored object mapping and field data using the
@ ref mapping ( ) and @ ref field ( ) accessors .
However , since each @ ref SceneField can be in a variety of types , you ' re
expected to either check that the type is indeed what you expect using
@ ref fieldType ( SceneField ) const , or at least check with documentation of the
corresponding importer . For example , because glTF files represent the scene
in a textual form , @ ref CgltfImporter will always parse the data into canonical
32 - bit types . With that assumption , the above snippet that used
@ ref transformations3DAsArray ( ) can be rewritten to a zero - copy form like this :
@ snippet MagnumTrade . cpp SceneData - usage - advanced
@ section Trade - SceneData - usage - per - object Per - object access
While the designated way to access scene data is by iterating through the field
and object arrays , it ' s also possible to directly look at fields for a
particular object without having to do a lookup on your own and with simplified
error handling . The @ ref parentFor ( ) , @ ref childrenFor ( ) ,
@ ref transformation3DFor ( ) , @ ref meshesMaterialsFor ( ) and other functions
return either an @ relativeref { Corrade , Containers : : Optional } or an
@ relativeref { Corrade , Containers : : Array } depending on whether there ' s expected
just one occurence of the field or more , returning an empty optional or array
if the field is not present in the scene or if the object was not found in the
field array .
For example , together with an @ ref AbstractImporter instance the scene comes
from , the following snippet lists meshes and material names that are associated
with a " Chair " object , assuming such object exists :
@ snippet MagnumTrade . cpp SceneData - per - object
The actual object ID lookup is done by @ ref findFieldObjectOffset ( ) and
depending on what @ ref SceneFieldFlags are present for given field , it can be
done in constant , logarithmic or , worst case , linear time . As such , for general
scene representations these are suited mainly for introspection and debugging
purposes and retrieving field data for many objects is better achieved by
accessing the field data directly .
@ section Trade - SceneData - usage - mutable Mutable data access
The interfaces implicitly provide @ cpp const @ ce views on the contained object
and field data through the @ ref data ( ) , @ ref mapping ( ) and @ ref field ( )
accessors . This is done because in general case the data can also refer to a
memory - mapped file or constant memory . In cases when it ' s desirable to modify
the data in - place , there ' s the @ ref mutableData ( ) , @ ref mutableMapping ( ) and
@ ref mutableField ( ) set of functions . To use these , you need to check that
the data are mutable using @ ref dataFlags ( ) first . The following snippet
updates all transformations with the live state of a scene imported earlier ,
for example in order to bake in a certain animation state :
@ snippet MagnumTrade . cpp SceneData - usage - mutable
@ section Trade - SceneData - populating Populating an instance
The actual data in a @ ref SceneData instance are represented as a single block
of contiguous memory , which all object and field views point to . This is
easiest to achieve with an @ relativeref { Corrade , Containers : : ArrayTuple } . In the
example below , all objects have a parent and a transformation field , which are
stored together in a @ cpp struct @ ce , while a subset of them has a mesh and a
material assigned , which are stored in separate arrays . And because the scene
is small , we save space by using just 16 - bit indices for everything .
@ snippet MagnumTrade . cpp SceneData - populating
Note that the above layout is just an example , you ' re free to choose any
representation that matches your use case best , with fields interleaved
together or not . See also the @ ref SceneFieldData class documentation for
additional ways how to specify and annotate the data .
@ subsection Trade - SceneData - populating - custom Custom scene fields and non - node objects
Let ' s say that , in addition to the node hierarchy from above , our scene
contains also a precomputed [ camera - space light culling grid ] ( https : //wickedengine.net/2018/01/10/optimizing-tile-based-light-culling/),
where each cell of the grid contains a list of lights that affect given area of
the screen . And we want to add it into the @ ref SceneData for verification with
external tools .
For simplicity let ' s assume we have a 32 x24 grid and the shader we have can
work with up to 8 lights . So there will be a fixed - size array for each of those
cells , and we save calculated frustums for inspection as well . For the new data
we allocate object IDs from a range after ` nodeCount ` , and copy in the actual
data .
@ snippet MagnumTrade . cpp SceneData - populating - custom1
Then , similarly as with @ ref MeshData , the scene can have custom fields as
well , created with @ ref sceneFieldCustom ( ) . We create one for the cell light
reference array and one for the cell frustum and then use them to annotate
the views allocated above . Note that we also increased the total object count
to include the light culling grid cells as well .
@ snippet MagnumTrade . cpp SceneData - populating - custom2
Later , the fields can be retrieved back using the same custom identifiers .
The light references are actually a 2 D array ( 8 lights for each cell ) , so a
@ cpp [ ] @ ce needs to be used :
@ snippet MagnumTrade . cpp SceneData - populating - custom - retrieve
@ see @ ref AbstractImporter : : scene ( )
*/
class MAGNUM_TRADE_EXPORT SceneData {
public :
/**
* @ brief Construct scene data
* @ param mappingType Object mapping type
* @ param mappingBound Upper bound on object mapping indices in the
* scene
* @ param data Data for all fields and object mappings
* @ param fields Description of all scene field data
* @ param importerState Importer - specific state
* @ m_since_latest
*
* The @ p mappingType is expected to be large enough to index
* @ p mappingBound objects . The @ p fields are expected to reference
* ( sparse ) sub - ranges of @ p data , each having an unique
* @ ref SceneField , and @ ref SceneMappingType equal to @ p mappingType .
* Particular fields can have additional restrictions , see
* documentation of @ ref SceneField values for more information .
*
* The @ ref dataFlags ( ) are implicitly set to a combination of
* @ ref DataFlag : : Owned and @ ref DataFlag : : Mutable . For non - owned data
* use the @ ref SceneData ( SceneMappingType , UnsignedLong , DataFlags , Containers : : ArrayView < const void > , Containers : : Array < SceneFieldData > & & , const void * )
* constructor or its variants instead .
*/
explicit SceneData ( SceneMappingType mappingType , UnsignedLong mappingBound , Containers : : Array < char > & & data , Containers : : Array < SceneFieldData > & & fields , const void * importerState = nullptr ) noexcept ;
/**
* @ overload
* @ m_since_latest
*/
/* Not noexcept because allocation happens inside */
explicit SceneData ( SceneMappingType mappingType , UnsignedLong mappingBound , Containers : : Array < char > & & data , std : : initializer_list < SceneFieldData > fields , const void * importerState = nullptr ) ;
/**
* @ brief Construct non - owned scene data
* @ param mappingType Object mapping type
* @ param mappingBound Upper bound on object mapping indices in the
* scene
* @ param dataFlags Data flags
* @ param data View on data for all fields and object mappings
* @ param fields Description of all scene field data
* @ param importerState Importer - specific state
* @ m_since_latest
*
* Compared to @ ref SceneData ( SceneMappingType , UnsignedLong , Containers : : Array < char > & & , Containers : : Array < SceneFieldData > & & , const void * )
* creates an instance that doesn ' t own the passed data . The
* @ p dataFlags parameter can contain @ ref DataFlag : : Mutable to
* indicate the external data can be modified , and is expected to * not *
* have @ ref DataFlag : : Owned set .
*/
explicit SceneData ( SceneMappingType mappingType , UnsignedLong mappingBound , DataFlags dataFlags , Containers : : ArrayView < const void > data , Containers : : Array < SceneFieldData > & & fields , const void * importerState = nullptr ) noexcept ;
/**
* @ overload
* @ m_since_latest
*/
/* Not noexcept because allocation happens inside */
explicit SceneData ( SceneMappingType mappingType , UnsignedLong mappingBound , DataFlags dataFlags , Containers : : ArrayView < const void > data , std : : initializer_list < SceneFieldData > fields , const void * importerState = nullptr ) ;
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ brief Constructor
* @ param children2D Two - dimensional child objects
* @ param children3D Three - dimensional child objects
* @ param importerState Importer - specific state
* @ m_deprecated_since_latest Use @ ref SceneData ( SceneMappingType , UnsignedLong , Containers : : Array < char > & & , Containers : : Array < SceneFieldData > & & , const void * )
* instead .
*/
explicit CORRADE_DEPRECATED ( " use SceneData(SceneMappingType, UnsignedLong, Containers::Array<char>&&, Containers::Array<SceneFieldData>&&, const void*) instead " ) SceneData(std::vector<UnsignedInt> children2D, std::vector<UnsignedInt> children3D, const void* importerState = nullptr) ;
# endif
/** @brief Copying is not allowed */
SceneData ( const SceneData & ) = delete ;
/** @brief Move constructor */
SceneData ( SceneData & & ) noexcept ;
~ SceneData ( ) ;
/** @brief Copying is not allowed */
SceneData & operator = ( const SceneData & ) = delete ;
/** @brief Move assignment */
SceneData & operator = ( SceneData & & ) noexcept ;
/**
* @ brief Data flags
* @ m_since_latest
*
* @ see @ ref releaseData ( ) , @ ref mutableData ( ) , @ ref mutableMapping ( ) ,
* @ ref mutableField ( )
*/
DataFlags dataFlags ( ) const { return _dataFlags ; }
/**
* @ brief Raw data
* @ m_since_latest
*
* Returns @ cpp nullptr @ ce if the scene has no data .
*/
Containers : : ArrayView < const char > data ( ) const & { return _data ; }
/**
* @ brief Taking a view to a r - value instance is not allowed
* @ m_since_latest
*/
Containers : : ArrayView < const char > data ( ) const & & = delete ;
/**
* @ brief Mutable raw data
* @ m_since_latest
*
* Like @ ref data ( ) , but returns a non - const view . Expects that the
* scene is mutable .
* @ see @ ref dataFlags ( )
*/
Containers : : ArrayView < char > mutableData ( ) & ;
/**
* @ brief Taking a view to a r - value instance is not allowed
* @ m_since_latest
*/
Containers : : ArrayView < char > mutableData ( ) & & = delete ;
/**
* @ brief Type used for object mapping
* @ m_since_latest
*
* Type returned from @ ref mapping ( ) and @ ref mutableMapping ( ) . It ' s
* the same for all fields and is guaranteed to be large enough to fit
* @ ref mappingBound ( ) objects .
*/
SceneMappingType mappingType ( ) const { return _mappingType ; }
/**
* @ brief Object mapping bound
* @ m_since_latest
*
* Upper bound on object mapping indices of all fields in the scene .
* @ see @ ref fieldCount ( ) , @ ref fieldSize ( )
*/
UnsignedLong mappingBound ( ) const { return _mappingBound ; }
/**
* @ brief Field count
* @ m_since_latest
*
* Count of different fields contained in the scene , or @ cpp 0 @ ce for
* a scene with no fields . Each @ ref SceneField can be present only
* once , however an object can have a certain field associated with it
* multiple times with different values ( for example an object having
* multiple meshes ) .
*/
UnsignedInt fieldCount ( ) const { return _fields . size ( ) ; }
/**
* @ brief Raw field metadata
* @ m_since_latest
*
* Returns the raw data that are used as a base for all ` field * ( ) `
* accessors , or @ cpp nullptr @ ce if the scene has no fields . In most
* cases you don ' t want to access those directly , but rather use the
* @ ref mapping ( ) , @ ref field ( ) , @ ref fieldName ( ) , @ ref fieldType ( ) ,
* @ ref fieldSize ( ) and @ ref fieldArraySize ( ) accessors . Compared to
* those and to @ ref fieldData ( UnsignedInt ) const , the
* @ ref SceneFieldData instances returned by this function may have
* different data pointers , and some of them might have
* @ ref SceneFieldFlag : : OffsetOnly set - - - use this function only if
* you * really * know what are you doing .
* @ see @ ref SceneFieldData : : flags ( )
*/
Containers : : ArrayView < const SceneFieldData > fieldData ( ) const & { return _fields ; }
/**
* @ brief Taking a view to a r - value instance is not allowed
* @ m_since_latest
*/
Containers : : ArrayView < const SceneFieldData > fieldData ( ) const & & = delete ;
/**
* @ brief Raw field data
* @ m_since_latest
*
* Returns the raw data that are used as a base for all ` field * ( ) `
* accessors . In most cases you don ' t want to access those directly ,
* but rather use the @ ref mapping ( ) , @ ref field ( ) , @ ref fieldName ( ) ,
* @ ref fieldType ( ) , @ ref fieldSize ( ) and @ ref fieldArraySize ( )
* accessors . This is also the reason why there ' s no overload taking a
* @ ref SceneField , unlike the other accessors .
*
* Unlike with @ ref fieldData ( ) and @ ref releaseFieldData ( ) , returned
* instances are guaranteed to always have an absolute data pointer
* ( i . e . , @ ref SceneFieldData : : flags ( ) never having
* @ ref SceneFieldFlag : : OffsetOnly set ) . The @ p id is expected to be
* smaller than @ ref fieldCount ( ) .
*/
SceneFieldData fieldData ( UnsignedInt id ) const ;
/**
* @ brief Field name
* @ m_since_latest
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) .
* @ see @ ref fieldType ( ) , @ ref isSceneFieldCustom ( ) ,
* @ ref AbstractImporter : : sceneFieldForName ( ) ,
* @ ref AbstractImporter : : sceneFieldName ( )
*/
SceneField fieldName ( UnsignedInt id ) const ;
/**
* @ brief Field flags
* @ m_since_latest
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) .
* @ see @ ref findFieldObjectOffset ( UnsignedInt , UnsignedLong , std : : size_t ) const
*/
SceneFieldFlags fieldFlags ( UnsignedInt id ) const ;
/**
* @ brief Field type
* @ m_since_latest
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) . You can
* also use @ ref fieldType ( SceneField ) const to directly get a type of
* given named field .
* @ see @ ref fieldName ( ) , @ ref mappingType ( )
*/
SceneFieldType fieldType ( UnsignedInt id ) const ;
/**
* @ brief Size of given field
* @ m_since_latest
*
* Size of the view returned by @ ref mapping ( ) / @ ref mutableMapping ( )
* and @ ref field ( ) / @ ref mutableField ( ) for given @ p id . Since an
* object can have multiple entries of the same field ( for example
* multiple meshes associated with an object ) , the size doesn ' t
* necessarily match the number of objects having given field .
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) . You can
* also use @ ref fieldSize ( SceneField ) const to directly get a size of
* given named field .
*/
std : : size_t fieldSize ( UnsignedInt id ) const ;
/**
* @ brief Field array size
* @ m_since_latest
*
* In case given field is an array ( the euqivalent of e . g .
* @ cpp int [ 30 ] @ ce ) , returns array size , otherwise returns @ cpp 0 @ ce .
* At the moment only custom fields can be arrays , no builtin
* @ ref SceneField is an array attribute . Note that this is different
* from the count of entries for given field , which is exposed through
* @ ref fieldSize ( ) . See @ ref Trade - SceneData - populating - custom for an
* example .
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) . You can
* also use @ ref fieldArraySize ( SceneField ) const to directly get a
* type of given named field .
*/
UnsignedShort fieldArraySize ( UnsignedInt id ) const ;
/**
* @ brief Whether the scene is two - dimensional
* @ m_since_latest
*
* Returns @ cpp true @ ce if the present
* @ ref SceneField : : Transformation ,
* @ relativeref { SceneField , Translation } ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } fields have a 2 D type ,
* @ cpp false @ ce otherwise .
*
* If there ' s no transformation - related field , the scene is treated as
* neither 2 D nor 3 D and both @ ref is2D ( ) and @ ref is3D ( ) return
* @ cpp false @ ce . On the other hand , a scene can ' t be both 2 D and 3 D .
* @ see @ ref hasField ( )
*/
bool is2D ( ) const { return _dimensions = = 2 ; }
/**
* @ brief Whether the scene is three - dimensional
* @ m_since_latest
*
* Returns @ cpp true @ ce if the present
* @ ref SceneField : : Transformation ,
* @ relativeref { SceneField , Translation } ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } fields have a 3 D type ,
* @ cpp false @ ce otherwise .
*
* If there ' s no transformation - related field , the scene is treated as
* neither 2 D nor 3 D and both @ ref is2D ( ) and @ ref is3D ( ) return
* @ cpp false @ ce . On the other hand , a scene can ' t be both 2 D and 3 D .
* @ see @ ref hasField ( )
*/
bool is3D ( ) const { return _dimensions = = 3 ; }
/**
* @ brief Find an absolute ID of a named field
* @ m_since_latest
*
* If @ p name doesn ' t exist , returns @ ref Containers : : NullOpt . The
* lookup is done in an @ f $ \ mathcal { O } ( n ) @ f $ complexity with
* @ f $ n @ f $ being the field count .
* @ see @ ref hasField ( ) , @ ref fieldId ( )
*/
Containers : : Optional < UnsignedInt > findFieldId ( SceneField name ) const ;
/**
* @ brief Absolute ID of a named field
* @ m_since_latest
*
* Like @ ref findFieldId ( ) , but the @ p name is expected to exist .
* @ see @ ref hasField ( ) , @ ref fieldName ( UnsignedInt ) const
*/
UnsignedInt fieldId ( SceneField name ) const ;
/**
* @ brief Whether the scene has given field
* @ m_since_latest
*
* @ see @ ref is2D ( ) , @ ref is3D ( )
*/
bool hasField ( SceneField name ) const ;
/**
* @ brief Find offset of an object in given field
* @ m_since_latest
*
* If @ p object isn ' t present in @ p fieldId starting at @ p offset ,
* returns @ ref Containers : : NullOpt . The @ p fieldId is expected to be
* smaller than @ ref fieldCount ( ) , @ p object smaller than
* @ ref mappingBound ( ) and @ p offset not larger than
* @ ref fieldSize ( UnsignedInt ) const .
*
* If the field has @ ref SceneFieldFlag : : ImplicitMapping , the lookup is
* done in an @ f $ \ mathcal { O } ( 1 ) @ f $ complexity . Otherwise , if the
* field has @ ref SceneFieldFlag : : OrderedMapping , the lookup is done in
* an @ f $ \ mathcal { O } ( \ log { } n ) @ f $ complexity with @ f $ n @ f $ being the
* size of the field . Otherwise , the lookup is done in an
* @ f $ \ mathcal { O } ( n ) @ f $ complexity .
*
* You can also use @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* to directly find offset of an object in given named field .
* @ see @ ref hasFieldObject ( UnsignedInt , UnsignedLong ) const ,
* @ ref fieldObjectOffset ( UnsignedInt , UnsignedLong , std : : size_t ) const
*/
Containers : : Optional < std : : size_t > findFieldObjectOffset ( UnsignedInt fieldId , UnsignedLong object , std : : size_t offset = 0 ) const ;
/**
* @ brief Find offset of an object in given named field
* @ m_since_latest
*
* If @ p object isn ' t present in @ p fieldName starting at @ p offset ,
* returns @ ref Containers : : NullOpt . The @ p fieldName is expected to
* exist , @ p object is expected to be smaller than @ ref mappingBound ( )
* and @ p offset not be larger than @ ref fieldSize ( SceneField ) const .
*
* If the field has @ ref SceneFieldFlag : : ImplicitMapping , the lookup is
* done in an @ f $ \ mathcal { O } ( m ) @ f $ complexity with @ f $ m @ f $ being
* the * field count . Otherwise , if the field has
* @ ref SceneFieldFlag : : OrderedMapping , the lookup is done in an
* @ f $ \ mathcal { O } ( m + \ log { } n ) @ f $ complexity with @ f $ m @ f $ being
* the field count and @ f $ n @ f $ the size of the field . Otherwise , the
* lookup is done in an @ f $ \ mathcal { O } ( m + n ) @ f $ complexity .
*
* @ see @ ref hasField ( ) , @ ref hasFieldObject ( SceneField , UnsignedLong ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
Containers : : Optional < std : : size_t > findFieldObjectOffset ( SceneField fieldName , UnsignedLong object , std : : size_t offset = 0 ) const ;
/**
* @ brief Offset of an object in given field
* @ m_since_latest
*
* Like @ ref findFieldObjectOffset ( UnsignedInt , UnsignedLong , std : : size_t ) const ,
* but @ p object is additionally expected to be present in @ p fieldId
* starting at @ p offset .
*
* You can also use @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* to directly get offset of an object in given named field .
*/
std : : size_t fieldObjectOffset ( UnsignedInt fieldId , UnsignedLong object , std : : size_t offset = 0 ) const ;
/**
* @ brief Offset of an object in given named field
* @ m_since_latest
*
* Like @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const ,
* but @ p object is additionally expected to be present in @ p fieldName
* starting at @ p offset .
*/
std : : size_t fieldObjectOffset ( SceneField fieldName , UnsignedLong object , std : : size_t offset = 0 ) const ;
/**
* @ brief Whether a scene field has given object
* @ m_since_latest
*
* The @ p fieldId is expected to be smaller than @ ref fieldCount ( ) and
* @ p object smaller than @ ref mappingBound ( ) .
*/
bool hasFieldObject ( UnsignedInt fieldId , UnsignedLong object ) const ;
/**
* @ brief Whether a named scene field has given object
* @ m_since_latest
*
* The @ p fieldName is expected to exist and @ p object is expected to
* be smaller than @ ref mappingBound ( ) .
* @ see @ ref hasField ( )
*/
bool hasFieldObject ( SceneField fieldName , UnsignedLong object ) const ;
/**
* @ brief Field flags
* @ m_since_latest
*
* The @ p name is expected to exist .
* @ see @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
SceneFieldFlags fieldFlags ( SceneField name ) const ;
/**
* @ brief Type of a named field
* @ m_since_latest
*
* The @ p name is expected to exist .
* @ see @ ref hasField ( ) , @ ref fieldType ( UnsignedInt ) const
*/
SceneFieldType fieldType ( SceneField name ) const ;
/**
* @ brief Number of entries for given named field
* @ m_since_latest
*
* The @ p name is expected to exist .
* @ see @ ref hasField ( ) , @ ref fieldSize ( UnsignedInt ) const
*/
std : : size_t fieldSize ( SceneField name ) const ;
/**
* @ brief Array size of a named field
* @ m_since_latest
*
* The @ p name is expected to exist .
* @ see @ ref hasField ( ) , @ ref fieldArraySize ( UnsignedInt ) const
*/
UnsignedShort fieldArraySize ( SceneField name ) const ;
/**
* @ brief Object mapping data for given field
* @ m_since_latest
*
* The @ p fieldId is expected to be smaller than @ ref fieldCount ( ) . The
* second dimension represents the actual data type ( its size is equal
* to @ ref SceneMappingType size ) and is guaranteed to be contiguous .
* Use the templated overload below to get the mapping in a concrete
* type .
* @ see @ ref mutableMapping ( UnsignedInt ) ,
* @ ref Corrade : : Containers : : StridedArrayView : : isContiguous ( ) ,
* @ ref sceneMappingTypeSize ( )
*/
Containers : : StridedArrayView2D < const char > mapping ( UnsignedInt fieldId ) const ;
/**
* @ brief Mutable object mapping data for given field
* @ m_since_latest
*
* Like @ ref mapping ( UnsignedInt ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
Containers : : StridedArrayView2D < char > mutableMapping ( UnsignedInt fieldId ) ;
/**
* @ brief Object mapping for given field
* @ m_since_latest
*
* The @ p fieldId is expected to be smaller than @ ref fieldCount ( ) and
* @ p T is expected to correspond to @ ref mappingType ( ) .
*
* You can also use the non - templated @ ref mappingAsArray ( ) accessor
* ( or the combined @ ref parentsAsArray ( ) ,
* @ ref transformations2DAsArray ( ) , @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors ) to get the object mapping
* converted to the usual type , but note that these operations involve
* extra allocation and data conversion .
* @ see @ ref mutableMapping ( UnsignedInt )
*/
template < class T > Containers : : StridedArrayView1D < const T > mapping ( UnsignedInt fieldId ) const ;
/**
* @ brief Mutable object mapping for given field
* @ m_since_latest
*
* Like @ ref mapping ( UnsignedInt ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
template < class T > Containers : : StridedArrayView1D < T > mutableMapping ( UnsignedInt fieldId ) ;
/**
* @ brief Object mapping data for given named field
* @ m_since_latest
*
* The @ p fieldName is expected to exist . The second dimension
* represents the actual data type ( its size is equal to
* @ ref SceneMappingType size ) and is guaranteed to be contiguous . Use
* the templated overload below to get the object mapping in a concrete
* type .
* @ see @ ref hasField ( ) , @ ref mapping ( UnsignedInt ) const ,
* @ ref mutableMapping ( SceneField ) ,
* @ ref Corrade : : Containers : : StridedArrayView : : isContiguous ( )
*/
Containers : : StridedArrayView2D < const char > mapping ( SceneField fieldName ) const ;
/**
* @ brief Mutable object mapping data for given named field
* @ m_since_latest
*
* Like @ ref mapping ( SceneField ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
Containers : : StridedArrayView2D < char > mutableMapping ( SceneField fieldName ) ;
/**
* @ brief Object mapping for given named field
* @ m_since_latest
*
* The @ p fieldName is expected to exist and @ p T is expected to
* correspond to @ ref mappingType ( ) .
*
* You can also use the non - templated @ ref mappingAsArray ( ) accessor
* ( or the combined @ ref parentsAsArray ( ) ,
* @ ref transformations2DAsArray ( ) , @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors ) to get the object mapping
* converted to the usual type , but note that these operations involve
* extra allocation and data conversion .
* @ see @ ref hasField ( ) , @ ref mapping ( UnsignedInt ) const ,
* @ ref mutableMapping ( UnsignedInt )
*/
template < class T > Containers : : StridedArrayView1D < const T > mapping ( SceneField fieldName ) const ;
/**
* @ brief Mutable object mapping for given named field
* @ m_since_latest
*
* Like @ ref mapping ( SceneField ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
template < class T > Containers : : StridedArrayView1D < T > mutableMapping ( SceneField fieldName ) ;
/**
* @ brief Data for given field
* @ m_since_latest
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) . The
* second dimension represents the actual data type ( its size is equal
* to @ ref SceneFieldType size , possibly multiplied by array size ) and
* is guaranteed to be contiguous . Use the templated overload below to
* get the field in a concrete type .
* @ see @ ref Corrade : : Containers : : StridedArrayView : : isContiguous ( ) ,
* @ ref sceneFieldTypeSize ( ) , @ ref mutableField ( UnsignedInt )
*/
Containers : : StridedArrayView2D < const char > field ( UnsignedInt id ) const ;
/**
* @ brief Mutable data for given field
* @ m_since_latest
*
* Like @ ref field ( UnsignedInt ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
Containers : : StridedArrayView2D < char > mutableField ( UnsignedInt id ) ;
/**
* @ brief Data for given field in a concrete type
* @ m_since_latest
*
* The @ p id is expected to be smaller than @ ref fieldCount ( ) and @ p T
* is expected to correspond to @ ref fieldType ( UnsignedInt ) const . The
* field is also expected to not be an array , in that case you need to
* use the overload below by using @ cpp T [ ] @ ce instead of @ cpp T @ ce .
*
* You can also use the non - templated @ ref parentsAsArray ( ) ,
* @ ref transformations2DAsArray ( ) , @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors to get common fields converted
* to usual types , but note that these operations involve extra
* allocation and data conversion .
* @ see @ ref field ( SceneField ) const , @ ref mutableField ( UnsignedInt ) ,
* @ ref fieldArraySize ( )
*/
template < class T , class = typename std : : enable_if < ! std : : is_array < T > : : value > : : type > Containers : : StridedArrayView1D < const T > field ( UnsignedInt id ) const ;
/**
* @ brief Data for given array field in a concrete type
* @ m_since_latest
*
* Same as above , except that it works with array fields instead - - -
* you ' re expected to select this overload by passing @ cpp T [ ] @ ce
* instead of @ cpp T @ ce . The second dimension is guaranteed to be
* contiguous and have the same size as reported by
* @ ref fieldArraySize ( UnsignedInt ) const for given field .
*/
template < class T , class = typename std : : enable_if < std : : is_array < T > : : value > : : type > Containers : : StridedArrayView2D < const typename std : : remove_extent < T > : : type > field ( UnsignedInt id ) const ;
/**
* @ brief Mutable data for given field in a concrete type
* @ m_since_latest
*
* Like @ ref field ( UnsignedInt ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
template < class T , class = typename std : : enable_if < ! std : : is_array < T > : : value > : : type > Containers : : StridedArrayView1D < T > mutableField ( UnsignedInt id ) ;
/**
* @ brief Mutable data for given array field in a concrete type
* @ m_since_latest
*
* Same as above , except that it works with array fields instead - - -
* you ' re expected to select this overload by passing @ cpp T [ ] @ ce
* instead of @ cpp T @ ce . The second dimension is guaranteed to be
* contiguous and have the same size as reported by
* @ ref fieldArraySize ( UnsignedInt ) const for given field .
*/
template < class T , class = typename std : : enable_if < std : : is_array < T > : : value > : : type > Containers : : StridedArrayView2D < typename std : : remove_extent < T > : : type > mutableField ( UnsignedInt id ) ;
/**
* @ brief Data for given named field
* @ m_since_latest
*
* The @ p name is expected to exist . The second dimension represents
* the actual data type ( its size is equal to @ ref SceneFieldType size ,
* possibly multiplied by array size ) and is guaranteed to be
* contiguous . Use the templated overload below to get the field in a
* concrete type .
* @ see @ ref hasField ( ) , @ ref field ( UnsignedInt ) const ,
* @ ref mutableField ( SceneField ) ,
* @ ref Corrade : : Containers : : StridedArrayView : : isContiguous ( )
*/
Containers : : StridedArrayView2D < const char > field ( SceneField name ) const ;
/**
* @ brief Mutable data for given named field
* @ m_since_latest
*
* Like @ ref field ( SceneField ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
Containers : : StridedArrayView2D < char > mutableField ( SceneField name ) ;
/**
* @ brief Data for given named field in a concrete type
* @ m_since_latest
*
* The @ p name is expected to exist and @ p T is expected to correspond
* to @ ref fieldType ( SceneField ) const . The field is also expected to
* not be an array , in that case you need to use the overload below by
* using @ cpp T [ ] @ ce instead of @ cpp T @ ce .
*
* You can also use the non - templated @ ref parentsAsArray ( ) ,
* @ ref transformations2DAsArray ( ) , @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors to get common fields converted
* to usual types , but note that these operations involve extra
* allocation and data conversion .
* @ see @ ref field ( UnsignedInt ) const , @ ref mutableField ( SceneField )
*/
template < class T , class = typename std : : enable_if < ! std : : is_array < T > : : value > : : type > Containers : : StridedArrayView1D < const T > field ( SceneField name ) const ;
/**
* @ brief Data for given named array field in a concrete type
* @ m_since_latest
*
* Same as above , except that it works with array fields instead - - -
* you ' re expected to select this overload by passing @ cpp T [ ] @ ce
* instead of @ cpp T @ ce . The second dimension is guaranteed to be
* contiguous and have the same size as reported by
* @ ref fieldArraySize ( SceneField ) const for given field .
*/
template < class T , class = typename std : : enable_if < std : : is_array < T > : : value > : : type > Containers : : StridedArrayView2D < const typename std : : remove_extent < T > : : type > field ( SceneField name ) const ;
/**
* @ brief Mutable data for given named field
* @ m_since_latest
*
* Like @ ref field ( SceneField ) const , but returns a mutable view .
* Expects that the scene is mutable .
* @ see @ ref dataFlags ( )
*/
template < class T , class = typename std : : enable_if < ! std : : is_array < T > : : value > : : type > Containers : : StridedArrayView1D < T > mutableField ( SceneField name ) ;
/**
* @ brief Mutable data for given named array field in a concrete type
* @ m_since_latest
*
* Same as above , except that it works with array fields instead - - -
* you ' re expected to select this overload by passing @ cpp T [ ] @ ce
* instead of @ cpp T @ ce . The second dimension is guaranteed to be
* contiguous and have the same size as reported by
* @ ref fieldArraySize ( SceneField ) const for given field .
*/
template < class T , class = typename std : : enable_if < std : : is_array < T > : : value > : : type > Containers : : StridedArrayView2D < typename std : : remove_extent < T > : : type > mutableField ( SceneField name ) ;
/**
* @ brief Object mapping for given field as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to the templated
* @ ref mapping ( UnsignedInt ) const that converts the field from an
* arbitrary underlying type and returns it in a newly - allocated array .
* The @ p fieldId is expected to be smaller than @ ref fieldCount ( ) .
*
* Note that , for common fields , you can also use the
* @ ref parentsAsArray ( ) , @ ref transformations2DAsArray ( ) ,
* @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors , which give out the object
* mapping together with the field data .
* @ see @ ref mappingInto ( UnsignedInt , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
*/
Containers : : Array < UnsignedInt > mappingAsArray ( UnsignedInt fieldId ) const ;
/**
* @ brief Object mapping for given field as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref mappingAsArray ( UnsignedInt ) const , but puts the result
* into @ p destination instead of allocating a new array . Expects that
* @ p destination is sized to contain exactly all data .
*
* Note that , for common fields , you can also use the
* @ ref parentsInto ( ) , @ ref transformations2DInto ( ) ,
* @ ref transformations3DInto ( ) ,
* @ ref translationsRotationsScalings2DInto ( ) ,
* @ ref translationsRotationsScalings3DInto ( ) ,
* @ ref meshesMaterialsInto ( ) , @ ref lightsInto ( ) , @ ref camerasInto ( ) ,
* @ ref skinsInto ( ) , @ ref importerStateInto ( ) accessors , which can give
* out the object mapping together with the field data .
*
* @ see @ ref fieldSize ( UnsignedInt ) const
*/
void mappingInto ( UnsignedInt fieldId , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
/**
* @ brief A subrange of object mapping for given field as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref mappingInto ( UnsignedInt , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
* extracts only a subrange of the object mapping defined by @ p offset
* and size of the @ p destination view , returning the count of items
* actually extracted . The @ p offset is expected to not be larger than
* the field size .
*
* Note that , for common fields , you can also use the
* @ ref parentsInto ( ) , @ ref transformations2DInto ( ) ,
* @ ref transformations3DInto ( ) ,
* @ ref translationsRotationsScalings2DInto ( ) ,
* @ ref translationsRotationsScalings3DInto ( ) ,
* @ ref meshesMaterialsInto ( ) , @ ref lightsInto ( ) , @ ref camerasInto ( ) ,
* @ ref skinsInto ( ) , @ ref importerStateInto ( ) accessors , which can give
* out the object mapping together with the field data .
*
* @ see @ ref fieldSize ( UnsignedInt ) const ,
* @ ref fieldObjectOffset ( UnsignedInt , UnsignedLong , std : : size_t ) const
*/
std : : size_t mappingInto ( UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
/**
* @ brief Object mapping for given named field as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to the templated
* @ ref mapping ( SceneField ) const that converts the field from an
* arbitrary underlying type and returns it in a newly - allocated array .
* The @ p fieldName is expected to exist .
*
* Note that , for common fields , you can also use the
* @ ref parentsAsArray ( ) , @ ref transformations2DAsArray ( ) ,
* @ ref transformations3DAsArray ( ) ,
* @ ref translationsRotationsScalings2DAsArray ( ) ,
* @ ref translationsRotationsScalings3DAsArray ( ) ,
* @ ref meshesMaterialsAsArray ( ) , @ ref lightsAsArray ( ) ,
* @ ref camerasAsArray ( ) , @ ref skinsAsArray ( ) ,
* @ ref importerStateAsArray ( ) accessors , which give out the object
* mapping together with the field data .
* @ see @ ref mappingInto ( SceneField , const Containers : : StridedArrayView1D < UnsignedInt > & ) const ,
* @ ref hasField ( )
*/
Containers : : Array < UnsignedInt > mappingAsArray ( SceneField fieldName ) const ;
/**
* @ brief Object mapping for given named field as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref mappingAsArray ( SceneField ) const , but puts the result into
* @ p destination instead of allocating a new array . Expects that
* @ p destination is sized to contain exactly all data .
*
* Note that , for common fields , you can also use the
* @ ref parentsInto ( ) , @ ref transformations2DInto ( ) ,
* @ ref transformations3DInto ( ) ,
* @ ref translationsRotationsScalings2DInto ( ) ,
* @ ref translationsRotationsScalings3DInto ( ) ,
* @ ref meshesMaterialsInto ( ) , @ ref lightsInto ( ) , @ ref camerasInto ( ) ,
* @ ref skinsInto ( ) , @ ref importerStateInto ( ) accessors , which can give
* out the object mapping together with the field data .
*
* @ see @ ref fieldSize ( SceneField ) const
*/
void mappingInto ( SceneField fieldName , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
/**
* @ brief A subrange of object mapping for given named field as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref mappingInto ( SceneField , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
* extracts only a subrange of the object mapping defined by @ p offset
* and size of the @ p destination view , returning the count of items
* actually extracted . The @ p offset is expected to not be larger than
* the field size .
*
* Note that , for common fields , you can also use the
* @ ref parentsInto ( ) , @ ref transformations2DInto ( ) ,
* @ ref transformations3DInto ( ) ,
* @ ref translationsRotationsScalings2DInto ( ) ,
* @ ref translationsRotationsScalings3DInto ( ) ,
* @ ref meshesMaterialsInto ( ) , @ ref lightsInto ( ) , @ ref camerasInto ( ) ,
* @ ref skinsInto ( ) , @ ref importerStateInto ( ) accessors , which can give
* out the object mapping together with the field data .
*
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t mappingInto ( SceneField fieldName , std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
/**
* @ brief Parent indices as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Parent as
* the argument . Converts the object mapping and the field from
* arbitrary underlying types and returns them in a newly - allocated
* array . The field is expected to exist .
* @ see @ ref parentsInto ( ) , @ ref hasField ( ) , @ ref parentFor ( ) ,
* @ ref childrenFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Int > > parentsAsArray ( ) const ;
/**
* @ brief Parent indices as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref parentsAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with @ ref SceneField : : Parent .
* @ see @ ref fieldSize ( SceneField ) const
*/
void parentsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Int > & fieldDestination ) const ;
/**
* @ brief A subrange of parent indices as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref parentsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Int > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t parentsInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Int > & fieldDestination ) const ;
/**
* @ brief 2 D transformations as 3 x3 float matrices
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with
* @ ref SceneField : : Transformation as the argument , or , if not present ,
* to a matrix created out of a subset of the
* @ ref SceneField : : Translation , @ ref SceneField : : Rotation and
* @ ref SceneField : : Scaling fields that ' s present . Converts the object
* mapping and the fields from arbitrary underlying types and returns
* them in a newly - allocated array . At least one of the fields is
* expected to exist and they are expected to have a type corresponding
* to 2 D , otherwise you ' re supposed to use
* @ ref transformations3DAsArray ( ) .
* @ see @ ref is2D ( ) , @ ref transformations2DInto ( ) , @ ref hasField ( ) ,
* @ ref fieldType ( SceneField ) const , @ ref transformation2DFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Matrix3 > > transformations2DAsArray ( ) const ;
/**
* @ brief 2 D transformations as 3 x3 float matrices into a pre - allocated view
* @ m_since_latest
*
* Like @ ref transformations2DAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with the first of the
* @ ref SceneField : : Transformation , @ ref SceneField : : Translation ,
* @ ref SceneField : : Rotation and @ ref SceneField : : Scaling fields that ' s
* present .
* @ see @ ref fieldSize ( SceneField ) const
*/
void transformations2DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Matrix3 > & fieldDestination ) const ;
/**
* @ brief A subrange of 2 D transformations as 3 x3 float matrices into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref transformations2DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Matrix3 > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t transformations2DInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Matrix3 > & fieldDestination ) const ;
/**
* @ brief 2 D transformations as float translation , rotation and scaling components
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Translation ,
* @ ref SceneField : : Rotation and @ ref SceneField : : Scaling as the
* arguments , as these are required to share the same object mapping .
* Converts the object mapping and the fields from arbitrary underlying
* types and returns them in a newly - allocated array . At least one of
* the fields is expected to exist and they are expected to have a type
* corresponding to 2 D , otherwise you ' re supposed to use
* @ ref translationsRotationsScalings3DAsArray ( ) . If the
* @ ref SceneField : : Translation field isn ' t present , the first returned
* value is a zero vector . If the @ relativeref { SceneField , Rotation }
* field isn ' t present , the second value is an identity rotation . If
* the @ relativeref { SceneField , Scaling } field isn ' t present , the third
* value is an identity scaling ( @ cpp 1.0f @ ce in both dimensions ) .
* @ see @ ref is2D ( ) , @ ref translationsRotationsScalings2DInto ( ) ,
* @ ref hasField ( ) , @ ref fieldType ( SceneField ) const ,
* @ ref translationRotationScaling2DFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Containers : : Triple < Vector2 , Complex , Vector2 > > > translationsRotationsScalings2DAsArray ( ) const ;
/**
* @ brief 2 D transformations as float translation , rotation and scaling components into a pre - allocated view
* @ m_since_latest
*
* Like @ ref translationsRotationsScalings2DAsArray ( ) , but puts the
* result into @ p mappingDestination , @ p translationDestination ,
* @ p rotationDestination and @ p scalingDestination instead of
* allocating a new array . Expects that each view is either
* @ cpp nullptr @ ce or sized to contain exactly all data . If
* @ p translationDestination , @ p rotationDestination and
* @ p scalingDestination are all @ cpp nullptr @ ce , the effect is the
* same as calling @ ref mappingInto ( ) with one of the
* @ ref SceneField : : Translation , @ ref SceneField : : Rotation and
* @ ref SceneField : : Scaling fields that ' s present .
* @ see @ ref fieldSize ( SceneField ) const
*/
void translationsRotationsScalings2DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Vector2 > & translationDestination , const Containers : : StridedArrayView1D < Complex > & rotationDestination , const Containers : : StridedArrayView1D < Vector2 > & scalingDestination ) const ;
/**
* @ brief A subrange of 2 D transformations as float translation , rotation and scaling components into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref translationsRotationsScalings2DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Vector2 > & , const Containers : : StridedArrayView1D < Complex > & , const Containers : : StridedArrayView1D < Vector2 > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t translationsRotationsScalings2DInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Vector2 > & translationDestination , const Containers : : StridedArrayView1D < Complex > & rotationDestination , const Containers : : StridedArrayView1D < Vector2 > & scalingDestination ) const ;
/**
* @ brief 3 D transformations as 4 x4 float matrices
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with
* @ ref SceneField : : Transformation as the argument , or , if not present ,
* to a matrix created out of a subset of the
* @ ref SceneField : : Translation , @ ref SceneField : : Rotation and
* @ ref SceneField : : Scaling fields that ' s present . Converts the object
* mapping and the fields from arbitrary underlying types and returns
* them in a newly - allocated array . At least one of the fields is
* expected to exist and they are expected to have a type corresponding
* to 3 D , otherwise you ' re supposed to use
* @ ref transformations2DAsArray ( ) .
* @ see @ ref is3D ( ) , @ ref transformations3DInto ( ) , @ ref hasField ( ) ,
* @ ref fieldType ( SceneField ) const , @ ref transformation3DFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Matrix4 > > transformations3DAsArray ( ) const ;
/**
* @ brief 3 D transformations as 4 x4 float matrices into a pre - allocated view
* @ m_since_latest
*
* Like @ ref transformations3DAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that the two views are either @ cpp nullptr @ ce
* or sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with the first of the
* @ ref SceneField : : Transformation , @ ref SceneField : : Translation ,
* @ ref SceneField : : Rotation and @ ref SceneField : : Scaling fields that ' s
* present .
* @ see @ ref fieldSize ( SceneField ) const
*/
void transformations3DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Matrix4 > & destination ) const ;
/**
* @ brief A subrange of 3 D transformations as 4 x4 float matrices into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref transformations3DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Matrix4 > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t transformations3DInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Matrix4 > & destination ) const ;
/**
* @ brief 3 D transformations as float translation , rotation and scaling components
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Translation ,
* @ ref SceneField : : Rotation and @ ref SceneField : : Scaling as the
* arguments , as these are required to share the same object mapping .
* Converts the object mapping and the fields from arbitrary underlying
* types and returns them in a newly - allocated array . At least one of
* the fields is expected to exist and they are expected to have a type
* corresponding to 3 D , otherwise you ' re supposed to use
* @ ref translationsRotationsScalings2DAsArray ( ) . If the
* @ ref SceneField : : Translation field isn ' t present , the first returned
* value is a zero vector . If the @ relativeref { SceneField , Rotation }
* field isn ' t present , the second value is an identity rotation . If
* the @ relativeref { SceneField , Scaling } field isn ' t present , the third
* value is an identity scaling ( @ cpp 1.0f @ ce in all dimensions ) .
* @ see @ ref is3D ( ) , @ ref translationsRotationsScalings3DInto ( ) ,
* @ ref hasField ( ) , @ ref fieldType ( SceneField ) const ,
* @ ref translationRotationScaling3DFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Containers : : Triple < Vector3 , Quaternion , Vector3 > > > translationsRotationsScalings3DAsArray ( ) const ;
/**
* @ brief 3 D transformations as float translation , rotation and scaling components into a pre - allocated view
* @ m_since_latest
*
* Like @ ref translationsRotationsScalings3DAsArray ( ) , but puts the
* result into @ p mappingDestination , @ p translationDestination ,
* @ p rotationDestination and @ p scalingDestination instead of
* allocating a new array . Expects that each view is either
* @ cpp nullptr @ ce or sized to contain exactly all data . If
* @ p translationDestination , @ p rotationDestination and
* @ p scalingDestination are all @ cpp nullptr @ ce , the effect is the
* same as calling @ ref mappingInto ( ) with one of the
* @ ref SceneField : : Translation , @ ref SceneField : : Rotation and
* @ ref SceneField : : Scaling fields that ' s present .
* @ see @ ref fieldSize ( SceneField ) const
*/
void translationsRotationsScalings3DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Vector3 > & translationDestination , const Containers : : StridedArrayView1D < Quaternion > & rotationDestination , const Containers : : StridedArrayView1D < Vector3 > & scalingDestination ) const ;
/**
* @ brief A subrange of 3 D transformations as float translation , rotation and scaling components into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref translationsRotationsScalings3DInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Vector3 > & , const Containers : : StridedArrayView1D < Quaternion > & , const Containers : : StridedArrayView1D < Vector3 > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t translationsRotationsScalings3DInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < Vector3 > & translationDestination , const Containers : : StridedArrayView1D < Quaternion > & rotationDestination , const Containers : : StridedArrayView1D < Vector3 > & scalingDestination ) const ;
/**
* @ brief Mesh and material IDs as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Mesh and
* @ ref SceneField : : MeshMaterial as the argument , as the two are
* required to share the same object mapping . Converts the object
* mapping and the fields from arbitrary underlying types and returns
* them in a newly - allocated array . The @ ref SceneField : : Mesh field is
* expected to exist , if @ ref SceneField : : MeshMaterial isn ' t present ,
* the second returned values are all @ cpp - 1 @ ce .
* @ see @ ref meshesMaterialsInto ( ) , @ ref hasField ( ) ,
* @ ref meshesMaterialsFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Containers : : Pair < UnsignedInt , Int > > > meshesMaterialsAsArray ( ) const ;
/**
* @ brief Mesh and material IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref meshesMaterialsAsArray ( ) , but puts the results into
* @ p mappingDestination , @ p meshDestination and
* @ p meshMaterialDestination instead of allocating a new array .
* Expects that each view is either @ cpp nullptr @ ce or sized to
* contain exactly all data . If @ p meshDestination and
* @ p meshMaterialDestination are both @ cpp nullptr @ ce , the effect is
* the same as calling @ ref mappingInto ( ) with @ ref SceneField : : Mesh .
* @ see @ ref fieldSize ( SceneField ) const
*/
void meshesMaterialsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & meshDestination , const Containers : : StridedArrayView1D < Int > & meshMaterialDestination ) const ;
/**
* @ brief A subrange of mesh and material IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref meshesMaterialsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < Int > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t meshesMaterialsInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & meshDestination , const Containers : : StridedArrayView1D < Int > & meshMaterialsDestination ) const ;
/**
* @ brief Light IDs as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Light as the
* argument . Converts the object mapping and the field from arbitrary
* underlying types and returns them in a newly - allocated array . The
* field is expected to exist .
* @ see @ ref lightsInto ( ) , @ ref hasField ( ) , @ ref lightsFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , UnsignedInt > > lightsAsArray ( ) const ;
/**
* @ brief Light IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref lightsAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref lightsInto ( ) with @ ref SceneField : : Light .
* @ see @ ref fieldSize ( SceneField ) const
*/
void lightsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief A subrange of light IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref lightsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t lightsInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief Camera IDs as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Camera as
* the argument . Converts the object mapping and the field from
* arbitrary underlying types and returns them in a newly - allocated
* array . The field is expected to exist .
* @ see @ ref camerasInto ( ) , @ ref hasField ( ) , @ ref camerasFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , UnsignedInt > > camerasAsArray ( ) const ;
/**
* @ brief Camera IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref camerasAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with @ ref SceneField : : Camera .
* @ see @ ref fieldSize ( SceneField ) const
*/
void camerasInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief A subrange of camera IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref camerasInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t camerasInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief Skin IDs as 32 - bit integers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : Skin as the
* argument . Converts the object mapping and the field from arbitrary
* underlying types and returns them in a newly - allocated array . The
* field is expected to exist .
* @ see @ ref skinsInto ( ) , @ ref hasField ( ) , @ ref skinsFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , UnsignedInt > > skinsAsArray ( ) const ;
/**
* @ brief Skin IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref skinsAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating a
* new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with @ ref SceneField : : Skin .
* @ see @ ref fieldSize ( SceneField ) const
*/
void skinsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief A subrange of skin IDs as 32 - bit integers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref skinsInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < UnsignedInt > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t skinsInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < UnsignedInt > & fieldDestination ) const ;
/**
* @ brief Per - object importer state as ` void ` pointers
* @ m_since_latest
*
* Convenience alternative to @ ref mapping ( SceneField ) const together
* with @ ref field ( SceneField ) const with @ ref SceneField : : ImporterState
* as the argument . Converts the object mapping and the field from
* arbitrary underlying types and returns them in a newly - allocated
* array . The field is expected to exist .
*
* This is different from @ ref importerState ( ) , which returns importer
* state for the scene itself , not particular objects .
* @ see @ ref importerStateInto ( ) , @ ref hasField ( ) , @ ref importerStateFor ( )
*/
Containers : : Array < Containers : : Pair < UnsignedInt , const void * > > importerStateAsArray ( ) const ;
/**
* @ brief Per - object importer state as ` void ` pointers into a pre - allocated view
* @ m_since_latest
*
* Like @ ref importerStateAsArray ( ) , but puts the result into
* @ p mappingDestination and @ p fieldDestination instead of allocating
* a new array . Expects that each view is either @ cpp nullptr @ ce or
* sized to contain exactly all data . If @ p fieldDestination is
* @ cpp nullptr @ ce , the effect is the same as calling
* @ ref mappingInto ( ) with @ ref SceneField : : ImporterState .
* @ see @ ref fieldSize ( SceneField ) const
*/
void importerStateInto ( const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < const void * > & fieldDestination ) const ;
/**
* @ brief A subrange of per - object importer state as ` void ` pointers into a pre - allocated view
* @ m_since_latest
*
* Compared to @ ref importerStateInto ( const Containers : : StridedArrayView1D < UnsignedInt > & , const Containers : : StridedArrayView1D < const void * > & ) const
* extracts only a subrange of the field defined by @ p offset and size
* of the views , returning the count of items actually extracted . The
* @ p offset is expected to not be larger than the field size , views
* that are not @ cpp nullptr @ ce are expected to have the same size .
* @ see @ ref fieldSize ( SceneField ) const ,
* @ ref fieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
*/
std : : size_t importerStateInto ( std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & mappingDestination , const Containers : : StridedArrayView1D < const void * > & fieldDestination ) const ;
/**
* @ brief Parent for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : Parent field for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref parentsAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving parent
* info for many objects it ' s recommended to access the field data
* directly .
*
* If the @ ref SceneField : : Parent field is not present or if there ' s no
* parent for @ p object , returns @ ref Containers : : NullOpt . If @ p object
* is top - level , returns @ cpp - 1 @ ce .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref childrenFor ( )
*/
Containers : : Optional < Long > parentFor ( UnsignedLong object ) const ;
/**
* @ brief Children for given object
* @ m_since_latest
*
* Looks up @ p object in the object mapping array for
* @ ref SceneField : : Parent equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const ,
* converts the fields from an arbitrary underlying type the same way
* as @ ref parentsAsArray ( ) , returning a list of all object IDs that
* have it listed as the parent . See the lookup function documentation
* for operation complexity - - - for retrieving parent / child info for
* many objects it ' s recommended to access the field data directly .
*
* If the @ ref SceneField : : Parent field doesn ' t exist or there are no
* objects which would have @ p object listed as their parent , returns
* an empty array . Pass @ cpp - 1 @ ce to get a list of top - level objects .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref parentFor ( )
*/
Containers : : Array < UnsignedLong > childrenFor ( Long object ) const ;
/**
* @ brief 2 D transformation for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : Transformation field for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* or combines it from a @ ref SceneField : : Translation ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } , converting the fields from
* arbitrary underlying types the same way as
* @ ref transformations2DAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving
* transformation info for many objects it ' s recommended to access the
* field data directly .
*
* If neither @ ref SceneField : : Transformation nor any of
* @ ref SceneField : : Translation , @ relativeref { SceneField , Rotation } or
* @ relativeref { SceneField , Scaling } is present , the fields represent a
* 3 D transformation or there ' s no transformation for @ p object ,
* returns @ ref Containers : : NullOpt .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref translationRotationScaling2DFor ( )
*/
Containers : : Optional < Matrix3 > transformation2DFor ( UnsignedLong object ) const ;
/**
* @ brief 2 D translation , rotation and scaling for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : Translation ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } fields for @ p object equivalently
* to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the fields from arbitrary underlying types the
* same way as @ ref translationsRotationsScalings2DAsArray ( ) . See the
* lookup function documentation for operation complexity - - - for
* retrieving transformation info for many objects it ' s recommended to
* access the field data directly .
*
* If the @ ref SceneField : : Translation field isn ' t present , the first
* returned value is a zero vector . If the
* @ relativeref { SceneField , Rotation } field isn ' t present , the second
* value is an identity rotation . If the @ relativeref { SceneField , Scaling }
* field isn ' t present , the third value is an identity scaling
* ( @ cpp 1.0f @ ce in both dimensions ) . If neither of those fields is
* present , if any of the fields represents a 3 D transformation or if
* there ' s no transformation for @ p object , returns
* @ ref Containers : : NullOpt .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref transformation2DFor ( )
*/
Containers : : Optional < Containers : : Triple < Vector2 , Complex , Vector2 > > translationRotationScaling2DFor ( UnsignedLong object ) const ;
/**
* @ brief 3 D transformation for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : Transformation field for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* or combines it from a @ ref SceneField : : Translation ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } , converting the fields from
* arbitrary underlying types the same way as
* @ ref transformations3DAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving
* transformation info for many objects it ' s recommended to access the
* field data directly .
*
* If neither @ ref SceneField : : Transformation nor any of
* @ ref SceneField : : Translation , @ relativeref { SceneField , Rotation } or
* @ relativeref { SceneField , Scaling } is present , the fields represent a
* 2 D transformation or there ' s no transformation for @ p object ,
* returns @ ref Containers : : NullOpt .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref translationRotationScaling3DFor ( )
*/
Containers : : Optional < Matrix4 > transformation3DFor ( UnsignedLong object ) const ;
/**
* @ brief 3 D translation , rotation and scaling for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : Translation ,
* @ relativeref { SceneField , Rotation } and
* @ relativeref { SceneField , Scaling } fields for @ p object equivalently
* to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the fields from arbitrary underlying types the
* same way as @ ref translationsRotationsScalings2DAsArray ( ) . See the
* lookup function documentation for operation complexity - - - for
* retrieving transformation info for many objects it ' s recommended to
* access the field data directly .
*
* If the @ ref SceneField : : Translation field isn ' t present , the first
* returned value is a zero vector . If the
* @ relativeref { SceneField , Rotation } field isn ' t present , the second
* value is an identity rotation . If the @ relativeref { SceneField , Scaling }
* field isn ' t present , the third value is an identity scaling
* ( @ cpp 1.0f @ ce in all dimensions ) . If neither of those fields is
* present , if any of the fields represents a 2 D transformation or if
* there ' s no transformation for @ p object , returns
* @ ref Containers : : NullOpt .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
* @ see @ ref transformation3DFor ( )
*/
Containers : : Optional < Containers : : Triple < Vector3 , Quaternion , Vector3 > > translationRotationScaling3DFor ( UnsignedLong object ) const ;
/**
* @ brief Meshes and materials for given object
* @ m_since_latest
*
* Looks up all @ ref SceneField : : Mesh and @ ref SceneField : : MeshMaterial
* @ relativeref { SceneField , Scaling } fields for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref meshesMaterialsAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving mesh and
* material info for many objects it ' s recommended to access the field
* data directly .
*
* If the @ ref SceneField : : MeshMaterial field is not present , the
* second returned value is always @ cpp - 1 @ ce . If
* @ ref SceneField : : Mesh is not present or if there ' s no mesh for
* @ p object , returns an empty array .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
*/
Containers : : Array < Containers : : Pair < UnsignedInt , Int > > meshesMaterialsFor ( UnsignedLong object ) const ;
/**
* @ brief Lights for given object
* @ m_since_latest
*
* Looks up all @ ref SceneField : : Light fields for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref lightsAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving light info
* for many objects it ' s recommended to access the field data directly .
*
* If the @ ref SceneField : : Light field is not present or if there ' s no
* light for @ p object , returns an empty array .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
*/
Containers : : Array < UnsignedInt > lightsFor ( UnsignedLong object ) const ;
/**
* @ brief Cameras for given object
* @ m_since_latest
*
* Looks up all @ ref SceneField : : Camera fields for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref camerasAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving camera
* info for many objects it ' s recommended to access the field data
* directly .
*
* If the @ ref SceneField : : Camera field is not present or if there ' s no
* camera for @ p object , returns an empty array .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
*/
Containers : : Array < UnsignedInt > camerasFor ( UnsignedLong object ) const ;
/**
* @ brief Skins for given object
* @ m_since_latest
*
* Looks up all @ ref SceneField : : Skin fields for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref skinsAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving skin info
* for many objects it ' s recommended to access the field data directly .
*
* If the @ ref SceneField : : Skin field is not present or if there ' s no
* skin for @ p object , returns an empty array .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
*/
Containers : : Array < UnsignedInt > skinsFor ( UnsignedLong object ) const ;
/**
* @ brief Importer state for given object
* @ m_since_latest
*
* Looks up the @ ref SceneField : : ImporterState field for @ p object
* equivalently to @ ref findFieldObjectOffset ( SceneField , UnsignedLong , std : : size_t ) const
* and then converts the field from an arbitrary underlying type the
* same way as @ ref importerStateAsArray ( ) . See the lookup function
* documentation for operation complexity - - - for retrieving importer
* state info for many objects it ' s recommended to access the field
* data directly .
*
* If the @ ref SceneField : : ImporterState field is not present or if
* there ' s no importer state for @ p object , returns
* @ ref Containers : : NullOpt .
*
* The @ p object is expected to be less than @ ref mappingBound ( ) .
*/
Containers : : Optional < const void * > importerStateFor ( UnsignedLong object ) const ;
# ifdef MAGNUM_BUILD_DEPRECATED
/**
* @ brief Two - dimensional root scene objects
* @ m_deprecated_since_latest Use @ ref childrenFor ( ) with ` - 1 ` passed
* as the @ p object argument .
*/
CORRADE_DEPRECATED ( " use childrenFor() instead " ) std : : vector < UnsignedInt > children2D ( ) const ;
/**
* @ brief Three - dimensional root scene objects
* @ m_deprecated_since_latest Use @ ref childrenFor ( ) with ` - 1 ` passed
* as the @ p object argument .
*/
CORRADE_DEPRECATED ( " use childrenFor() instead " ) std : : vector < UnsignedInt > children3D ( ) const ;
# endif
/**
* @ brief Release field data storage
* @ m_since_latest
*
* Releases the ownership of the field data array and resets internal
* field - related state to default . The scene then behaves like if it
* has no fields ( but it can still have non - empty data ) . Note that the
* returned array has a custom no - op deleter when the data are not
* owned by the scene , and while the returned array type is mutable ,
* the actual memory might be not . Additionally , the returned
* @ ref SceneFieldData instances may have different data pointers and
* sizes than what ' s returned by the @ ref field ( ) and
* @ ref fieldData ( UnsignedInt ) const accessors as some of them might
* have @ ref SceneFieldFlag : : OffsetOnly - - - use this function only if
* you * really * know what are you doing .
* @ see @ ref fieldData ( ) , @ ref SceneFieldData : : flags ( )
*/
Containers : : Array < SceneFieldData > releaseFieldData ( ) ;
/**
* @ brief Release data storage
* @ m_since_latest
*
* Releases the ownership of the data array and resets internal
* field - related state to default . The scene then behaves like it has
* no fields and no data . If you want to release field data as well ,
* first call @ ref releaseFieldData ( ) and then this function .
*
* Note that the returned array has a custom no - op deleter when the
* data are not owned by the scene , and while the returned array type
* is mutable , the actual memory might be not .
* @ see @ ref data ( ) , @ ref dataFlags ( )
*/
Containers : : Array < char > releaseData ( ) ;
/**
* @ brief Importer - specific state
*
* Scene - specific importer state . For object - specific importer state
* look for the @ ref SceneField : : ImporterState field or access it via
* @ ref importerStateAsArray ( ) , @ ref importerStateFor ( ) and related
* convenience functions . See @ ref AbstractImporter : : importerState ( )
* for general information about importer state pointers .
*/
const void * importerState ( ) const { return _importerState ; }
private :
/* For custom deleter checks. Not done in the constructors here because
the restriction is pointless when used outside of plugin
implementations . */
friend AbstractImporter ;
/* Internal helper without the extra overhead from Optional, returns
~ UnsignedInt { } on failure */
UnsignedInt findFieldIdInternal ( SceneField name ) const ;
/* Returns the offset at which `object` is for field at index `id`, or
the end offset if the object is not found . The returned offset can
be then passed to fieldData { Mapping , Field } ViewInternal ( ) . */
MAGNUM_TRADE_LOCAL std : : size_t findFieldObjectOffsetInternal ( const SceneFieldData & field , UnsignedLong object , std : : size_t offset ) const ;
/* Like objects() / field(), but returning just a 1D view, sliced from
offset to offset + size . The parameterless overloads are equal to
offset = 0 and size = field . size ( ) . */
MAGNUM_TRADE_LOCAL Containers : : StridedArrayView1D < const void > fieldDataMappingViewInternal ( const SceneFieldData & field , std : : size_t offset , std : : size_t size ) const ;
MAGNUM_TRADE_LOCAL Containers : : StridedArrayView1D < const void > fieldDataMappingViewInternal ( const SceneFieldData & field ) const ;
MAGNUM_TRADE_LOCAL Containers : : StridedArrayView1D < const void > fieldDataFieldViewInternal ( const SceneFieldData & field , std : : size_t offset , std : : size_t size ) const ;
MAGNUM_TRADE_LOCAL Containers : : StridedArrayView1D < const void > fieldDataFieldViewInternal ( const SceneFieldData & field ) const ;
# ifndef CORRADE_NO_ASSERT
template < class T > bool checkFieldTypeCompatibility ( const SceneFieldData & attribute , const char * prefix ) const ;
# endif
MAGNUM_TRADE_LOCAL void mappingIntoInternal ( UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
MAGNUM_TRADE_LOCAL void parentsIntoInternal ( UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Int > & destination ) const ;
MAGNUM_TRADE_LOCAL UnsignedInt findTransformFields ( UnsignedInt & transformationFieldId , UnsignedInt & translationFieldId , UnsignedInt & rotationFieldId , UnsignedInt & scalingFieldId ) const ;
MAGNUM_TRADE_LOCAL UnsignedInt findTranslationRotationScalingFields ( UnsignedInt & translationFieldId , UnsignedInt & rotationFieldId , UnsignedInt & scalingFieldId ) const ;
MAGNUM_TRADE_LOCAL void transformations2DIntoInternal ( UnsignedInt transformationFieldId , UnsignedInt translationFieldId , UnsignedInt rotationFieldId , UnsignedInt scalingFieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Matrix3 > & destination ) const ;
MAGNUM_TRADE_LOCAL void translationsRotationsScalings2DIntoInternal ( UnsignedInt translationFieldId , UnsignedInt rotationFieldId , UnsignedInt scalingFieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Vector2 > & translationDestination , const Containers : : StridedArrayView1D < Complex > & rotationDestination , const Containers : : StridedArrayView1D < Vector2 > & scalingDestination ) const ;
MAGNUM_TRADE_LOCAL void transformations3DIntoInternal ( UnsignedInt transformationFieldId , UnsignedInt translationFieldId , UnsignedInt rotationFieldId , UnsignedInt scalingFieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Matrix4 > & destination ) const ;
MAGNUM_TRADE_LOCAL void translationsRotationsScalings3DIntoInternal ( UnsignedInt translationFieldId , UnsignedInt rotationFieldId , UnsignedInt scalingFieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Vector3 > & translationDestination , const Containers : : StridedArrayView1D < Quaternion > & rotationDestination , const Containers : : StridedArrayView1D < Vector3 > & scalingDestination ) const ;
MAGNUM_TRADE_LOCAL void unsignedIndexFieldIntoInternal ( const UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & destination ) const ;
MAGNUM_TRADE_LOCAL void indexFieldIntoInternal ( const UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < Int > & destination ) const ;
MAGNUM_TRADE_LOCAL Containers : : Array < Containers : : Pair < UnsignedInt , UnsignedInt > > unsignedIndexFieldAsArrayInternal ( const UnsignedInt fieldId ) const ;
MAGNUM_TRADE_LOCAL void meshesMaterialsIntoInternal ( UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < UnsignedInt > & meshDestination , const Containers : : StridedArrayView1D < Int > & meshMaterialDestination ) const ;
MAGNUM_TRADE_LOCAL void importerStateIntoInternal ( const UnsignedInt fieldId , std : : size_t offset , const Containers : : StridedArrayView1D < const void * > & destination ) const ;
DataFlags _dataFlags ;
SceneMappingType _mappingType ;
UnsignedByte _dimensions ;
/* 1/5 bytes free */
UnsignedLong _mappingBound ;
const void * _importerState ;
Containers : : Array < SceneFieldData > _fields ;
Containers : : Array < char > _data ;
} ;
namespace Implementation {
/* Making this a struct because there can't be partial specializations for
a function ( which we may need for pointers , matrix / vector subclasses
etc ) */
template < class T > struct SceneFieldTypeFor {
static_assert ( sizeof ( T ) = = 0 , " unsupported field type " ) ;
} ;
# ifndef DOXYGEN_GENERATING_OUTPUT
# define _c(type_) template<> struct SceneFieldTypeFor<type_> { \
constexpr static SceneFieldType type ( ) { \
return SceneFieldType : : type_ ; \
} \
} ;
/* Bool needs a special type */
_c ( Float )
_c ( Half )
_c ( Double )
_c ( UnsignedByte )
_c ( Byte )
_c ( UnsignedShort )
_c ( Short )
_c ( UnsignedInt )
_c ( Int )
_c ( UnsignedLong )
_c ( Long )
_c ( Vector2 )
_c ( Vector2h )
_c ( Vector2d )
_c ( Vector2ub )
_c ( Vector2b )
_c ( Vector2us )
_c ( Vector2s )
_c ( Vector2ui )
_c ( Vector2i )
_c ( Vector3 )
_c ( Vector3h )
_c ( Vector3d )
_c ( Vector3ub )
_c ( Vector3b )
_c ( Vector3us )
_c ( Vector3s )
_c ( Vector3ui )
_c ( Vector3i )
_c ( Vector4 )
_c ( Vector4h )
_c ( Vector4d )
_c ( Vector4ub )
_c ( Vector4b )
_c ( Vector4us )
_c ( Vector4s )
_c ( Vector4ui )
_c ( Vector4i )
_c ( Matrix2x2 )
_c ( Matrix2x2h )
_c ( Matrix2x2d )
_c ( Matrix2x3 )
_c ( Matrix2x3h )
_c ( Matrix2x3d )
_c ( Matrix2x4 )
_c ( Matrix2x4h )
_c ( Matrix2x4d )
_c ( Matrix3x2 )
_c ( Matrix3x2h )
_c ( Matrix3x2d )
_c ( Matrix3x3 )
_c ( Matrix3x3h )
_c ( Matrix3x3d )
_c ( Matrix3x4 )
_c ( Matrix3x4h )
_c ( Matrix3x4d )
_c ( Matrix4x2 )
_c ( Matrix4x2h )
_c ( Matrix4x2d )
_c ( Matrix4x3 )
_c ( Matrix4x3h )
_c ( Matrix4x3d )
_c ( Matrix4x4 )
_c ( Matrix4x4h )
_c ( Matrix4x4d )
_c ( Range1D )
_c ( Range1Dh )
_c ( Range1Dd )
_c ( Range1Di )
_c ( Range2D )
_c ( Range2Dh )
_c ( Range2Dd )
_c ( Range2Di )
_c ( Range3D )
_c ( Range3Dh )
_c ( Range3Dd )
_c ( Range3Di )
_c ( Complex )
_c ( Complexd )
_c ( DualComplex )
_c ( DualComplexd )
_c ( Quaternion )
_c ( Quaterniond )
_c ( DualQuaternion )
_c ( DualQuaterniond )
_c ( Deg )
_c ( Degh )
_c ( Degd )
_c ( Rad )
_c ( Radh )
_c ( Radd )
# undef _c
# endif
/** @todo this doesn't handle RectangleMatrix<size, size, T> and Vector<size, T> at the moment, do we need those? */
template < class T > struct SceneFieldTypeFor < Math : : Color3 < T > > : SceneFieldTypeFor < Math : : Vector3 < T > > { } ;
template < class T > struct SceneFieldTypeFor < Math : : Color4 < T > > : SceneFieldTypeFor < Math : : Vector4 < T > > { } ;
template < class T > struct SceneFieldTypeFor < Math : : Matrix3 < T > > : SceneFieldTypeFor < Math : : Matrix3x3 < T > > { } ;
template < class T > struct SceneFieldTypeFor < Math : : Matrix4 < T > > : SceneFieldTypeFor < Math : : Matrix4x4 < T > > { } ;
template < class T > struct SceneFieldTypeFor < const T * > {
constexpr static SceneFieldType type ( ) {
return SceneFieldType : : Pointer ;
}
} ;
template < class T > struct SceneFieldTypeFor < T * > {
constexpr static SceneFieldType type ( ) {
return SceneFieldType : : MutablePointer ;
}
} ;
template < class T > constexpr SceneMappingType sceneMappingTypeFor ( ) {
static_assert ( sizeof ( T ) = = 0 , " unsupported mapping type " ) ;
return { } ;
}
# ifndef DOXYGEN_GENERATING_OUTPUT
# define _c(type) \
template < > constexpr SceneMappingType sceneMappingTypeFor < type > ( ) { return SceneMappingType : : type ; }
_c ( UnsignedByte )
_c ( UnsignedShort )
_c ( UnsignedInt )
_c ( UnsignedLong )
# undef _c
# endif
constexpr bool isSceneFieldTypeCompatibleWithField ( SceneField name , SceneFieldType type ) {
return
/* Named fields are restricted so we can decode them */
( name = = SceneField : : Parent & &
( type = = SceneFieldType : : Byte | |
type = = SceneFieldType : : Short | |
type = = SceneFieldType : : Int | |
type = = SceneFieldType : : Long ) ) | |
( name = = SceneField : : Transformation & &
( type = = SceneFieldType : : Matrix3x3 | |
type = = SceneFieldType : : Matrix3x3d | |
type = = SceneFieldType : : Matrix4x4 | |
type = = SceneFieldType : : Matrix4x4d | |
type = = SceneFieldType : : Matrix3x2 | |
type = = SceneFieldType : : Matrix3x2d | |
type = = SceneFieldType : : Matrix4x3 | |
type = = SceneFieldType : : Matrix4x3d | |
type = = SceneFieldType : : DualComplex | |
type = = SceneFieldType : : DualComplexd | |
type = = SceneFieldType : : DualQuaternion | |
type = = SceneFieldType : : DualQuaterniond ) ) | |
( ( name = = SceneField : : Translation | |
name = = SceneField : : Scaling ) & &
( type = = SceneFieldType : : Vector2 | |
type = = SceneFieldType : : Vector2d | |
type = = SceneFieldType : : Vector3 | |
type = = SceneFieldType : : Vector3d ) ) | |
( name = = SceneField : : Rotation & &
( type = = SceneFieldType : : Complex | |
type = = SceneFieldType : : Complexd | |
type = = SceneFieldType : : Quaternion | |
type = = SceneFieldType : : Quaterniond ) ) | |
( ( name = = SceneField : : Mesh | |
name = = SceneField : : Light | |
name = = SceneField : : Camera | |
name = = SceneField : : Skin ) & &
( type = = SceneFieldType : : UnsignedByte | |
type = = SceneFieldType : : UnsignedShort | |
type = = SceneFieldType : : UnsignedInt ) ) | |
( name = = SceneField : : MeshMaterial & &
( type = = SceneFieldType : : Byte | |
type = = SceneFieldType : : Short | |
type = = SceneFieldType : : Int ) ) | |
( name = = SceneField : : ImporterState & &
( type = = SceneFieldType : : Pointer | |
type = = SceneFieldType : : MutablePointer ) ) | |
/* Custom fields can be anything */
isSceneFieldCustom ( name ) ;
}
constexpr bool isSceneFieldArrayAllowed ( SceneField name ) {
return isSceneFieldCustom ( name ) ;
}
}
constexpr SceneFieldData : : SceneFieldData ( const SceneField name , const SceneMappingType mappingType , const Containers : : StridedArrayView1D < const void > & mappingData , const SceneFieldType fieldType , const Containers : : StridedArrayView1D < const void > & fieldData , const UnsignedShort fieldArraySize , const SceneFieldFlags flags ) noexcept :
_size { ( CORRADE_CONSTEXPR_ASSERT ( mappingData . size ( ) = = fieldData . size ( ) ,
" Trade::SceneFieldData: expected " < < name < < " mapping and field view to have the same size but got " < < mappingData . size ( ) < < " and " < < fieldData . size ( ) ) , mappingData . size ( ) ) } ,
_name { ( CORRADE_CONSTEXPR_ASSERT ( Implementation : : isSceneFieldTypeCompatibleWithField ( name , fieldType ) ,
" Trade::SceneFieldData: " < < fieldType < < " is not a valid type for " < < name ) , name ) } ,
_flags { ( CORRADE_CONSTEXPR_ASSERT ( ! ( flags & SceneFieldFlag : : OffsetOnly ) ,
" Trade::SceneFieldData: can't pass Trade::SceneFieldFlag::OffsetOnly for a view " ) , flags ) } ,
_mappingType { mappingType } ,
_mappingStride { ( CORRADE_CONSTEXPR_ASSERT ( mappingData . stride ( ) > = - 32768 & & mappingData . stride ( ) < = 32767 ,
" Trade::SceneFieldData: expected mapping view stride to fit into 16 bits, but got " < < mappingData . stride ( ) ) , Short ( mappingData . stride ( ) ) ) } ,
_mappingData { mappingData . data ( ) } ,
_fieldType { fieldType } ,
_fieldStride { ( CORRADE_CONSTEXPR_ASSERT ( fieldData . stride ( ) > = - 32768 & & fieldData . stride ( ) < = 32767 ,
" Trade::SceneFieldData: expected field view stride to fit into 16 bits, but got " < < fieldData . stride ( ) ) , Short ( fieldData . stride ( ) ) ) } ,
_fieldArraySize { ( CORRADE_CONSTEXPR_ASSERT ( ! fieldArraySize | | Implementation : : isSceneFieldArrayAllowed ( name ) ,
" Trade::SceneFieldData: " < < name < < " can't be an array field " ) , fieldArraySize ) } ,
_fieldData { fieldData . data ( ) } { }
template < class T , class U > constexpr SceneFieldData : : SceneFieldData ( const SceneField name , const Containers : : StridedArrayView1D < T > & mappingData , const Containers : : StridedArrayView1D < U > & fieldData , const SceneFieldFlags flags ) noexcept : SceneFieldData { name , Implementation : : sceneMappingTypeFor < typename std : : remove_const < T > : : type > ( ) , mappingData , Implementation : : SceneFieldTypeFor < typename std : : remove_const < U > : : type > : : type ( ) , fieldData , 0 , flags } { }
template < class T , class U > constexpr SceneFieldData : : SceneFieldData ( const SceneField name , const Containers : : StridedArrayView1D < T > & mappingData , const Containers : : StridedArrayView2D < U > & fieldData , const SceneFieldFlags flags ) noexcept : SceneFieldData {
name ,
Implementation : : sceneMappingTypeFor < typename std : : remove_const < T > : : type > ( ) ,
mappingData ,
Implementation : : SceneFieldTypeFor < typename std : : remove_const < U > : : type > : : type ( ) ,
Containers : : StridedArrayView1D < const void > { { fieldData . data ( ) , ~ std : : size_t { } } , fieldData . size ( ) [ 0 ] , fieldData . stride ( ) [ 0 ] } ,
/* Not using isContiguous<1>() as that's not constexpr */
( CORRADE_CONSTEXPR_ASSERT ( fieldData . stride ( ) [ 1 ] = = sizeof ( U ) , " Trade::SceneFieldData: second field view dimension is not contiguous " ) , UnsignedShort ( fieldData . size ( ) [ 1 ] ) ) ,
flags
} { }
constexpr SceneFieldData : : SceneFieldData ( const SceneField name , const std : : size_t size , const SceneMappingType mappingType , const std : : size_t mappingOffset , const std : : ptrdiff_t mappingStride , const SceneFieldType fieldType , const std : : size_t fieldOffset , const std : : ptrdiff_t fieldStride , const UnsignedShort fieldArraySize , const SceneFieldFlags flags ) noexcept :
_size { size } ,
_name { ( CORRADE_CONSTEXPR_ASSERT ( Implementation : : isSceneFieldTypeCompatibleWithField ( name , fieldType ) ,
" Trade::SceneFieldData: " < < fieldType < < " is not a valid type for " < < name ) , name ) } ,
_flags { flags | SceneFieldFlag : : OffsetOnly } ,
_mappingType { mappingType } ,
_mappingStride { ( CORRADE_CONSTEXPR_ASSERT ( mappingStride > = - 32768 & & mappingStride < = 32767 ,
" Trade::SceneFieldData: expected mapping view stride to fit into 16 bits, but got " < < mappingStride ) , Short ( mappingStride ) ) } ,
_mappingData { mappingOffset } ,
_fieldType { fieldType } ,
_fieldStride { ( CORRADE_CONSTEXPR_ASSERT ( fieldStride > = - 32768 & & fieldStride < = 32767 ,
" Trade::SceneFieldData: expected field view stride to fit into 16 bits, but got " < < fieldStride ) , Short ( fieldStride ) ) } ,
_fieldArraySize { ( CORRADE_CONSTEXPR_ASSERT ( ! fieldArraySize | | Implementation : : isSceneFieldArrayAllowed ( name ) ,
" Trade::SceneFieldData: " < < name < < " can't be an array field " ) , fieldArraySize ) } ,
_fieldData { fieldOffset } { }
template < class T > Containers : : StridedArrayView1D < const T > SceneData : : mapping ( const UnsignedInt fieldId ) const {
Containers : : StridedArrayView2D < const char > data = mapping ( fieldId ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
CORRADE_ASSERT ( Implementation : : sceneMappingTypeFor < T > ( ) = = _mappingType ,
" Trade::SceneData::mapping(): mapping is " < < _mappingType < < " but requested " < < Implementation : : sceneMappingTypeFor < T > ( ) , { } ) ;
return Containers : : arrayCast < 1 , const T > ( data ) ;
}
template < class T > Containers : : StridedArrayView1D < T > SceneData : : mutableMapping ( const UnsignedInt fieldId ) {
Containers : : StridedArrayView2D < char > data = mutableMapping ( fieldId ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
CORRADE_ASSERT ( Implementation : : sceneMappingTypeFor < T > ( ) = = _mappingType ,
" Trade::SceneData::mutableMapping(): mapping is " < < _mappingType < < " but requested " < < Implementation : : sceneMappingTypeFor < T > ( ) , { } ) ;
return Containers : : arrayCast < 1 , T > ( data ) ;
}
template < class T > Containers : : StridedArrayView1D < const T > SceneData : : mapping ( const SceneField fieldName ) const {
Containers : : StridedArrayView2D < const char > data = mapping ( fieldName ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
CORRADE_ASSERT ( Implementation : : sceneMappingTypeFor < T > ( ) = = _mappingType ,
" Trade::SceneData::mapping(): mapping is " < < _mappingType < < " but requested " < < Implementation : : sceneMappingTypeFor < T > ( ) , { } ) ;
return Containers : : arrayCast < 1 , const T > ( data ) ;
}
template < class T > Containers : : StridedArrayView1D < T > SceneData : : mutableMapping ( const SceneField fieldName ) {
Containers : : StridedArrayView2D < char > data = mutableMapping ( fieldName ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
CORRADE_ASSERT ( Implementation : : sceneMappingTypeFor < T > ( ) = = _mappingType ,
" Trade::SceneData::mutableMapping(): mapping is " < < _mappingType < < " but requested " < < Implementation : : sceneMappingTypeFor < T > ( ) , { } ) ;
return Containers : : arrayCast < 1 , T > ( data ) ;
}
# ifndef CORRADE_NO_ASSERT
template < class T > bool SceneData : : checkFieldTypeCompatibility ( const SceneFieldData & field , const char * const prefix ) const {
CORRADE_ASSERT ( Implementation : : SceneFieldTypeFor < typename std : : remove_extent < T > : : type > : : type ( ) = = field . _fieldType ,
prefix < < field . _name < < " is " < < field . _fieldType < < " but requested a type equivalent to " < < Implementation : : SceneFieldTypeFor < typename std : : remove_extent < T > : : type > : : type ( ) , false ) ;
if ( field . _fieldArraySize ) CORRADE_ASSERT ( std : : is_array < T > : : value ,
prefix < < field . _name < < " is an array field, use T[] to access it " , false ) ;
else CORRADE_ASSERT ( ! std : : is_array < T > : : value ,
prefix < < field . _name < < " is not an array field, can't use T[] to access it " , false ) ;
return true ;
}
# endif
template < class T , class > Containers : : StridedArrayView1D < const T > SceneData : : field ( const UnsignedInt id ) const {
Containers : : StridedArrayView2D < const char > data = field ( id ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ id ] , " Trade::SceneData::field(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 1 , const T > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView2D < const typename std : : remove_extent < T > : : type > SceneData : : field ( const UnsignedInt id ) const {
Containers : : StridedArrayView2D < const char > data = field ( id ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ id ] , " Trade::SceneData::field(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 2 , const typename std : : remove_extent < T > : : type > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView1D < T > SceneData : : mutableField ( const UnsignedInt id ) {
Containers : : StridedArrayView2D < char > data = mutableField ( id ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ id ] , " Trade::SceneData::mutableField(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 1 , T > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView2D < typename std : : remove_extent < T > : : type > SceneData : : mutableField ( const UnsignedInt id ) {
Containers : : StridedArrayView2D < char > data = mutableField ( id ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ id ] , " Trade::SceneData::mutableField(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 2 , typename std : : remove_extent < T > : : type > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView1D < const T > SceneData : : field ( const SceneField name ) const {
Containers : : StridedArrayView2D < const char > data = field ( name ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ findFieldIdInternal ( name ) ] , " Trade::SceneData::field(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 1 , const T > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView2D < const typename std : : remove_extent < T > : : type > SceneData : : field ( const SceneField name ) const {
Containers : : StridedArrayView2D < const char > data = field ( name ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ findFieldIdInternal ( name ) ] , " Trade::SceneData::field(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 2 , const typename std : : remove_extent < T > : : type > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView1D < T > SceneData : : mutableField ( const SceneField name ) {
Containers : : StridedArrayView2D < char > data = mutableField ( name ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ findFieldIdInternal ( name ) ] , " Trade::SceneData::mutableField(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 1 , T > ( data ) ;
}
template < class T , class > Containers : : StridedArrayView2D < typename std : : remove_extent < T > : : type > SceneData : : mutableField ( const SceneField name ) {
Containers : : StridedArrayView2D < char > data = mutableField ( name ) ;
# ifdef CORRADE_GRACEFUL_ASSERT /* Sigh. Brittle. Better idea? */
if ( ! data . stride ( ) [ 1 ] ) return { } ;
# endif
# ifndef CORRADE_NO_ASSERT
if ( ! checkFieldTypeCompatibility < T > ( _fields [ findFieldIdInternal ( name ) ] , " Trade::SceneData::mutableField(): " ) ) return { } ;
# endif
return Containers : : arrayCast < 2 , typename std : : remove_extent < T > : : type > ( data ) ;
}
} }
# endif