mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Restore / fix bone overrides
This commit is contained in:
parent
a687a7a6e7
commit
d10abba38c
5 changed files with 32 additions and 77 deletions
|
@ -14,21 +14,6 @@ namespace scene
|
||||||
{
|
{
|
||||||
class IAnimatedMeshSceneNode;
|
class IAnimatedMeshSceneNode;
|
||||||
|
|
||||||
//! Callback interface for catching events of ended animations.
|
|
||||||
/** Implement this interface and use
|
|
||||||
IAnimatedMeshSceneNode::setAnimationEndCallback to be able to
|
|
||||||
be notified if an animation playback has ended.
|
|
||||||
**/
|
|
||||||
class IAnimationEndCallBack : public virtual IReferenceCounted
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! Will be called when the animation playback has ended.
|
|
||||||
/** See IAnimatedMeshSceneNode::setAnimationEndCallback for
|
|
||||||
more information.
|
|
||||||
\param node: Node of which the animation has ended. */
|
|
||||||
virtual void OnAnimationEnd(IAnimatedMeshSceneNode *node) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Scene node capable of displaying an animated mesh.
|
//! Scene node capable of displaying an animated mesh.
|
||||||
class IAnimatedMeshSceneNode : public ISceneNode
|
class IAnimatedMeshSceneNode : public ISceneNode
|
||||||
{
|
{
|
||||||
|
@ -108,11 +93,10 @@ public:
|
||||||
/** When true the animations are played looped */
|
/** When true the animations are played looped */
|
||||||
virtual bool getLoopMode() const = 0;
|
virtual bool getLoopMode() const = 0;
|
||||||
|
|
||||||
//! Sets a callback interface which will be called if an animation playback has ended.
|
//! Will be called right after the joints have been animated,
|
||||||
/** Set this to 0 to disable the callback again.
|
//! but before the transforms have been propagated recursively to children.
|
||||||
Please note that this will only be called when in non looped
|
virtual void setOnAnimateCallback(
|
||||||
mode, see IAnimatedMeshSceneNode::setLoopMode(). */
|
const std::function<void(f32 dtime)> &cb) = 0;
|
||||||
virtual void setAnimationEndCallback(IAnimationEndCallBack *callback = 0) = 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 in a read only style.
|
||||||
/** In this way it is possible to change the materials a mesh
|
/** In this way it is possible to change the materials a mesh
|
||||||
|
|
|
@ -36,7 +36,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh *mesh,
|
||||||
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
|
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
|
||||||
JointsUsed(false),
|
JointsUsed(false),
|
||||||
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
|
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
|
||||||
LoopCallBack(0), PassCount(0)
|
PassCount(0)
|
||||||
{
|
{
|
||||||
setMesh(mesh);
|
setMesh(mesh);
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh *mesh,
|
||||||
//! destructor
|
//! destructor
|
||||||
CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
|
CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode()
|
||||||
{
|
{
|
||||||
if (LoopCallBack)
|
|
||||||
LoopCallBack->drop();
|
|
||||||
if (Mesh)
|
if (Mesh)
|
||||||
Mesh->drop();
|
Mesh->drop();
|
||||||
}
|
}
|
||||||
|
@ -87,8 +85,7 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
|
||||||
if (FramesPerSecond > 0.f) { // forwards...
|
if (FramesPerSecond > 0.f) { // forwards...
|
||||||
if (CurrentFrameNr > EndFrame)
|
if (CurrentFrameNr > EndFrame)
|
||||||
CurrentFrameNr = StartFrame + fmodf(CurrentFrameNr - StartFrame, EndFrame - StartFrame);
|
CurrentFrameNr = StartFrame + fmodf(CurrentFrameNr - StartFrame, EndFrame - StartFrame);
|
||||||
} else // backwards...
|
} else { // backwards...
|
||||||
{
|
|
||||||
if (CurrentFrameNr < StartFrame)
|
if (CurrentFrameNr < StartFrame)
|
||||||
CurrentFrameNr = EndFrame - fmodf(EndFrame - CurrentFrameNr, EndFrame - StartFrame);
|
CurrentFrameNr = EndFrame - fmodf(EndFrame - CurrentFrameNr, EndFrame - StartFrame);
|
||||||
}
|
}
|
||||||
|
@ -97,18 +94,9 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
|
||||||
|
|
||||||
CurrentFrameNr += timeMs * FramesPerSecond;
|
CurrentFrameNr += timeMs * FramesPerSecond;
|
||||||
if (FramesPerSecond > 0.f) { // forwards...
|
if (FramesPerSecond > 0.f) { // forwards...
|
||||||
if (CurrentFrameNr > EndFrame) {
|
CurrentFrameNr = std::min(CurrentFrameNr, EndFrame);
|
||||||
CurrentFrameNr = EndFrame;
|
} else { // backwards...
|
||||||
if (LoopCallBack)
|
CurrentFrameNr = std::max(CurrentFrameNr, StartFrame);
|
||||||
LoopCallBack->OnAnimationEnd(this);
|
|
||||||
}
|
|
||||||
} else // backwards...
|
|
||||||
{
|
|
||||||
if (CurrentFrameNr < StartFrame) {
|
|
||||||
CurrentFrameNr = StartFrame;
|
|
||||||
if (LoopCallBack)
|
|
||||||
LoopCallBack->OnAnimationEnd(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,6 +179,8 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
|
||||||
// anything is rendered so that the transformations of children are up to date
|
// anything is rendered so that the transformations of children are up to date
|
||||||
animateJoints();
|
animateJoints();
|
||||||
|
|
||||||
|
OnAnimateCallback(timeMs / 1000.0f);
|
||||||
|
|
||||||
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,22 +451,6 @@ bool CAnimatedMeshSceneNode::getLoopMode() const
|
||||||
return Looping;
|
return Looping;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Sets a callback interface which will be called if an animation
|
|
||||||
//! playback has ended. Set this to 0 to disable the callback again.
|
|
||||||
void CAnimatedMeshSceneNode::setAnimationEndCallback(IAnimationEndCallBack *callback)
|
|
||||||
{
|
|
||||||
if (callback == LoopCallBack)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (LoopCallBack)
|
|
||||||
LoopCallBack->drop();
|
|
||||||
|
|
||||||
LoopCallBack = callback;
|
|
||||||
|
|
||||||
if (LoopCallBack)
|
|
||||||
LoopCallBack->grab();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! 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.
|
||||||
void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly)
|
void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly)
|
||||||
{
|
{
|
||||||
|
@ -681,9 +655,6 @@ ISceneNode *CAnimatedMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *
|
||||||
newNode->TransitingBlend = TransitingBlend;
|
newNode->TransitingBlend = TransitingBlend;
|
||||||
newNode->Looping = Looping;
|
newNode->Looping = Looping;
|
||||||
newNode->ReadOnlyMaterials = ReadOnlyMaterials;
|
newNode->ReadOnlyMaterials = ReadOnlyMaterials;
|
||||||
newNode->LoopCallBack = LoopCallBack;
|
|
||||||
if (newNode->LoopCallBack)
|
|
||||||
newNode->LoopCallBack->grab();
|
|
||||||
newNode->PassCount = PassCount;
|
newNode->PassCount = PassCount;
|
||||||
newNode->JointChildSceneNodes = JointChildSceneNodes;
|
newNode->JointChildSceneNodes = JointChildSceneNodes;
|
||||||
newNode->PretransitingSave = PretransitingSave;
|
newNode->PretransitingSave = PretransitingSave;
|
||||||
|
|
|
@ -54,9 +54,11 @@ public:
|
||||||
//! returns the current loop mode
|
//! returns the current loop mode
|
||||||
bool getLoopMode() const override;
|
bool getLoopMode() const override;
|
||||||
|
|
||||||
//! Sets a callback interface which will be called if an animation
|
void setOnAnimateCallback(
|
||||||
//! playback has ended. Set this to 0 to disable the callback again.
|
const std::function<void(f32 dtime)> &cb) override
|
||||||
void setAnimationEndCallback(IAnimationEndCallBack *callback = 0) override;
|
{
|
||||||
|
OnAnimateCallback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
//! sets the speed with which the animation is played
|
//! sets the speed with which the animation is played
|
||||||
//! NOTE: setMesh will also change this value and set it to the default speed of the mesh
|
//! NOTE: setMesh will also change this value and set it to the default speed of the mesh
|
||||||
|
@ -161,8 +163,8 @@ private:
|
||||||
bool ReadOnlyMaterials;
|
bool ReadOnlyMaterials;
|
||||||
bool RenderFromIdentity;
|
bool RenderFromIdentity;
|
||||||
|
|
||||||
IAnimationEndCallBack *LoopCallBack;
|
|
||||||
s32 PassCount;
|
s32 PassCount;
|
||||||
|
std::function<void(f32)> OnAnimateCallback;
|
||||||
|
|
||||||
std::vector<IBoneSceneNode *> JointChildSceneNodes;
|
std::vector<IBoneSceneNode *> JointChildSceneNodes;
|
||||||
core::array<core::matrix4> PretransitingSave;
|
core::array<core::matrix4> PretransitingSave;
|
||||||
|
|
|
@ -682,7 +682,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
|
m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
|
||||||
m_animated_meshnode->grab();
|
m_animated_meshnode->grab();
|
||||||
mesh->drop(); // The scene node took hold of it
|
mesh->drop(); // The scene node took hold of it
|
||||||
m_animated_meshnode->animateJoints(); // Needed for some animations
|
|
||||||
m_animated_meshnode->setScale(m_prop.visual_size);
|
m_animated_meshnode->setScale(m_prop.visual_size);
|
||||||
|
|
||||||
// set vertex colors to ensure alpha is set
|
// set vertex colors to ensure alpha is set
|
||||||
|
@ -693,6 +692,21 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
m_animated_meshnode->forEachMaterial([this] (auto &mat) {
|
m_animated_meshnode->forEachMaterial([this] (auto &mat) {
|
||||||
mat.BackfaceCulling = m_prop.backface_culling;
|
mat.BackfaceCulling = m_prop.backface_culling;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_animated_meshnode->setOnAnimateCallback([&](f32 dtime) {
|
||||||
|
for (auto &it : m_bone_override) {
|
||||||
|
auto* bone = m_animated_meshnode->getJointNode(it.first.c_str());
|
||||||
|
if (!bone)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BoneOverride &props = it.second;
|
||||||
|
props.dtime_passed += dtime;
|
||||||
|
|
||||||
|
bone->setPosition(props.getPosition(bone->getPosition()));
|
||||||
|
bone->setRotation(props.getRotationEulerDeg(bone->getRotation()));
|
||||||
|
bone->setScale(props.getScale(bone->getScale()));
|
||||||
|
}
|
||||||
|
});
|
||||||
} else
|
} else
|
||||||
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
||||||
break;
|
break;
|
||||||
|
@ -783,7 +797,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||||
updateMarker();
|
updateMarker();
|
||||||
updateNodePos();
|
updateNodePos();
|
||||||
updateAnimation();
|
updateAnimation();
|
||||||
updateBones(.0f);
|
|
||||||
updateAttachments();
|
updateAttachments();
|
||||||
setNodeLight(m_last_light);
|
setNodeLight(m_last_light);
|
||||||
updateMeshCulling();
|
updateMeshCulling();
|
||||||
|
@ -1174,18 +1187,6 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
||||||
rot_translator.val_current = m_rotation;
|
rot_translator.val_current = m_rotation;
|
||||||
updateNodePos();
|
updateNodePos();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_animated_meshnode) {
|
|
||||||
// Everything must be updated; the whole transform
|
|
||||||
// chain as well as the animated mesh node.
|
|
||||||
// Otherwise, bone attachments would be relative to
|
|
||||||
// a position that's one frame old.
|
|
||||||
if (m_matrixnode)
|
|
||||||
updatePositionRecursive(m_matrixnode);
|
|
||||||
m_animated_meshnode->updateAbsolutePosition();
|
|
||||||
m_animated_meshnode->animateJoints();
|
|
||||||
updateBones(dtime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count)
|
static void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count)
|
||||||
|
@ -1746,7 +1747,6 @@ void GenericCAO::processMessage(const std::string &data)
|
||||||
} else {
|
} else {
|
||||||
m_bone_override[bone] = props;
|
m_bone_override[bone] = props;
|
||||||
}
|
}
|
||||||
// updateBones(); now called every step
|
|
||||||
} else if (cmd == AO_CMD_ATTACH_TO) {
|
} else if (cmd == AO_CMD_ATTACH_TO) {
|
||||||
u16 parent_id = readS16(is);
|
u16 parent_id = readS16(is);
|
||||||
std::string bone = deSerializeString16(is);
|
std::string bone = deSerializeString16(is);
|
||||||
|
|
|
@ -286,8 +286,6 @@ public:
|
||||||
|
|
||||||
void updateAnimationSpeed();
|
void updateAnimationSpeed();
|
||||||
|
|
||||||
void updateBones(f32 dtime);
|
|
||||||
|
|
||||||
void processMessage(const std::string &data) override;
|
void processMessage(const std::string &data) override;
|
||||||
|
|
||||||
bool directReportPunch(v3f dir, const ItemStack *punchitem,
|
bool directReportPunch(v3f dir, const ItemStack *punchitem,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue