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

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

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

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

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

@ -471,21 +471,21 @@ IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName)
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);
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);
return 0;
}
return JointChildSceneNodes[number];
return JointChildSceneNodes[*number];
}

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

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

@ -4,6 +4,8 @@
#include "CBoneSceneNode.h"
#include <optional>
namespace irr
{
namespace scene
@ -11,7 +13,7 @@ namespace scene
//! constructor
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),
AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL)
{

@ -8,6 +8,8 @@
#include "IBoneSceneNode.h"
#include <optional>
namespace irr
{
namespace scene
@ -19,7 +21,8 @@ namespace scene
//! constructor
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
u32 getBoneIndex() const override;

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

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

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

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

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