1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-11 09:36:37 +00:00
OpenMW/components/sceneutil/riggeometry.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

125 lines
4.5 KiB
C++
Raw Normal View History

#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
{
class Skeleton;
class Bone;
// 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.
/// @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
{
public:
RigGeometry();
RigGeometry(const RigGeometry& copy, const osg::CopyOp& copyop);
2015-12-06 14:27:43 +00:00
META_Object(SceneUtil, RigGeometry)
// 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.
void compileGLObjects(osg::RenderInfo& renderInfo) const override {}
struct BoneInfluence
{
osg::Matrixf mInvBindMatrix;
osg::BoundingSpheref mBoundSphere;
// <vertex index, weight>
std::vector<std::pair<unsigned short, float>> mWeights;
};
struct InfluenceMap : public osg::Referenced
{
std::vector<std::pair<std::string, BoneInfluence>> mData;
};
void setInfluenceMap(osg::ref_ptr<InfluenceMap> influenceMap);
2016-03-11 18:18:51 +00:00
/// Initialize this geometry from the source geometry.
/// @note The source geometry will not be modified.
void setSourceGeometry(osg::ref_ptr<osg::Geometry> sourceGeom);
osg::ref_ptr<osg::Geometry> getSourceGeometry() const;
void accept(osg::NodeVisitor& nv) override;
bool supports(const osg::PrimitiveFunctor&) const override { return true; }
void accept(osg::PrimitiveFunctor&) const override;
struct CopyBoundingBoxCallback : osg::Drawable::ComputeBoundingBoxCallback
{
osg::BoundingBox boundingBox;
osg::BoundingBox computeBound(const osg::Drawable&) const override { return boundingBox; }
};
struct CopyBoundingSphereCallback : osg::Node::ComputeBoundingSphereCallback
{
osg::BoundingSphere boundingSphere;
osg::BoundingSphere computeBound(const osg::Node&) const override { return boundingSphere; }
};
private:
void cull(osg::NodeVisitor* nv);
void updateBounds(osg::NodeVisitor* nv);
osg::ref_ptr<osg::Geometry> mGeometry[2];
osg::Geometry* getGeometry(unsigned int frame) const;
osg::ref_ptr<osg::Geometry> mSourceGeometry;
2017-09-01 21:02:19 +00:00
osg::ref_ptr<const osg::Vec4Array> mSourceTangents;
2015-05-26 17:12:29 +00:00
Skeleton* mSkeleton;
osg::ref_ptr<osg::RefMatrix> mGeomToSkelMatrix;
osg::ref_ptr<InfluenceMap> mInfluenceMap;
typedef std::pair<std::string, osg::Matrixf> BoneBindMatrixPair;
typedef std::pair<BoneBindMatrixPair, float> BoneWeight;
typedef std::vector<unsigned short> VertexList;
2015-04-25 17:32:07 +00:00
typedef std::map<std::vector<BoneWeight>, VertexList> Bone2VertexMap;
2019-01-11 17:20:58 +00:00
struct Bone2VertexVector : public osg::Referenced
{
std::vector<std::pair<std::vector<BoneWeight>, VertexList>> mData;
2019-01-11 17:20:58 +00:00
};
osg::ref_ptr<Bone2VertexVector> mBone2VertexVector;
2019-01-11 17:20:58 +00:00
struct BoneSphereVector : public osg::Referenced
{
std::vector<std::pair<std::string, osg::BoundingSpheref>> mData;
2019-01-11 17:20:58 +00:00
};
osg::ref_ptr<BoneSphereVector> mBoneSphereVector;
std::vector<Bone*> mBoneNodesVector;
unsigned int mLastFrameNumber;
bool mBoundsFirstFrame;
bool initFromParentSkeleton(osg::NodeVisitor* nv);
void updateGeomToSkelMatrix(const osg::NodePath& nodePath);
};
}
#endif