Ensure that absent bone names work (#284)

This commit is contained in:
Lars Müller 2024-02-06 20:22:44 +01:00 committed by GitHub
parent 8482cc3db8
commit f1504093d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 73 additions and 95 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.12)
set(IRRLICHTMT_REVISION 14) set(IRRLICHTMT_REVISION 15)
project(Irrlicht project(Irrlicht
VERSION 1.9.0.${IRRLICHTMT_REVISION} VERSION 1.9.0.${IRRLICHTMT_REVISION}

View File

@ -14,6 +14,7 @@
#include "aabbox3d.h" #include "aabbox3d.h"
#include "matrix4.h" #include "matrix4.h"
#include "IAttributes.h" #include "IAttributes.h"
#include <list> #include <list>
#include <optional> #include <optional>
@ -117,23 +118,14 @@ namespace scene
//! Returns the name of the node. //! Returns the name of the node.
/** \return Name as character string. */ /** \return Name as character string. */
virtual const c8* getName() const virtual const std::optional<std::string> &getName() const
{ {
return Name.c_str(); return Name;
} }
//! Sets the name of the node. //! Sets the name of the node.
/** \param name New name of the scene node. */ /** \param name New name of the scene node. */
virtual void setName(const c8* name) virtual void setName(const std::optional<std::string> &name)
{
Name = name;
}
//! Sets the name of the node.
/** \param name New name of the scene node. */
virtual void setName(const core::stringc& name)
{ {
Name = name; Name = name;
} }
@ -601,7 +593,7 @@ namespace scene
} }
//! Name of the scene node. //! Name of the scene node.
core::stringc Name; std::optional<std::string> Name;
//! Absolute transformation of the node. //! Absolute transformation of the node.
core::matrix4 AbsoluteTransformation; core::matrix4 AbsoluteTransformation;

View File

