mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Change material sharing for CMeshSceneNode
This commit is contained in:
parent
e51221d247
commit
5a8720a484
4 changed files with 35 additions and 34 deletions
|
@ -34,16 +34,16 @@ public:
|
||||||
/** \return Pointer to mesh which is displayed by this node. */
|
/** \return Pointer to mesh which is displayed by this node. */
|
||||||
virtual IMesh *getMesh(void) = 0;
|
virtual IMesh *getMesh(void) = 0;
|
||||||
|
|
||||||
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
//! Sets if the scene node should not copy the materials of the mesh but use them directly.
|
||||||
/** In this way it is possible to change the materials of a mesh
|
/** In this way it is possible to change the materials of a mesh
|
||||||
causing all mesh scene nodes referencing this mesh to change, too.
|
causing all mesh scene nodes referencing this mesh to change, too.
|
||||||
\param readonly Flag if the materials shall be read-only. */
|
\param shared Flag if the materials shall be shared. */
|
||||||
virtual void setReadOnlyMaterials(bool readonly) = 0;
|
virtual void setSharedMaterials(bool shared) = 0;
|
||||||
|
|
||||||
//! Check if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Check if the scene node does not copy the materials of the mesh but uses them directly.
|
||||||
/** This flag can be set by setReadOnlyMaterials().
|
/** This flag can be set by setSharedMaterials().
|
||||||
\return Whether the materials are read-only. */
|
\return Whether the materials are shared. */
|
||||||
virtual bool isReadOnlyMaterials() const = 0;
|
virtual bool isSharedMaterials() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -21,7 +21,7 @@ CMeshSceneNode::CMeshSceneNode(IMesh *mesh, ISceneNode *parent, ISceneManager *m
|
||||||
const core::vector3df &scale) :
|
const core::vector3df &scale) :
|
||||||
IMeshSceneNode(parent, mgr, id, position, rotation, scale),
|
IMeshSceneNode(parent, mgr, id, position, rotation, scale),
|
||||||
Mesh(0),
|
Mesh(0),
|
||||||
PassCount(0), ReadOnlyMaterials(false)
|
PassCount(0), SharedMaterials(false)
|
||||||
{
|
{
|
||||||
setMesh(mesh);
|
setMesh(mesh);
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ void CMeshSceneNode::OnRegisterSceneNode()
|
||||||
int solidCount = 0;
|
int solidCount = 0;
|
||||||
|
|
||||||
// count transparent and solid materials in this scene node
|
// count transparent and solid materials in this scene node
|
||||||
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
const u32 numMaterials = SharedMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
||||||
for (u32 i = 0; i < numMaterials; ++i) {
|
for (u32 i = 0; i < numMaterials; ++i) {
|
||||||
const video::SMaterial &material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
const auto &material = SharedMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
||||||
|
|
||||||
if (driver->needsTransparentRenderPass(material))
|
if (driver->needsTransparentRenderPass(material))
|
||||||
++transparentCount;
|
++transparentCount;
|
||||||
|
@ -93,7 +93,7 @@ void CMeshSceneNode::render()
|
||||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
||||||
scene::IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
scene::IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
||||||
if (mb) {
|
if (mb) {
|
||||||
const video::SMaterial &material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
const auto &material = SharedMaterials ? mb->getMaterial() : Materials[i];
|
||||||
|
|
||||||
const bool transparent = driver->needsTransparentRenderPass(material);
|
const bool transparent = driver->needsTransparentRenderPass(material);
|
||||||
|
|
||||||
|
@ -164,14 +164,10 @@ const core::aabbox3d<f32> &CMeshSceneNode::getBoundingBox() const
|
||||||
|
|
||||||
//! returns the material based on the zero based index i. To get the amount
|
//! returns the material based on the zero based index i. To get the amount
|
||||||
//! of materials used by this scene node, use getMaterialCount().
|
//! of materials used by this scene node, use getMaterialCount().
|
||||||
//! This function is needed for inserting the node into the scene hierarchy on a
|
|
||||||
//! optimal position for minimizing renderstate changes, but can also be used
|
|
||||||
//! to directly modify the material of a scene node.
|
|
||||||
video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
||||||
{
|
{
|
||||||
if (Mesh && ReadOnlyMaterials && i < Mesh->getMeshBufferCount()) {
|
if (Mesh && SharedMaterials && i < Mesh->getMeshBufferCount()) {
|
||||||
ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial();
|
return Mesh->getMeshBuffer(i)->getMaterial();
|
||||||
return ReadOnlyMaterial;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= Materials.size())
|
if (i >= Materials.size())
|
||||||
|
@ -183,7 +179,7 @@ video::SMaterial &CMeshSceneNode::getMaterial(u32 i)
|
||||||
//! returns amount of materials used by this scene node.
|
//! returns amount of materials used by this scene node.
|
||||||
u32 CMeshSceneNode::getMaterialCount() const
|
u32 CMeshSceneNode::getMaterialCount() const
|
||||||
{
|
{
|
||||||
if (Mesh && ReadOnlyMaterials)
|
if (Mesh && SharedMaterials)
|
||||||
return Mesh->getMeshBufferCount();
|
return Mesh->getMeshBufferCount();
|
||||||
|
|
||||||
return Materials.size();
|
return Materials.size();
|
||||||
|
@ -206,9 +202,10 @@ void CMeshSceneNode::copyMaterials()
|
||||||
{
|
{
|
||||||
Materials.clear();
|
Materials.clear();
|
||||||
|
|
||||||
if (Mesh) {
|
if (Mesh && !SharedMaterials) {
|
||||||
video::SMaterial mat;
|
video::SMaterial mat;
|
||||||
|
|
||||||
|
Materials.reserve(Mesh->getMeshBufferCount());
|
||||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) {
|
||||||
IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
IMeshBuffer *mb = Mesh->getMeshBuffer(i);
|
||||||
if (mb)
|
if (mb)
|
||||||
|
@ -222,15 +219,18 @@ void CMeshSceneNode::copyMaterials()
|
||||||
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
||||||
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
||||||
referencing this mesh to change too. */
|
referencing this mesh to change too. */
|
||||||
void CMeshSceneNode::setReadOnlyMaterials(bool readonly)
|
void CMeshSceneNode::setSharedMaterials(bool shared)
|
||||||
{
|
{
|
||||||
ReadOnlyMaterials = readonly;
|
if (SharedMaterials != shared) {
|
||||||
|
SharedMaterials = shared;
|
||||||
|
copyMaterials();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
||||||
bool CMeshSceneNode::isReadOnlyMaterials() const
|
bool CMeshSceneNode::isSharedMaterials() const
|
||||||
{
|
{
|
||||||
return ReadOnlyMaterials;
|
return SharedMaterials;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Creates a clone of this scene node and its children.
|
//! Creates a clone of this scene node and its children.
|
||||||
|
@ -245,7 +245,7 @@ ISceneNode *CMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *newManag
|
||||||
newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale);
|
newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale);
|
||||||
|
|
||||||
nb->cloneMembers(this, newManager);
|
nb->cloneMembers(this, newManager);
|
||||||
nb->ReadOnlyMaterials = ReadOnlyMaterials;
|
nb->SharedMaterials = SharedMaterials;
|
||||||
nb->Materials = Materials;
|
nb->Materials = Materials;
|
||||||
|
|
||||||
if (newParent)
|
if (newParent)
|
||||||
|
|
|
@ -52,13 +52,16 @@ public:
|
||||||
//! Returns the current mesh
|
//! Returns the current mesh
|
||||||
IMesh *getMesh(void) override { return Mesh; }
|
IMesh *getMesh(void) override { return Mesh; }
|
||||||
|
|
||||||
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
|
//! Sets if the scene node should not copy the materials of the mesh but use them directly.
|
||||||
/* In this way it is possible to change the materials a mesh causing all mesh scene nodes
|
/** In this way it is possible to change the materials of a mesh
|
||||||
referencing this mesh to change too. */
|
causing all mesh scene nodes referencing this mesh to change, too.
|
||||||
void setReadOnlyMaterials(bool readonly) override;
|
\param shared Flag if the materials shall be shared. */
|
||||||
|
void setSharedMaterials(bool shared) override;
|
||||||
|
|
||||||
//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style
|
//! Check if the scene node does not copy the materials of the mesh but uses them directly.
|
||||||
bool isReadOnlyMaterials() const override;
|
/** This flag can be set by setSharedMaterials().
|
||||||
|
\return Whether the materials are shared. */
|
||||||
|
bool isSharedMaterials() const override;
|
||||||
|
|
||||||
//! Creates a clone of this scene node and its children.
|
//! Creates a clone of this scene node and its children.
|
||||||
ISceneNode *clone(ISceneNode *newParent = 0, ISceneManager *newManager = 0) override;
|
ISceneNode *clone(ISceneNode *newParent = 0, ISceneManager *newManager = 0) override;
|
||||||
|
@ -71,14 +74,13 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void copyMaterials();
|
void copyMaterials();
|
||||||
|
|
||||||
core::array<video::SMaterial> Materials;
|
std::vector<video::SMaterial> Materials;
|
||||||
core::aabbox3d<f32> Box{{0, 0, 0}};
|
core::aabbox3d<f32> Box{{0, 0, 0}};
|
||||||
video::SMaterial ReadOnlyMaterial;
|
|
||||||
|
|
||||||
IMesh *Mesh;
|
IMesh *Mesh;
|
||||||
|
|
||||||
s32 PassCount;
|
s32 PassCount;
|
||||||
bool ReadOnlyMaterials;
|
bool SharedMaterials;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -204,7 +204,6 @@ WieldMeshSceneNode::WieldMeshSceneNode(scene::ISceneManager *mgr, s32 id):
|
||||||
// Create the child scene node
|
// Create the child scene node
|
||||||
scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube();
|
scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube();
|
||||||
m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1);
|
m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1);
|
||||||
m_meshnode->setReadOnlyMaterials(false);
|
|
||||||
m_meshnode->setVisible(false);
|
m_meshnode->setVisible(false);
|
||||||
dummymesh->drop(); // m_meshnode grabbed it
|
dummymesh->drop(); // m_meshnode grabbed it
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue