2015-04-21 14:02:40 +00:00
|
|
|
#ifndef OPENMW_COMPONENTS_NIFOSG_RIGGEOMETRY_H
|
|
|
|
#define OPENMW_COMPONENTS_NIFOSG_RIGGEOMETRY_H
|
|
|
|
|
|
|
|
#include <osg/Geometry>
|
|
|
|
#include <osg/Matrixf>
|
|
|
|
|
2015-04-21 18:30:48 +00:00
|
|
|
namespace SceneUtil
|
2015-04-21 14:02:40 +00:00
|
|
|
{
|
|
|
|
class Skeleton;
|
|
|
|
class Bone;
|
|
|
|
|
2021-10-23 08:31:46 +00:00
|
|
|
// TODO: This class has a lot of issues.
|
|
|
|
// - We require too many workarounds to ensure safety.
|
|
|
|
// - mSourceGeometry should be const, but can not be const because of a use case in shadervisitor.cpp.
|
|
|
|
// - We create useless mGeometry clones in template RigGeometries.
|
|
|
|
// - We do not support compileGLObjects.
|
|
|
|
// - We duplicate some code in MorphGeometry.
|
|
|
|
|
2015-04-21 18:42:50 +00:00
|
|
|
/// @brief Mesh skinning implementation.
|
|
|
|
/// @note A RigGeometry may be attached directly to a Skeleton, or somewhere below a Skeleton.
|
|
|
|
/// Note though that the RigGeometry ignores any transforms below the Skeleton, so the attachment point is not that
|
|
|
|
/// important.
|
2017-09-01 16:27:00 +00:00
|
|
|
/// @note The internal Geometry used for rendering is double buffered, this allows updates to be done in a thread
|
|
|
|
/// safe way while not compromising rendering performance. This is crucial when using osg's default threading model
|
|
|
|
/// of DrawThreadPerContext.
|
|
|
|
class RigGeometry : public osg::Drawable
|
2015-04-21 14:02:40 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
RigGeometry();
|
|
|
|
RigGeometry(const RigGeometry& copy, const osg::CopyOp& copyop);
|
|
|
|
|
2015-12-06 14:27:43 +00:00
|
|
|
META_Object(SceneUtil, RigGeometry)
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2018-04-15 12:38:03 +00:00
|
|
|
// Currently empty as this is difficult to implement. Technically we would need to compile both internal
|
|
|
|
// geometries in separate frames but this method is only called once. Alternatively we could compile just the
|
|
|
|
// static parts of the model.
|
2020-10-16 18:18:54 +00:00
|
|
|
void compileGLObjects(osg::RenderInfo& renderInfo) const override {}
|
2017-09-01 16:27:00 +00:00
|
|
|
|
2023-12-07 21:19:14 +00:00
|
|
|
struct BoneInfo
|
2015-04-21 14:02:40 +00:00
|
|
|
{
|
2023-12-07 21:19:14 +00:00
|
|
|
std::string mName;
|
2015-04-27 13:41:34 +00:00
|
|
|
osg::BoundingSpheref mBoundSphere;
|
2023-12-07 21:19:14 +00:00
|
|
|
osg::Matrixf mInvBindMatrix;
|
2015-04-21 14:02:40 +00:00
|
|
|
};
|
|
|
|
|
2023-12-07 21:19:14 +00:00
|
|
|
using VertexWeight = std::pair<unsigned short, float>;
|
|
|
|
using VertexWeights = std::vector<VertexWeight>;
|
|
|
|
using BoneWeight = std::pair<size_t, float>;
|
|
|
|
using BoneWeights = std::vector<BoneWeight>;
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2023-12-07 21:19:14 +00:00
|
|
|
void setBoneInfo(std::vector<BoneInfo>&& bones);
|
|
|
|
// Convert influences in vertex and weight list per bone format
|
|
|
|
void setInfluences(const std::vector<VertexWeights>& influences);
|
|
|
|
// Convert influences in bone and weight list per vertex format
|
|
|
|
void setInfluences(const std::vector<BoneWeights>& influences);
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2016-03-11 18:18:51 +00:00
|
|
|
/// Initialize this geometry from the source geometry.
|
|
|
|
/// @note The source geometry will not be modified.
|
2015-04-21 14:02:40 +00:00
|
|
|
void setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeom);
|
|
|
|
|
2019-06-13 13:37:00 +00:00
|
|
|
osg::ref_ptr<osg::Geometry> getSourceGeometry() const;
|
2016-03-23 15:48:41 +00:00
|
|
|
|
2020-10-16 18:18:54 +00:00
|
|
|
void accept(osg::NodeVisitor& nv) override;
|
|
|
|
bool supports(const osg::PrimitiveFunctor&) const override { return true; }
|
|
|
|
void accept(osg::PrimitiveFunctor&) const override;
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2018-08-08 22:24:57 +00:00
|
|
|
struct CopyBoundingBoxCallback : osg::Drawable::ComputeBoundingBoxCallback
|
|
|
|
{
|
|
|
|
osg::BoundingBox boundingBox;
|
|
|
|
|
2020-10-16 18:18:54 +00:00
|
|
|
osg::BoundingBox computeBound(const osg::Drawable&) const override { return boundingBox; }
|
2018-08-08 22:24:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CopyBoundingSphereCallback : osg::Node::ComputeBoundingSphereCallback
|
|
|
|
{
|
|
|
|
osg::BoundingSphere boundingSphere;
|
|
|
|
|
2020-10-16 18:18:54 +00:00
|
|
|
osg::BoundingSphere computeBound(const osg::Node&) const override { return boundingSphere; }
|
2018-08-08 22:24:57 +00:00
|
|
|
};
|
|
|
|
|
2017-09-01 16:27:00 +00:00
|
|
|
private:
|
|
|
|
void cull(osg::NodeVisitor* nv);
|
2015-04-27 13:41:34 +00:00
|
|
|
void updateBounds(osg::NodeVisitor* nv);
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2017-09-01 16:27:00 +00:00
|
|
|
osg::ref_ptr<osg::Geometry> mGeometry[2];
|
|
|
|
osg::Geometry* getGeometry(unsigned int frame) const;
|
|
|
|
|
2016-03-22 22:28:57 +00:00
|
|
|
osg::ref_ptr<osg::Geometry> mSourceGeometry;
|
2017-09-01 21:02:19 +00:00
|
|
|
osg::ref_ptr<const osg::Vec4Array> mSourceTangents;
|
2023-10-02 22:27:14 +00:00
|
|
|
Skeleton* mSkeleton{ nullptr };
|
2015-04-21 14:02:40 +00:00
|
|
|
|
2017-02-03 05:44:14 +00:00
|
|
|
osg::ref_ptr<osg::RefMatrix> mGeomToSkelMatrix;
|
2015-11-22 18:49:11 +00:00
|
|
|
|
2023-10-02 22:27:14 +00:00
|
|
|
using VertexList = std::vector<unsigned short>;
|
|
|
|
struct InfluenceData : public osg::Referenced
|
2019-01-11 17:20:58 +00:00
|
|
|
{
|
2023-10-02 22:27:14 +00:00
|
|
|
std::vector<BoneInfo> mBones;
|
2023-12-07 21:19:14 +00:00
|
|
|
std::vector<std::pair<BoneWeights, VertexList>> mInfluences;
|
2019-01-11 17:20:58 +00:00
|
|
|
};
|
2023-10-02 22:27:14 +00:00
|
|
|
osg::ref_ptr<InfluenceData> mData;
|
|
|
|
std::vector<Bone*> mNodes;
|
2015-04-27 13:41:34 +00:00
|
|
|
|
2023-10-02 22:27:14 +00:00
|
|
|
unsigned int mLastFrameNumber{ 0 };
|
|
|
|
bool mBoundsFirstFrame{ true };
|
2015-04-29 21:48:08 +00:00
|
|
|
|
2015-04-21 14:02:40 +00:00
|
|
|
bool initFromParentSkeleton(osg::NodeVisitor* nv);
|
2015-04-27 13:41:34 +00:00
|
|
|
|
2016-07-02 17:27:19 +00:00
|
|
|
void updateGeomToSkelMatrix(const osg::NodePath& nodePath);
|
2015-04-21 14:02:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|