@ -10,6 +10,8 @@
#include "IAnimatedMesh.h" #include "IAnimatedMesh.h"
#include "SSkinMeshBuffer.h" #include "SSkinMeshBuffer.h"
#include <optional>
namespace irr namespace irr
{ {
namespace scene namespace scene
@ -41,12 +43,12 @@ namespace scene
/** \param number: Zero based index of joint. The last joint /** \param number: Zero based index of joint. The last joint
has the number getJointCount()-1; has the number getJointCount()-1;
\return Name of joint and null if an error happened. */ \return Name of joint and null if an error happened. */
virtual const c8* getJointName(u32 number) const = 0; virtual const std::optional<std::string> &getJointName(u32 number) const = 0;
//! Gets a joint number from its name //! Gets a joint number from its name
/** \param name: Name of the joint. /** \param name: Name of the joint.
\return Number of the joint or -1 if not found. */ \return Number of the joint or std::nullopt if not found. */
virtual s32 getJointNumber(const c8* name) const = 0; virtual std::optional<u32> getJointNumber(const std::string &name) const = 0;
//! Use animation from another mesh //! Use animation from another mesh
/** The animation is linked (not copied) based on joint names /** The animation is linked (not copied) based on joint names
@ -136,7 +138,7 @@ namespace scene
} }
//! The name of this joint //! The name of this joint
core::stringc Name; std::optional<std::string> Name;
//! Local matrix of this joint //! Local matrix of this joint
core::matrix4 LocalMatrix; core::matrix4 LocalMatrix;

View File

@ -5,8 +5,8 @@
#pragma once #pragma once
//! Identifies the IrrlichtMt fork customized for the Minetest engine //! Identifies the IrrlichtMt fork customized for the Minetest engine
#define IRRLICHT_VERSION_MT_REVISION 14 #define IRRLICHT_VERSION_MT_REVISION 15
#define IRRLICHT_VERSION_MT "mt14" #define IRRLICHT_VERSION_MT "mt15"
//! Irrlicht SDK Version //! Irrlicht SDK Version
#define IRRLICHT_VERSION_MAJOR 1 #define IRRLICHT_VERSION_MAJOR 1

View File

@ -471,21 +471,21 @@ IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName)
ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh;
const s32 number = skinnedMesh->getJointNumber(jointName); const std::optional<u32> number = skinnedMesh->getJointNumber(jointName);
if (number == -1) if (!number.has_value())
{ {
os::Printer::log("Joint with specified name not found in skinned mesh", jointName, ELL_DEBUG); os::Printer::log("Joint with specified name not found in skinned mesh", jointName, ELL_DEBUG);
return 0; return 0;
} }
if ((s32)JointChildSceneNodes.size() <= number) if (JointChildSceneNodes.size() <= *number)
{ {
os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING); os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING);
return 0; return 0;
} }
return JointChildSceneNodes[number]; return JointChildSceneNodes[*number];
} }

View File

@ -12,6 +12,8 @@
#include "IFileSystem.h" #include "IFileSystem.h"
#include "os.h" #include "os.h"
#include <algorithm>
#ifdef _DEBUG #ifdef _DEBUG
#define _B3D_READER_DEBUG #define _B3D_READER_DEBUG
#endif #endif
@ -149,7 +151,7 @@ bool CB3DMeshFileLoader::load()
bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint)
{ {
CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint);
readString(joint->Name); joint->Name = readString();
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
core::stringc logStr; core::stringc logStr;
@ -818,8 +820,8 @@ bool CB3DMeshFileLoader::readChunkTEXS()
Textures.push_back(SB3dTexture()); Textures.push_back(SB3dTexture());
SB3dTexture& B3dTexture = Textures.getLast(); SB3dTexture& B3dTexture = Textures.getLast();
readString(B3dTexture.TextureName); B3dTexture.TextureName = readString();
B3dTexture.TextureName.replace('\\','/'); std::replace(B3dTexture.TextureName.begin(), B3dTexture.TextureName.end(), '\\', '/');
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
os::Printer::log("read Texture", B3dTexture.TextureName.c_str(), ELL_DEBUG); os::Printer::log("read Texture", B3dTexture.TextureName.c_str(), ELL_DEBUG);
#endif #endif
@ -872,10 +874,9 @@ bool CB3DMeshFileLoader::readChunkBRUS()
{ {
// This is what blitz basic calls a brush, like a Irrlicht Material // This is what blitz basic calls a brush, like a Irrlicht Material
core::stringc name; auto name = readString();
readString(name);
#ifdef _B3D_READER_DEBUG #ifdef _B3D_READER_DEBUG
os::Printer::log("read Material", name, ELL_DEBUG); os::Printer::log("read Material", name.c_str(), ELL_DEBUG);
#endif #endif
Materials.push_back(SB3dMaterial()); Materials.push_back(SB3dMaterial());
SB3dMaterial& B3dMaterial=Materials.getLast(); SB3dMaterial& B3dMaterial=Materials.getLast();
@ -1031,18 +1032,19 @@ bool CB3DMeshFileLoader::readChunkBRUS()
} }
void CB3DMeshFileLoader::readString(core::stringc& newstring) std::string CB3DMeshFileLoader::readString()
{ {
newstring=""; std::string newstring = "";
while (true) while (true)
{ {
c8 character; c8 character;
if (B3DFile->read(&character, sizeof(character)) == 0) if (B3DFile->read(&character, sizeof(character)) == 0)
return; // eof break; // eof
if (character==0) if (character==0)
return; break;
newstring.append(character); newstring.push_back(character);
} }
return newstring;
} }

View File

@ -52,7 +52,7 @@ private:
bool readChunkTEXS(); bool readChunkTEXS();
bool readChunkBRUS(); bool readChunkBRUS();
void readString(core::stringc& newstring); std::string readString();
void readFloats(f32* vec, u32 count); void readFloats(f32* vec, u32 count);
core::array<SB3dChunk> B3dStack; core::array<SB3dChunk> B3dStack;

View File

@ -4,6 +4,8 @@
#include "CBoneSceneNode.h" #include "CBoneSceneNode.h"
#include <optional>
namespace irr namespace irr
{ {
namespace scene namespace scene
@ -11,7 +13,7 @@ namespace scene
//! constructor //! constructor
CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
u32 boneIndex, const c8* boneName) u32 boneIndex, const std::optional<std::string> &boneName)
: IBoneSceneNode(parent, mgr, id), BoneIndex(boneIndex), : IBoneSceneNode(parent, mgr, id), BoneIndex(boneIndex),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL) AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{ {

View File

@ -8,6 +8,8 @@
#include "IBoneSceneNode.h" #include "IBoneSceneNode.h"
#include <optional>
namespace irr namespace irr
{ {
namespace scene namespace scene
@ -19,7 +21,8 @@ namespace scene
//! constructor //! constructor
CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr,
s32 id=-1, u32 boneIndex=0, const c8* boneName=0); s32 id=-1, u32 boneIndex=0,
const std::optional<std::string> &boneName = std::nullopt);
//! Returns the index of the bone //! Returns the index of the bone
u32 getBoneIndex() const override; u32 getBoneIndex() const override;

View File

@ -697,7 +697,8 @@ ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* st
if (start == 0) if (start == 0)
start = getRootSceneNode(); start = getRootSceneNode();
if (!strcmp(start->getName(),name)) auto startName = start->getName();
if (startName.has_value() && startName == name)
return start; return start;
ISceneNode* node = 0; ISceneNode* node = 0;

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CSkinnedMesh.h" #include "CSkinnedMesh.h"
#include <optional>
#include "CBoneSceneNode.h" #include "CBoneSceneNode.h"
#include "IAnimatedMeshSceneNode.h" #include "IAnimatedMeshSceneNode.h"
#include "os.h" #include "os.h"
@ -624,18 +625,18 @@ u32 CSkinnedMesh::getJointCount() const
return AllJoints.size(); return AllJoints.size();
} }
//! Gets the name of a joint. //! Gets the name of a joint.
const c8* CSkinnedMesh::getJointName(u32 number) const const std::optional<std::string> &CSkinnedMesh::getJointName(u32 number) const {
{ if (number >= getJointCount()) {
if (number >= AllJoints.size()) static const std::optional<std::string> nullopt;
return 0; return nullopt;
return AllJoints[number]->Name.c_str(); }
return AllJoints[number]->Name;
} }
//! Gets a joint number from its name //! Gets a joint number from its name
s32 CSkinnedMesh::getJointNumber(const c8* name) const std::optional<u32> CSkinnedMesh::getJointNumber(const std::string &name) const
{ {
for (u32 i=0; i<AllJoints.size(); ++i) for (u32 i=0; i<AllJoints.size(); ++i)
{ {
@ -643,7 +644,7 @@ s32 CSkinnedMesh::getJointNumber(const c8* name) const
return i; return i;
} }
return -1; return std::nullopt;
} }
@ -1396,7 +1397,7 @@ void CSkinnedMesh::addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
//Create new joints //Create new joints
for (u32 i=0; i<AllJoints.size(); ++i) for (u32 i=0; i<AllJoints.size(); ++i)
{ {
jointChildSceneNodes.push_back(new CBoneSceneNode(0, smgr, 0, i, AllJoints[i]->Name.c_str())); jointChildSceneNodes.push_back(new CBoneSceneNode(0, smgr, 0, i, AllJoints[i]->Name));
} }
//Match up parents //Match up parents

View File

@ -8,9 +8,6 @@
#include "ISkinnedMesh.h" #include "ISkinnedMesh.h"
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
#include "S3DVertex.h"
#include "irrString.h"
#include "matrix4.h"
#include "quaternion.h" #include "quaternion.h"
namespace irr namespace irr
@ -84,10 +81,10 @@ namespace scene
u32 getJointCount() const override; u32 getJointCount() const override;
//! Gets the name of a joint. //! Gets the name of a joint.
const c8* getJointName(u32 number) const override; const std::optional<std::string> &getJointName(u32 number) const override;
//! Gets a joint number from its name //! Gets a joint number from its name
s32 getJointNumber(const c8* name) const override; std::optional<u32> getJointNumber(const std::string &name) const override;
//! uses animation from another mesh //! uses animation from another mesh
bool useAnimationFrom(const ISkinnedMesh *mesh) override; bool useAnimationFrom(const ISkinnedMesh *mesh) override;

View File

@ -594,16 +594,11 @@ bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent)
CSkinnedMesh::SJoint *joint=0; CSkinnedMesh::SJoint *joint=0;
if (name.size()) if (name.size()) {
{ auto n = AnimatedMesh->getJointNumber(name.c_str());
for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n) if (n.has_value()) {
{ JointID = *n;
if (AnimatedMesh->getAllJoints()[n]->Name==name) joint = AnimatedMesh->getAllJoints()[JointID];
{
joint=AnimatedMesh->getAllJoints()[n];
JointID=n;
break;
}
} }
} }
@ -613,7 +608,7 @@ bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent)
os::Printer::log("creating joint ", name.c_str(), ELL_DEBUG); os::Printer::log("creating joint ", name.c_str(), ELL_DEBUG);
#endif #endif
joint=AnimatedMesh->addJoint(Parent); joint=AnimatedMesh->addJoint(Parent);
joint->Name=name; joint->Name=name.c_str();
JointID=AnimatedMesh->getAllJoints().size()-1; JointID=AnimatedMesh->getAllJoints().size()-1;
} }
else else
@ -1121,17 +1116,8 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
mesh.HasSkinning=true; mesh.HasSkinning=true;
CSkinnedMesh::SJoint *joint=0; auto n = AnimatedMesh->getJointNumber(TransformNodeName.c_str());
CSkinnedMesh::SJoint *joint = n.has_value() ? AnimatedMesh->getAllJoints()[*n] : nullptr;
u32 n;
for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n)
{
if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName)
{
joint=AnimatedMesh->getAllJoints()[n];
break;
}
}
if (!joint) if (!joint)
{ {
@ -1140,7 +1126,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
#endif #endif
n = AnimatedMesh->getAllJoints().size(); n = AnimatedMesh->getAllJoints().size();
joint=AnimatedMesh->addJoint(0); joint=AnimatedMesh->addJoint(0);
joint->Name=TransformNodeName; joint->Name=TransformNodeName.c_str();
} }
// read vertex weights // read vertex weights
@ -1157,7 +1143,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh)
for (i=0; i<nWeights; ++i) for (i=0; i<nWeights; ++i)
{ {
mesh.WeightJoint.push_back(n); mesh.WeightJoint.push_back(*n);
mesh.WeightNum.push_back(joint->Weights.size()); mesh.WeightNum.push_back(joint->Weights.size());
CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(joint); CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(joint);
@ -1668,41 +1654,33 @@ bool CXMeshFileLoader::parseDataObjectAnimation()
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
os::Printer::log("frame name", FrameName.c_str(), ELL_DEBUG); os::Printer::log("frame name", FrameName.c_str(), ELL_DEBUG);
#endif #endif
CSkinnedMesh::SJoint *joint=0; auto n = AnimatedMesh->getJointNumber(FrameName.c_str());
u32 n; CSkinnedMesh::SJoint *joint;
for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n) if (n.has_value()) {
{ joint = AnimatedMesh->getAllJoints()[*n];
if (AnimatedMesh->getAllJoints()[n]->Name==FrameName) } else {
{
joint=AnimatedMesh->getAllJoints()[n];
break;
}
}
if (!joint)
{
#ifdef _XREADER_DEBUG #ifdef _XREADER_DEBUG
os::Printer::log("creating joint for animation ", FrameName.c_str(), ELL_DEBUG); os::Printer::log("creating joint for animation ", FrameName.c_str(), ELL_DEBUG);
#endif #endif
joint=AnimatedMesh->addJoint(0); joint=AnimatedMesh->addJoint(0);
joint->Name=FrameName; joint->Name=FrameName.c_str();
} }
joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size()); joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size());
for (n=0; n<animationDump.PositionKeys.size(); ++n) for (u32 n=0; n<animationDump.PositionKeys.size(); ++n)
{ {
joint->PositionKeys.push_back(animationDump.PositionKeys[n]); joint->PositionKeys.push_back(animationDump.PositionKeys[n]);
} }
joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size()); joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size());
for (n=0; n<animationDump.ScaleKeys.size(); ++n) for (u32 n=0; n<animationDump.ScaleKeys.size(); ++n)
{ {
joint->ScaleKeys.push_back(animationDump.ScaleKeys[n]); joint->ScaleKeys.push_back(animationDump.ScaleKeys[n]);
} }
joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size()); joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size());
for (n=0; n<animationDump.RotationKeys.size(); ++n) for (u32 n=0; n<animationDump.RotationKeys.size(); ++n)
{ {
joint->RotationKeys.push_back(animationDump.RotationKeys[n]); joint->RotationKeys.push_back(animationDump.RotationKeys[n]);
} }

View File

@ -39,7 +39,7 @@ struct SB3dChunk
struct SB3dTexture struct SB3dTexture
{ {
core::stringc TextureName; std::string TextureName;
s32 Flags; s32 Flags;
s32 Blend; s32 Blend;
f32 Xpos; f32 Xpos;