mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-06 17:41:04 +00:00
Do bounding box & matrix calculation at proper point in time
This commit is contained in:
parent
07963f1af5
commit
455f7a4cae
2 changed files with 51 additions and 39 deletions
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "CAnimatedMeshSceneNode.h"
|
#include "CAnimatedMeshSceneNode.h"
|
||||||
#include "CBoneSceneNode.h"
|
#include "CBoneSceneNode.h"
|
||||||
|
#include "EDebugSceneTypes.h"
|
||||||
#include "IVideoDriver.h"
|
#include "IVideoDriver.h"
|
||||||
#include "ISceneManager.h"
|
#include "ISceneManager.h"
|
||||||
#include "S3DVertex.h"
|
#include "S3DVertex.h"
|
||||||
|
@ -159,17 +160,8 @@ IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame()
|
||||||
|
|
||||||
auto *skinnedMesh = static_cast<SkinnedMesh *>(Mesh);
|
auto *skinnedMesh = static_cast<SkinnedMesh *>(Mesh);
|
||||||
|
|
||||||
std::vector<core::matrix4> matrices;
|
// Matrices have already been calculated in OnAnimate
|
||||||
matrices.reserve(JointChildSceneNodes.size());
|
skinnedMesh->skinMesh(PerJoint.GlobalMatrices);
|
||||||
for (auto *node : JointChildSceneNodes)
|
|
||||||
matrices.push_back(node->getRelativeTransformation());
|
|
||||||
skinnedMesh->calculateGlobalMatrices(matrices);
|
|
||||||
|
|
||||||
skinnedMesh->skinMesh(matrices);
|
|
||||||
|
|
||||||
// TODO this should have happened *before* the skinning in OnAnimate;
|
|
||||||
// we should thus probably store the global matrices.
|
|
||||||
Box = skinnedMesh->calculateBoundingBox(matrices);
|
|
||||||
|
|
||||||
return skinnedMesh;
|
return skinnedMesh;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +184,13 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
|
||||||
OnAnimateCallback(timeMs / 1000.0f);
|
OnAnimateCallback(timeMs / 1000.0f);
|
||||||
|
|
||||||
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
||||||
|
|
||||||
|
if (auto *skinnedMesh = dynamic_cast<SkinnedMesh*>(Mesh)) {
|
||||||
|
for (u16 i = 0; i < PerJoint.SceneNodes.size(); ++i)
|
||||||
|
PerJoint.GlobalMatrices[i] = PerJoint.SceneNodes[i]->getRelativeTransformation();
|
||||||
|
skinnedMesh->calculateGlobalMatrices(PerJoint.GlobalMatrices);
|
||||||
|
Box = skinnedMesh->calculateBoundingBox(PerJoint.GlobalMatrices);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! renders the node.
|
//! renders the node.
|
||||||
|
@ -389,12 +388,12 @@ IBoneSceneNode *CAnimatedMeshSceneNode::getJointNode(const c8 *jointName)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JointChildSceneNodes.size() <= *number) {
|
if (PerJoint.SceneNodes.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 PerJoint.SceneNodes[*number];
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Returns a pointer to a child node, which has the same transformation as
|
//! Returns a pointer to a child node, which has the same transformation as
|
||||||
|
@ -408,12 +407,12 @@ IBoneSceneNode *CAnimatedMeshSceneNode::getJointNode(u32 jointID)
|
||||||
|
|
||||||
checkJoints();
|
checkJoints();
|
||||||
|
|
||||||
if (JointChildSceneNodes.size() <= jointID) {
|
if (PerJoint.SceneNodes.size() <= jointID) {
|
||||||
os::Printer::log("Joint not loaded into node", ELL_WARNING);
|
os::Printer::log("Joint not loaded into node", ELL_WARNING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return JointChildSceneNodes[jointID];
|
return PerJoint.SceneNodes[jointID];
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Gets joint count.
|
//! Gets joint count.
|
||||||
|
@ -434,9 +433,9 @@ bool CAnimatedMeshSceneNode::removeChild(ISceneNode *child)
|
||||||
{
|
{
|
||||||
if (ISceneNode::removeChild(child)) {
|
if (ISceneNode::removeChild(child)) {
|
||||||
if (JointsUsed) { // stop weird bugs caused while changing parents as the joints are being created
|
if (JointsUsed) { // stop weird bugs caused while changing parents as the joints are being created
|
||||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i) {
|
for (u32 i = 0; i < PerJoint.SceneNodes.size(); ++i) {
|
||||||
if (JointChildSceneNodes[i] == child) {
|
if (PerJoint.SceneNodes[i] == child) {
|
||||||
JointChildSceneNodes[i] = 0; // remove link to child
|
PerJoint.SceneNodes[i] = 0; // remove link to child
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,18 +537,17 @@ void CAnimatedMeshSceneNode::setRenderFromIdentity(bool enable)
|
||||||
void CAnimatedMeshSceneNode::addJoints()
|
void CAnimatedMeshSceneNode::addJoints()
|
||||||
{
|
{
|
||||||
const auto &joints = static_cast<SkinnedMesh*>(Mesh)->getAllJoints();
|
const auto &joints = static_cast<SkinnedMesh*>(Mesh)->getAllJoints();
|
||||||
JointChildSceneNodes.clear();
|
PerJoint.setN(joints.size());
|
||||||
JointChildSceneNodes.reserve(joints.size());
|
PerJoint.SceneNodes.clear();
|
||||||
PretransitingSave.clear();
|
PerJoint.SceneNodes.reserve(joints.size());
|
||||||
PretransitingSave.resize(JointChildSceneNodes.size());
|
|
||||||
for (size_t i = 0; i < joints.size(); ++i) {
|
for (size_t i = 0; i < joints.size(); ++i) {
|
||||||
const auto *joint = joints[i];
|
const auto *joint = joints[i];
|
||||||
ISceneNode *parent = this;
|
ISceneNode *parent = this;
|
||||||
if (joint->ParentJointID)
|
if (joint->ParentJointID)
|
||||||
parent = JointChildSceneNodes.at(*joint->ParentJointID); // exists because of topo. order
|
parent = PerJoint.SceneNodes.at(*joint->ParentJointID); // exists because of topo. order
|
||||||
assert(parent);
|
assert(parent);
|
||||||
const auto *matrix = std::get_if<core::matrix4>(&joint->transform);
|
const auto *matrix = std::get_if<core::matrix4>(&joint->transform);
|
||||||
JointChildSceneNodes.push_back(new CBoneSceneNode(
|
PerJoint.SceneNodes.push_back(new CBoneSceneNode(
|
||||||
parent, SceneManager, 0, i, joint->Name,
|
parent, SceneManager, 0, i, joint->Name,
|
||||||
matrix ? core::Transform{} : std::get<core::Transform>(joint->transform),
|
matrix ? core::Transform{} : std::get<core::Transform>(joint->transform),
|
||||||
matrix ? *matrix : std::optional<core::matrix4>{}));
|
matrix ? *matrix : std::optional<core::matrix4>{}));
|
||||||
|
@ -561,7 +559,7 @@ void CAnimatedMeshSceneNode::updateJointSceneNodes(
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < transforms.size(); ++i) {
|
for (size_t i = 0; i < transforms.size(); ++i) {
|
||||||
const auto &transform = transforms[i];
|
const auto &transform = transforms[i];
|
||||||
auto *node = static_cast<CBoneSceneNode*>(JointChildSceneNodes[i]);
|
auto *node = static_cast<CBoneSceneNode*>(PerJoint.SceneNodes[i]);
|
||||||
if (const auto *trs = std::get_if<core::Transform>(&transform)) {
|
if (const auto *trs = std::get_if<core::Transform>(&transform)) {
|
||||||
node->setTransform(*trs);
|
node->setTransform(*trs);
|
||||||
// .x lets animations override matrix transforms entirely.
|
// .x lets animations override matrix transforms entirely.
|
||||||
|
@ -589,10 +587,10 @@ void CAnimatedMeshSceneNode::animateJoints()
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
|
|
||||||
if (Transiting != 0.f) {
|
if (Transiting != 0.f) {
|
||||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i) {
|
for (u32 i = 0; i < PerJoint.SceneNodes.size(); ++i) {
|
||||||
if (PretransitingSave[i]) {
|
if (PerJoint.PreTransSaves[i]) {
|
||||||
JointChildSceneNodes[i]->setTransform(PretransitingSave[i]->interpolate(
|
PerJoint.SceneNodes[i]->setTransform(PerJoint.PreTransSaves[i]->interpolate(
|
||||||
JointChildSceneNodes[i]->getTransform(), TransitingBlend));
|
PerJoint.SceneNodes[i]->getTransform(), TransitingBlend));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,8 +602,8 @@ void CAnimatedMeshSceneNode::checkJoints()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!JointsUsed) {
|
if (!JointsUsed) {
|
||||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i)
|
for (u32 i = 0; i < PerJoint.SceneNodes.size(); ++i)
|
||||||
removeChild(JointChildSceneNodes[i]);
|
removeChild(PerJoint.SceneNodes[i]);
|
||||||
addJoints();
|
addJoints();
|
||||||
|
|
||||||
JointsUsed = true;
|
JointsUsed = true;
|
||||||
|
@ -619,11 +617,11 @@ void CAnimatedMeshSceneNode::beginTransition()
|
||||||
|
|
||||||
if (TransitionTime != 0) {
|
if (TransitionTime != 0) {
|
||||||
// Copy the transforms of animated joints
|
// Copy the transforms of animated joints
|
||||||
for (u32 i = 0; i < JointChildSceneNodes.size(); ++i) {
|
for (u32 i = 0; i < PerJoint.SceneNodes.size(); ++i) {
|
||||||
if (!JointChildSceneNodes[i]->Matrix) {
|
if (!PerJoint.SceneNodes[i]->Matrix) {
|
||||||
PretransitingSave[i] = JointChildSceneNodes[i]->getTransform();
|
PerJoint.PreTransSaves[i] = PerJoint.SceneNodes[i]->getTransform();
|
||||||
} else {
|
} else {
|
||||||
PretransitingSave[i] = std::nullopt;
|
PerJoint.PreTransSaves[i] = std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,8 +662,8 @@ ISceneNode *CAnimatedMeshSceneNode::clone(ISceneNode *newParent, ISceneManager *
|
||||||
newNode->Looping = Looping;
|
newNode->Looping = Looping;
|
||||||
newNode->ReadOnlyMaterials = ReadOnlyMaterials;
|
newNode->ReadOnlyMaterials = ReadOnlyMaterials;
|
||||||
newNode->PassCount = PassCount;
|
newNode->PassCount = PassCount;
|
||||||
newNode->JointChildSceneNodes = JointChildSceneNodes;
|
newNode->PerJoint.SceneNodes = PerJoint.SceneNodes;
|
||||||
newNode->PretransitingSave = PretransitingSave;
|
newNode->PerJoint.PreTransSaves = PerJoint.PreTransSaves;
|
||||||
newNode->RenderFromIdentity = RenderFromIdentity;
|
newNode->RenderFromIdentity = RenderFromIdentity;
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "SkinnedMesh.h"
|
#include "SkinnedMesh.h"
|
||||||
#include "Transform.h"
|
#include "Transform.h"
|
||||||
|
#include "matrix4.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -172,8 +173,21 @@ private:
|
||||||
s32 PassCount;
|
s32 PassCount;
|
||||||
std::function<void(f32)> OnAnimateCallback;
|
std::function<void(f32)> OnAnimateCallback;
|
||||||
|
|
||||||
std::vector<CBoneSceneNode *> JointChildSceneNodes;
|
struct PerJointData {
|
||||||
std::vector<std::optional<core::Transform>> PretransitingSave;
|
std::vector<CBoneSceneNode *> SceneNodes;
|
||||||
|
std::vector<core::matrix4> GlobalMatrices;
|
||||||
|
std::vector<std::optional<core::Transform>> PreTransSaves;
|
||||||
|
void setN(u16 n) {
|
||||||
|
SceneNodes.clear();
|
||||||
|
SceneNodes.resize(n);
|
||||||
|
GlobalMatrices.clear();
|
||||||
|
GlobalMatrices.resize(n);
|
||||||
|
PreTransSaves.clear();
|
||||||
|
PreTransSaves.resize(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PerJointData PerJoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue