1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

do the todo

This commit is contained in:
Lars Mueller 2025-02-04 16:05:34 +01:00
parent a1ed14f4c2
commit 1a8912716f
16 changed files with 38 additions and 319 deletions

View file

@ -13,8 +13,8 @@ namespace scene
//! Interface for an animated mesh. //! Interface for an animated mesh.
/** There are already simple implementations of this interface available so /** There are already simple implementations of this interface available so
you don't have to implement this interface on your own if you need to: you don't have to implement this interface on your own if you need to:
You might want to use irr::scene::SAnimatedMesh, irr::scene::SMesh, You might want to use irr::scene::SMesh, irr::scene::SMeshBuffer etc.
irr::scene::SMeshBuffer etc. */ */
class IAnimatedMesh : public IMesh class IAnimatedMesh : public IMesh
{ {
public: public:
@ -34,22 +34,8 @@ public:
scene node the mesh is instantiated in.*/ scene node the mesh is instantiated in.*/
virtual void setAnimationSpeed(f32 fps) = 0; virtual void setAnimationSpeed(f32 fps) = 0;
//! Returns the IMesh interface for a frame. //! Returns the type of the animated mesh. Useful for safe downcasts.
/** \param frame: Frame number, >= 0, <= getMaxFrameNumber() E_ANIMATED_MESH_TYPE getMeshType() const = 0;
Linear interpolation is used if this is between two frames.
\return Returns the animated mesh for the given frame */
virtual IMesh *getMesh(f32 frame) = 0;
//! Returns the type of the animated mesh.
/** In most cases it is not necessary to use this method.
This is useful for making a safe downcast. For example,
if getMeshType() returns EAMT_MD2 it's safe to cast the
IAnimatedMesh to IAnimatedMeshMD2.
\returns Type of the mesh. */
E_ANIMATED_MESH_TYPE getMeshType() const override
{
return EAMT_UNKNOWN;
}
}; };
} // end namespace scene } // end namespace scene

View file

@ -111,7 +111,7 @@ public:
virtual void setMesh(IAnimatedMesh *mesh) = 0; virtual void setMesh(IAnimatedMesh *mesh) = 0;
//! Returns the current mesh //! Returns the current mesh
virtual IAnimatedMesh *getMesh(void) = 0; virtual IAnimatedMesh *getMesh() = 0;
//! Sets the transition time in seconds //! Sets the transition time in seconds
/** Note: You must call animateJoints(), or the mesh will not animate. */ /** Note: You must call animateJoints(), or the mesh will not animate. */

View file

@ -20,38 +20,6 @@ enum E_ANIMATED_MESH_TYPE
//! Unknown animated mesh type. //! Unknown animated mesh type.
EAMT_UNKNOWN = 0, EAMT_UNKNOWN = 0,
//! Quake 2 MD2 model file
EAMT_MD2,
//! Quake 3 MD3 model file
EAMT_MD3,
//! Maya .obj static model
EAMT_OBJ,
//! Quake 3 .bsp static Map
EAMT_BSP,
//! 3D Studio .3ds file
EAMT_3DS,
//! My3D Mesh, the file format by Zhuck Dimitry
EAMT_MY3D,
//! Pulsar LMTools .lmts file. This Irrlicht loader was written by Jonas Petersen
EAMT_LMTS,
//! Cartography Shop .csm file. This loader was created by Saurav Mohapatra.
EAMT_CSM,
//! .oct file for Paul Nette's FSRad or from Murphy McCauley's Blender .oct exporter.
/** The oct file format contains 3D geometry and lightmaps and
can be loaded directly by Irrlicht */
EAMT_OCT,
//! Halflife MDL model file
EAMT_MDL_HALFLIFE,
//! generic skinned mesh //! generic skinned mesh
EAMT_SKINNED, EAMT_SKINNED,
@ -119,9 +87,7 @@ public:
virtual void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) = 0; virtual void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) = 0;
//! Returns the type of the meshes. //! Returns the type of the meshes.
/** This is useful for making a safe downcast. For example, /** This is useful for making a safe downcast.
if getMeshType() returns EAMT_MD2 it's safe to cast the
IMesh to IAnimatedMeshMD2.
Note: It's no longer just about animated meshes, that name has just historical reasons. Note: It's no longer just about animated meshes, that name has just historical reasons.
\returns Type of the mesh */ \returns Type of the mesh */
virtual E_ANIMATED_MESH_TYPE getMeshType() const virtual E_ANIMATED_MESH_TYPE getMeshType() const

View file

@ -66,26 +66,6 @@ public:
IReferenceCounted::drop() for more information. */ IReferenceCounted::drop() for more information. */
virtual SMesh *createMeshCopy(IMesh *mesh) const = 0; virtual SMesh *createMeshCopy(IMesh *mesh) const = 0;
//! Get amount of polygons in mesh.
/** \param mesh Input mesh
\return Number of polygons in mesh. */
virtual s32 getPolyCount(IMesh *mesh) const = 0;
//! Get amount of polygons in mesh.
/** \param mesh Input mesh
\return Number of polygons in mesh. */
virtual s32 getPolyCount(IAnimatedMesh *mesh) const = 0;
//! Create a new AnimatedMesh and adds the mesh to it
/** \param mesh Input mesh
\param type The type of the animated mesh to create.
\return Newly created animated mesh with mesh as its only
content. When you don't need the animated mesh anymore, you
should call IAnimatedMesh::drop(). See
IReferenceCounted::drop() for more information. */
virtual IAnimatedMesh *createAnimatedMesh(IMesh *mesh,
scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0;
//! Apply a manipulator on the Meshbuffer //! Apply a manipulator on the Meshbuffer
/** \param func A functor defining the mesh manipulation. /** \param func A functor defining the mesh manipulation.
\param buffer The Meshbuffer to apply the manipulator to. \param buffer The Meshbuffer to apply the manipulator to.

View file

@ -32,7 +32,7 @@ public:
//! Get the currently defined mesh for display. //! Get the currently defined mesh for display.
/** \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() = 0;
//! Sets if the scene node should not copy the materials of the mesh but use them directly. //! 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

View file

@ -1,167 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include <vector>
#include "IAnimatedMesh.h"
#include "IMesh.h"
#include "aabbox3d.h"
namespace irr
{
namespace scene
{
//! Simple implementation of the IAnimatedMesh interface.
struct SAnimatedMesh final : public IAnimatedMesh
{
//! constructor
SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) :
IAnimatedMesh(), FramesPerSecond(25.f), Type(type)
{
addMesh(mesh);
recalculateBoundingBox();
}
//! destructor
virtual ~SAnimatedMesh()
{
// drop meshes
for (auto *mesh : Meshes)
mesh->drop();
}
f32 getMaxFrameNumber() const override
{
return static_cast<f32>(Meshes.size() - 1);
}
//! Gets the default animation speed of the animated mesh.
/** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */
f32 getAnimationSpeed() const override
{
return FramesPerSecond;
}
//! Gets the frame count of the animated mesh.
/** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated.
The actual speed is set in the scene node the mesh is instantiated in.*/
void setAnimationSpeed(f32 fps) override
{
FramesPerSecond = fps;
}
//! Returns the IMesh interface for a frame.
/** \param frame: Frame number as zero based index.
\return The animated mesh based for the given frame */
IMesh *getMesh(f32 frame) override
{
if (Meshes.empty())
return nullptr;
return Meshes[static_cast<s32>(frame)];
}
//! adds a Mesh
void addMesh(IMesh *mesh)
{
if (mesh) {
mesh->grab();
Meshes.push_back(mesh);
}
}
//! Returns an axis aligned bounding box of the mesh.
/** \return A bounding box of this mesh is returned. */
const core::aabbox3d<f32> &getBoundingBox() const override
{
return Box;
}
//! set user axis aligned bounding box
void setBoundingBox(const core::aabbox3df &box) override
{
Box = box;
}
//! Recalculates the bounding box.
void recalculateBoundingBox()
{
Box.reset(0, 0, 0);
if (Meshes.empty())
return;
Box = Meshes[0]->getBoundingBox();
for (u32 i = 1; i < Meshes.size(); ++i)
Box.addInternalBox(Meshes[i]->getBoundingBox());
}
//! Returns the type of the animated mesh.
E_ANIMATED_MESH_TYPE getMeshType() const override
{
return Type;
}
//! returns amount of mesh buffers.
u32 getMeshBufferCount() const override
{
if (Meshes.empty())
return 0;
return Meshes[0]->getMeshBufferCount();
}
//! returns pointer to a mesh buffer
IMeshBuffer *getMeshBuffer(u32 nr) const override
{
if (Meshes.empty())
return 0;
return Meshes[0]->getMeshBuffer(nr);
}
//! Returns pointer to a mesh buffer which fits a material
/** \param material: material to search for
\return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */
IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const override
{
if (Meshes.empty())
return 0;
return Meshes[0]->getMeshBuffer(material);
}
//! set the hardware mapping hint, for driver
void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
{
for (u32 i = 0; i < Meshes.size(); ++i)
Meshes[i]->setHardwareMappingHint(newMappingHint, buffer);
}
//! flags the meshbuffer as changed, reloads hardware buffers
void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
{
for (u32 i = 0; i < Meshes.size(); ++i)
Meshes[i]->setDirty(buffer);
}
//! All meshes defining the animated mesh
std::vector<IMesh *> Meshes;
//! The bounding box of this mesh
core::aabbox3d<f32> Box{{0.0f, 0.0f, 0.0f}};
//! Default animation speed of this mesh.
f32 FramesPerSecond;
//! The type of the mesh.
E_ANIMATED_MESH_TYPE Type;
};
} // end namespace scene
} // end namespace irr

View file

@ -5,7 +5,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "IMesh.h" #include "IAnimatedMesh.h"
#include "IMeshBuffer.h" #include "IMeshBuffer.h"
#include "aabbox3d.h" #include "aabbox3d.h"
@ -14,7 +14,7 @@ namespace irr
namespace scene namespace scene
{ {
//! Simple implementation of the IMesh interface. //! Simple implementation of the IMesh interface.
struct SMesh final : public IMesh struct SMesh final : public IAnimatedMesh
{ {
//! constructor //! constructor
SMesh() {} SMesh() {}
@ -134,6 +134,15 @@ struct SMesh final : public IMesh
//! The bounding box of this mesh //! The bounding box of this mesh
core::aabbox3d<f32> BoundingBox{{0, 0, 0}}; core::aabbox3d<f32> BoundingBox{{0, 0, 0}};
// Implement animated mesh interface as a static mesh.
// Slightly hacky: Eventually should be consolidated with SSkinnedMesh,
// with all the animation-related parts behind an optional.
virtual f32 getMaxFrameNumber() const override { return 0.0f; }
virtual f32 getAnimationSpeed() const override { return 0.0f; }
virtual void setAnimationSpeed(f32 fps) override {}
E_ANIMATED_MESH_TYPE getMeshType() const override { return EAMT_STATIC; }
}; };
} // end namespace scene } // end namespace scene

View file

@ -70,13 +70,6 @@ public:
The actual speed is set in the scene node the mesh is instantiated in.*/ The actual speed is set in the scene node the mesh is instantiated in.*/
void setAnimationSpeed(f32 fps) override; void setAnimationSpeed(f32 fps) override;
//! **Must not be called**.
IMesh *getMesh(f32) override {
// TODO refactor Irrlicht so that we need not implement this.
_IRR_DEBUG_BREAK_IF(true);
return nullptr;
};
//! Turns the given array of local matrices into an array of global matrices //! Turns the given array of local matrices into an array of global matrices
//! by multiplying with respective parent matrices. //! by multiplying with respective parent matrices.
void calculateGlobalMatrices(std::vector<core::matrix4> &matrices) const; void calculateGlobalMatrices(std::vector<core::matrix4> &matrices) const;

View file

@ -151,9 +151,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame() IMesh *CAnimatedMeshSceneNode::getMeshForCurrentFrame()
{ {
if (Mesh->getMeshType() != EAMT_SKINNED) { if (Mesh->getMeshType() != EAMT_SKINNED) {
auto *res = Mesh->getMesh(getFrameNr()); return Mesh;
Box = res->getBoundingBox();
return res;
} }
// As multiple scene nodes may be sharing the same skinned mesh, we have to // As multiple scene nodes may be sharing the same skinned mesh, we have to
@ -194,8 +192,11 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
if (auto *skinnedMesh = dynamic_cast<SkinnedMesh*>(Mesh)) { if (auto *skinnedMesh = dynamic_cast<SkinnedMesh*>(Mesh)) {
for (u16 i = 0; i < PerJoint.SceneNodes.size(); ++i) for (u16 i = 0; i < PerJoint.SceneNodes.size(); ++i)
PerJoint.GlobalMatrices[i] = PerJoint.SceneNodes[i]->getRelativeTransformation(); PerJoint.GlobalMatrices[i] = PerJoint.SceneNodes[i]->getRelativeTransformation();
_IRR_DEBUG_BREAK_IF(PerJoint.GlobalMatrices.size() != skinnedMesh->getJointCount());
skinnedMesh->calculateGlobalMatrices(PerJoint.GlobalMatrices); skinnedMesh->calculateGlobalMatrices(PerJoint.GlobalMatrices);
Box = skinnedMesh->calculateBoundingBox(PerJoint.GlobalMatrices); Box = skinnedMesh->calculateBoundingBox(PerJoint.GlobalMatrices);
} else {
Box = Mesh->getBoundingBox();
} }
} }

View file

@ -35,7 +35,7 @@ void CMeshCache::removeMesh(const IMesh *const mesh)
if (!mesh) if (!mesh)
return; return;
for (u32 i = 0; i < Meshes.size(); ++i) { for (u32 i = 0; i < Meshes.size(); ++i) {
if (Meshes[i].Mesh == mesh || (Meshes[i].Mesh && Meshes[i].Mesh->getMesh(0) == mesh)) { if (Meshes[i].Mesh == mesh) {
Meshes[i].Mesh->drop(); Meshes[i].Mesh->drop();
Meshes.erase(i); Meshes.erase(i);
return; return;
@ -53,7 +53,7 @@ u32 CMeshCache::getMeshCount() const
s32 CMeshCache::getMeshIndex(const IMesh *const mesh) const s32 CMeshCache::getMeshIndex(const IMesh *const mesh) const
{ {
for (u32 i = 0; i < Meshes.size(); ++i) { for (u32 i = 0; i < Meshes.size(); ++i) {
if (Meshes[i].Mesh == mesh || (Meshes[i].Mesh && Meshes[i].Mesh->getMesh(0) == mesh)) if (Meshes[i].Mesh == mesh)
return (s32)i; return (s32)i;
} }
@ -93,7 +93,7 @@ const io::SNamedPath &CMeshCache::getMeshName(const IMesh *const mesh) const
return emptyNamedPath; return emptyNamedPath;
for (u32 i = 0; i < Meshes.size(); ++i) { for (u32 i = 0; i < Meshes.size(); ++i) {
if (Meshes[i].Mesh == mesh || (Meshes[i].Mesh && Meshes[i].Mesh->getMesh(0) == mesh)) if (Meshes[i].Mesh == mesh)
return Meshes[i].NamedPath; return Meshes[i].NamedPath;
} }
@ -115,7 +115,7 @@ bool CMeshCache::renameMesh(u32 index, const io::path &name)
bool CMeshCache::renameMesh(const IMesh *const mesh, const io::path &name) bool CMeshCache::renameMesh(const IMesh *const mesh, const io::path &name)
{ {
for (u32 i = 0; i < Meshes.size(); ++i) { for (u32 i = 0; i < Meshes.size(); ++i) {
if (Meshes[i].Mesh == mesh || (Meshes[i].Mesh && Meshes[i].Mesh->getMesh(0) == mesh)) { if (Meshes[i].Mesh == mesh) {
Meshes[i].NamedPath.setPath(name); Meshes[i].NamedPath.setPath(name);
Meshes.sort(); Meshes.sort();
return true; return true;

View file

@ -6,7 +6,6 @@
#include "SkinnedMesh.h" #include "SkinnedMesh.h"
#include "SMesh.h" #include "SMesh.h"
#include "CMeshBuffer.h" #include "CMeshBuffer.h"
#include "SAnimatedMesh.h"
#include "os.h" #include "os.h"
#include <cassert> #include <cassert>
@ -178,34 +177,5 @@ SMesh *CMeshManipulator::createMeshCopy(scene::IMesh *mesh) const
return clone; return clone;
} }
//! Returns amount of polygons in mesh.
s32 CMeshManipulator::getPolyCount(scene::IMesh *mesh) const
{
if (!mesh)
return 0;
s32 trianglecount = 0;
for (u32 g = 0; g < mesh->getMeshBufferCount(); ++g)
trianglecount += mesh->getMeshBuffer(g)->getIndexCount() / 3;
return trianglecount;
}
//! Returns amount of polygons in mesh.
s32 CMeshManipulator::getPolyCount(scene::IAnimatedMesh *mesh) const
{
if (mesh && mesh->getMaxFrameNumber() != 0)
return getPolyCount(mesh->getMesh(0));
return 0;
}
//! create a new AnimatedMesh and adds the mesh to it
IAnimatedMesh *CMeshManipulator::createAnimatedMesh(scene::IMesh *mesh, scene::E_ANIMATED_MESH_TYPE type) const
{
return new SAnimatedMesh(mesh, type);
}
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr

View file

@ -31,15 +31,6 @@ public:
//! Clones a static IMesh into a modifiable SMesh. //! Clones a static IMesh into a modifiable SMesh.
SMesh *createMeshCopy(scene::IMesh *mesh) const override; SMesh *createMeshCopy(scene::IMesh *mesh) const override;
//! Returns amount of polygons in mesh.
s32 getPolyCount(scene::IMesh *mesh) const override;
//! Returns amount of polygons in mesh.
s32 getPolyCount(scene::IAnimatedMesh *mesh) const override;
//! create a new AnimatedMesh and adds the mesh to it
IAnimatedMesh *createAnimatedMesh(scene::IMesh *mesh, scene::E_ANIMATED_MESH_TYPE type) const override;
}; };
} // end namespace scene } // end namespace scene

View file

@ -1238,7 +1238,7 @@ void CNullDriver::addOcclusionQuery(scene::ISceneNode *node, const scene::IMesh
else if (node->getType() == scene::ESNT_MESH) else if (node->getType() == scene::ESNT_MESH)
mesh = static_cast<scene::IMeshSceneNode *>(node)->getMesh(); mesh = static_cast<scene::IMeshSceneNode *>(node)->getMesh();
else else
mesh = static_cast<scene::IAnimatedMeshSceneNode *>(node)->getMesh()->getMesh(0); mesh = static_cast<scene::IAnimatedMeshSceneNode *>(node)->getMesh();
if (!mesh) if (!mesh)
return; return;
} }

View file

@ -7,7 +7,6 @@
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "SMesh.h" #include "SMesh.h"
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
#include "SAnimatedMesh.h"
#include "IReadFile.h" #include "IReadFile.h"
#include "fast_atof.h" #include "fast_atof.h"
#include "coreutil.h" #include "coreutil.h"
@ -272,23 +271,19 @@ IAnimatedMesh *COBJMeshFileLoader::createMesh(io::IReadFile *file)
} }
} }
// Create the Animated mesh if there's anything in the mesh
SAnimatedMesh *animMesh = 0;
if (0 != mesh->getMeshBufferCount()) {
mesh->recalculateBoundingBox();
animMesh = new SAnimatedMesh();
animMesh->Type = EAMT_OBJ;
animMesh->addMesh(mesh);
animMesh->recalculateBoundingBox();
}
// Clean up the allocate obj file contents // Clean up the allocate obj file contents
delete[] buf; delete[] buf;
// more cleaning up // more cleaning up
cleanUp(); cleanUp();
mesh->drop();
return animMesh; // Nothing in the mesh
if (mesh->getMeshBufferCount() == 0) {
mesh->drop();
return nullptr;
}
mesh->recalculateBoundingBox();
return mesh;
} }
//! Read RGB color //! Read RGB color

View file

@ -8,7 +8,6 @@
#include "CSceneManager.h" #include "CSceneManager.h"
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "IFileSystem.h" #include "IFileSystem.h"
#include "SAnimatedMesh.h"
#include "CMeshCache.h" #include "CMeshCache.h"
#include "IGUIEnvironment.h" #include "IGUIEnvironment.h"
#include "IMaterialRenderer.h" #include "IMaterialRenderer.h"

View file

@ -10,10 +10,9 @@
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <IAnimatedMesh.h> #include <IAnimatedMesh.h>
#include <SAnimatedMesh.h>
#include <IAnimatedMeshSceneNode.h> #include <IAnimatedMeshSceneNode.h>
#include "S3DVertex.h" #include "S3DVertex.h"
#include "SMesh.h" #include <SMesh.h>
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
inline static void applyShadeFactor(video::SColor& color, float factor) inline static void applyShadeFactor(video::SColor& color, float factor)
@ -97,11 +96,8 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale)
mesh->addMeshBuffer(buf); mesh->addMeshBuffer(buf);
buf->drop(); buf->drop();
} }
scaleMesh(mesh, scale); // also recalculates bounding box
scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh); return mesh;
mesh->drop();
scaleMesh(anim_mesh, scale); // also recalculates bounding box
return anim_mesh;
} }
template<typename F> template<typename F>