|
|
@@ -3,9 +3,11 @@
|
|
|
|
|
|
#include "anki/scene/SceneNode.h"
|
|
|
#include "anki/scene/Renderable.h"
|
|
|
-#include "anki/scene/MaterialRuntime.h"
|
|
|
+#include "anki/scene/Movable.h"
|
|
|
+#include "anki/scene/Spatial.h"
|
|
|
#include "anki/resource/Model.h"
|
|
|
#include "anki/math/Math.h"
|
|
|
+
|
|
|
#include <boost/range/iterator_range.hpp>
|
|
|
#include <vector>
|
|
|
|
|
|
@@ -30,7 +32,7 @@ public:
|
|
|
};
|
|
|
|
|
|
/// Create the @a tfVbos with empty data
|
|
|
- SkinMesh(const Mesh* mesh_);
|
|
|
+ SkinMesh(const MeshBase* mesh_);
|
|
|
|
|
|
/// @name Accessors
|
|
|
/// @{
|
|
|
@@ -72,7 +74,7 @@ public:
|
|
|
|
|
|
private:
|
|
|
boost::array<Vbo, VBOS_TF_COUNT> tfVbos;
|
|
|
- const Mesh* mesh; ///< The resource
|
|
|
+ const MeshBase* mesh; ///< The resource
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -80,13 +82,37 @@ private:
|
|
|
class SkinModelPatch: public ModelPatchBase
|
|
|
{
|
|
|
public:
|
|
|
- SkinModelPatch(const ModelPatch* mpatch_)
|
|
|
- : mpatch(mpatch_)
|
|
|
+ /// See TfHwSkinningGeneric.glsl for the locations
|
|
|
+ enum TfShaderProgAttribLoc
|
|
|
{
|
|
|
- skinMesh.reset(new SkinMesh(&mpatch->getMeshBase()));
|
|
|
- create();
|
|
|
+ POSITION_LOC,
|
|
|
+ NORMAL_LOC,
|
|
|
+ TANGENT_LOC,
|
|
|
+ VERT_WEIGHT_BONES_NUM_LOC,
|
|
|
+ VERT_WEIGHT_BONE_IDS_LOC,
|
|
|
+ VERT_WEIGHT_WEIGHTS_LOC
|
|
|
+ };
|
|
|
+
|
|
|
+ /// @name Constructors/Destructor
|
|
|
+ /// @{
|
|
|
+ SkinModelPatch(const ModelPatch* mpatch_);
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// @name Accessors
|
|
|
+ /// @{
|
|
|
+ SkinMesh& getSkinMesh()
|
|
|
+ {
|
|
|
+ return *skinMesh;
|
|
|
+ }
|
|
|
+
|
|
|
+ const SkinMesh& getSkinMesh() const
|
|
|
+ {
|
|
|
+ return *skinMesh;
|
|
|
}
|
|
|
+ /// @}
|
|
|
|
|
|
+ /// @name Implementations of ModelPatchBase virtuals
|
|
|
+ /// @{
|
|
|
const MeshBase& getMeshBase() const
|
|
|
{
|
|
|
return *skinMesh;
|
|
|
@@ -96,10 +122,12 @@ public:
|
|
|
{
|
|
|
return mpatch->getMaterial();
|
|
|
}
|
|
|
+ /// @}
|
|
|
|
|
|
private:
|
|
|
boost::scoped_ptr<SkinMesh> skinMesh;
|
|
|
const ModelPatch* mpatch;
|
|
|
+ Vao tfVao;
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -108,17 +136,6 @@ class SkinPatchNode: public SceneNode, public Movable, public Renderable,
|
|
|
public Spatial
|
|
|
{
|
|
|
public:
|
|
|
- /// See TfHwSkinningGeneric.glsl for the locations
|
|
|
- enum TfShaderProgAttribLoc
|
|
|
- {
|
|
|
- POSITION_LOC,
|
|
|
- NORMAL_LOC,
|
|
|
- TANGENT_LOC,
|
|
|
- VERT_WEIGHT_BONES_NUM_LOC,
|
|
|
- VERT_WEIGHT_BONE_IDS_LOC,
|
|
|
- VERT_WEIGHT_WEIGHTS_LOC
|
|
|
- };
|
|
|
-
|
|
|
/// @name Constructors/Destructor
|
|
|
/// @{
|
|
|
SkinPatchNode(const ModelPatch* modelPatch_,
|
|
|
@@ -172,169 +189,190 @@ private:
|
|
|
|
|
|
|
|
|
/// A skin scene node
|
|
|
-class SkinNode: public SceneNode
|
|
|
+class SkinNode: public SceneNode, public Movable
|
|
|
{
|
|
|
- public:
|
|
|
- template<typename T>
|
|
|
- class Types
|
|
|
- {
|
|
|
- public:
|
|
|
- typedef std::vector<T> Container;
|
|
|
- typedef typename Container::iterator Iterator;
|
|
|
- typedef typename Container::const_iterator ConstIterator;
|
|
|
- typedef boost::iterator_range<Iterator> MutableRange;
|
|
|
- typedef boost::iterator_range<ConstIterator> ConstRange;
|
|
|
- };
|
|
|
-
|
|
|
- SkinNode(Scene& scene, ulong flags, SceneNode* parent);
|
|
|
- ~SkinNode();
|
|
|
-
|
|
|
- /// @name Accessors
|
|
|
- /// @{
|
|
|
- Types<Vec3>::ConstRange getHeads() const
|
|
|
- {
|
|
|
- return Types<Vec3>::ConstRange(heads.begin(), heads.end());
|
|
|
- }
|
|
|
- Types<Vec3>::MutableRange getHeads()
|
|
|
- {
|
|
|
- return Types<Vec3>::MutableRange(heads.begin(), heads.end());
|
|
|
- }
|
|
|
-
|
|
|
- Types<Vec3>::ConstRange getTails() const
|
|
|
- {
|
|
|
- return Types<Vec3>::ConstRange(tails.begin(), tails.end());
|
|
|
- }
|
|
|
- Types<Vec3>::MutableRange getTails()
|
|
|
- {
|
|
|
- return Types<Vec3>::MutableRange(tails.begin(), tails.end());
|
|
|
- }
|
|
|
-
|
|
|
- Types<Mat3>::ConstRange getBoneRotations() const
|
|
|
- {
|
|
|
- return Types<Mat3>::ConstRange(boneRotations.begin(),
|
|
|
- boneRotations.end());
|
|
|
- }
|
|
|
- Types<Mat3>::MutableRange getBoneRotations()
|
|
|
- {
|
|
|
- return Types<Mat3>::MutableRange(boneRotations.begin(),
|
|
|
- boneRotations.end());
|
|
|
- }
|
|
|
-
|
|
|
- Types<Vec3>::ConstRange getBoneTranslations() const
|
|
|
- {
|
|
|
- return Types<Vec3>::ConstRange(boneTranslations.begin(),
|
|
|
- boneTranslations.end());
|
|
|
- }
|
|
|
- Types<Vec3>::MutableRange getBoneTranslations()
|
|
|
- {
|
|
|
- return Types<Vec3>::MutableRange(boneTranslations.begin(),
|
|
|
- boneTranslations.end());
|
|
|
- }
|
|
|
-
|
|
|
- Types<SkinPatchNode*>::ConstRange getPatchNodes() const
|
|
|
- {
|
|
|
- return Types<SkinPatchNode*>::ConstRange(patches.begin(),
|
|
|
- patches.end());
|
|
|
- }
|
|
|
- Types<SkinPatchNode*>::MutableRange getPatchNodes()
|
|
|
- {
|
|
|
- return Types<SkinPatchNode*>::MutableRange(patches.begin(),
|
|
|
- patches.end());
|
|
|
- }
|
|
|
-
|
|
|
- const CollisionShape*
|
|
|
- getVisibilityCollisionShapeWorldSpace() const
|
|
|
- {
|
|
|
- return &visibilityShapeWSpace;
|
|
|
- }
|
|
|
-
|
|
|
- const Skin& getSkin() const
|
|
|
- {
|
|
|
- return *skin;
|
|
|
- }
|
|
|
-
|
|
|
- float getStep() const
|
|
|
- {
|
|
|
- return step;
|
|
|
- }
|
|
|
- float& getStep()
|
|
|
- {
|
|
|
- return step;
|
|
|
- }
|
|
|
- void setStep(const float x)
|
|
|
- {
|
|
|
- step = x;
|
|
|
- }
|
|
|
-
|
|
|
- float getFrame() const
|
|
|
- {
|
|
|
- return frame;
|
|
|
- }
|
|
|
- float& getFrame()
|
|
|
- {
|
|
|
- return frame;
|
|
|
- }
|
|
|
- void setFrame(const float x)
|
|
|
- {
|
|
|
- frame = x;
|
|
|
- }
|
|
|
-
|
|
|
- void setAnimation(const SkelAnim& anim_)
|
|
|
- {
|
|
|
- anim = &anim_;
|
|
|
- }
|
|
|
- const SkelAnim* getAnimation() const
|
|
|
- {
|
|
|
- return anim;
|
|
|
- }
|
|
|
- /// @}
|
|
|
-
|
|
|
- void init(const char* filename);
|
|
|
-
|
|
|
- /// Update boundingShapeWSpace from bone tails (not heads as well
|
|
|
- /// cause its faster that way). The tails come from the previous frame
|
|
|
- void moveUpdate();
|
|
|
-
|
|
|
- /// Update the animation stuff
|
|
|
- void frameUpdate(float prevUpdateTime, float crntTime);
|
|
|
-
|
|
|
- private:
|
|
|
- SkinResourcePointer skin; ///< The resource
|
|
|
- std::vector<SkinPatchNode*> patches;
|
|
|
- Obb visibilityShapeWSpace;
|
|
|
-
|
|
|
- /// @name Animation stuff
|
|
|
- /// @{
|
|
|
- float step;
|
|
|
- float frame;
|
|
|
- const SkelAnim* anim; ///< The active skeleton animation
|
|
|
- /// @}
|
|
|
-
|
|
|
- /// @name Bone data
|
|
|
- /// @{
|
|
|
- std::vector<Vec3> heads;
|
|
|
- std::vector<Vec3> tails;
|
|
|
- std::vector<Mat3> boneRotations;
|
|
|
- std::vector<Vec3> boneTranslations;
|
|
|
- /// @}
|
|
|
-
|
|
|
- /// Interpolate
|
|
|
- /// @param[in] animation Animation
|
|
|
- /// @param[in] frame Frame
|
|
|
- /// @param[out] translations Translations vector
|
|
|
- /// @param[out] rotations Rotations vector
|
|
|
- static void interpolate(const SkelAnim& animation, float frame,
|
|
|
- std::vector<Vec3>& translations, std::vector<Mat3>& rotations);
|
|
|
-
|
|
|
- /// Calculate the global pose
|
|
|
- static void updateBoneTransforms(const Skeleton& skel,
|
|
|
- std::vector<Vec3>& translations, std::vector<Mat3>& rotations);
|
|
|
-
|
|
|
- /// Deform the heads and tails
|
|
|
- static void deformHeadsTails(const Skeleton& skeleton,
|
|
|
- const std::vector<Vec3>& boneTranslations,
|
|
|
- const std::vector<Mat3>& boneRotations,
|
|
|
- std::vector<Vec3>& heads, std::vector<Vec3>& tails);
|
|
|
+public:
|
|
|
+ template<typename T>
|
|
|
+ struct Types
|
|
|
+ {
|
|
|
+ typedef std::vector<T> Container;
|
|
|
+ typedef typename Container::iterator Iterator;
|
|
|
+ typedef typename Container::const_iterator ConstIterator;
|
|
|
+ typedef boost::iterator_range<Iterator> MutableRange;
|
|
|
+ typedef boost::iterator_range<ConstIterator> ConstRange;
|
|
|
+ };
|
|
|
+
|
|
|
+ typedef boost::ptr_vector<SkinPatchNode> PatchesContainer;
|
|
|
+ typedef boost::iterator_range<PatchesContainer::iterator>
|
|
|
+ PatchesMutableRange;
|
|
|
+ typedef boost::iterator_range<PatchesContainer::const_iterator>
|
|
|
+ PatchesConstRange;
|
|
|
+
|
|
|
+ /// @name Constructors/Destructor
|
|
|
+ /// @{
|
|
|
+ SkinNode(const char* skinFname,
|
|
|
+ const char* name, Scene* scene, // SceneNode
|
|
|
+ uint movableFlags, Movable* movParent); // Movable
|
|
|
+
|
|
|
+ ~SkinNode();
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// @name SceneNode virtuals
|
|
|
+ /// @{
|
|
|
+
|
|
|
+ /// Override SceneNode::getMovable()
|
|
|
+ Movable* getMovable()
|
|
|
+ {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Update the animation stuff
|
|
|
+ void frameUpdate(float prevUpdateTime, float crntTime, int frame);
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// @name Movable virtuals
|
|
|
+ /// @{
|
|
|
+
|
|
|
+ /// Update boundingShapeWSpace from bone tails (not heads as well
|
|
|
+ /// cause its faster that way). The tails come from the previous frame
|
|
|
+ void movableUpdate();
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// @name Accessors
|
|
|
+ /// @{
|
|
|
+ Types<Vec3>::ConstRange getHeads() const
|
|
|
+ {
|
|
|
+ return Types<Vec3>::ConstRange(heads.begin(), heads.end());
|
|
|
+ }
|
|
|
+ Types<Vec3>::MutableRange getHeads()
|
|
|
+ {
|
|
|
+ return Types<Vec3>::MutableRange(heads.begin(), heads.end());
|
|
|
+ }
|
|
|
+
|
|
|
+ Types<Vec3>::ConstRange getTails() const
|
|
|
+ {
|
|
|
+ return Types<Vec3>::ConstRange(tails.begin(), tails.end());
|
|
|
+ }
|
|
|
+ Types<Vec3>::MutableRange getTails()
|
|
|
+ {
|
|
|
+ return Types<Vec3>::MutableRange(tails.begin(), tails.end());
|
|
|
+ }
|
|
|
+
|
|
|
+ Types<Mat3>::ConstRange getBoneRotations() const
|
|
|
+ {
|
|
|
+ return Types<Mat3>::ConstRange(boneRotations.begin(),
|
|
|
+ boneRotations.end());
|
|
|
+ }
|
|
|
+ Types<Mat3>::MutableRange getBoneRotations()
|
|
|
+ {
|
|
|
+ return Types<Mat3>::MutableRange(boneRotations.begin(),
|
|
|
+ boneRotations.end());
|
|
|
+ }
|
|
|
+
|
|
|
+ Types<Vec3>::ConstRange getBoneTranslations() const
|
|
|
+ {
|
|
|
+ return Types<Vec3>::ConstRange(boneTranslations.begin(),
|
|
|
+ boneTranslations.end());
|
|
|
+ }
|
|
|
+ Types<Vec3>::MutableRange getBoneTranslations()
|
|
|
+ {
|
|
|
+ return Types<Vec3>::MutableRange(boneTranslations.begin(),
|
|
|
+ boneTranslations.end());
|
|
|
+ }
|
|
|
+
|
|
|
+ PatchesConstRange getPatchNodes() const
|
|
|
+ {
|
|
|
+ return PatchesConstRange(patches.begin(), patches.end());
|
|
|
+ }
|
|
|
+ PatchesMutableRange getPatchNodes()
|
|
|
+ {
|
|
|
+ return PatchesMutableRange(patches.begin(), patches.end());
|
|
|
+ }
|
|
|
+
|
|
|
+ const CollisionShape*
|
|
|
+ getVisibilityCollisionShapeWorldSpace() const
|
|
|
+ {
|
|
|
+ return &visibilityShapeWSpace;
|
|
|
+ }
|
|
|
+
|
|
|
+ const Skin& getSkin() const
|
|
|
+ {
|
|
|
+ return *skin;
|
|
|
+ }
|
|
|
+
|
|
|
+ float getStep() const
|
|
|
+ {
|
|
|
+ return step;
|
|
|
+ }
|
|
|
+ float& getStep()
|
|
|
+ {
|
|
|
+ return step;
|
|
|
+ }
|
|
|
+ void setStep(const float x)
|
|
|
+ {
|
|
|
+ step = x;
|
|
|
+ }
|
|
|
+
|
|
|
+ float getFrame() const
|
|
|
+ {
|
|
|
+ return frame;
|
|
|
+ }
|
|
|
+ float& getFrame()
|
|
|
+ {
|
|
|
+ return frame;
|
|
|
+ }
|
|
|
+ void setFrame(const float x)
|
|
|
+ {
|
|
|
+ frame = x;
|
|
|
+ }
|
|
|
+
|
|
|
+ void setAnimation(const SkelAnim& anim_)
|
|
|
+ {
|
|
|
+ anim = &anim_;
|
|
|
+ }
|
|
|
+ const SkelAnim* getAnimation() const
|
|
|
+ {
|
|
|
+ return anim;
|
|
|
+ }
|
|
|
+ /// @}
|
|
|
+
|
|
|
+private:
|
|
|
+ SkinResourcePointer skin; ///< The resource
|
|
|
+ PatchesContainer patches;
|
|
|
+ Obb visibilityShapeWSpace;
|
|
|
+
|
|
|
+ /// @name Animation stuff
|
|
|
+ /// @{
|
|
|
+ float step;
|
|
|
+ float frame;
|
|
|
+ const SkelAnim* anim; ///< The active skeleton animation
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// @name Bone data
|
|
|
+ /// @{
|
|
|
+ std::vector<Vec3> heads;
|
|
|
+ std::vector<Vec3> tails;
|
|
|
+ std::vector<Mat3> boneRotations;
|
|
|
+ std::vector<Vec3> boneTranslations;
|
|
|
+ /// @}
|
|
|
+
|
|
|
+ /// Interpolate
|
|
|
+ /// @param[in] animation Animation
|
|
|
+ /// @param[in] frame Frame
|
|
|
+ /// @param[out] translations Translations vector
|
|
|
+ /// @param[out] rotations Rotations vector
|
|
|
+ static void interpolate(const SkelAnim& animation, float frame,
|
|
|
+ std::vector<Vec3>& translations, std::vector<Mat3>& rotations);
|
|
|
+
|
|
|
+ /// Calculate the global pose
|
|
|
+ static void updateBoneTransforms(const Skeleton& skel,
|
|
|
+ std::vector<Vec3>& translations, std::vector<Mat3>& rotations);
|
|
|
+
|
|
|
+ /// Deform the heads and tails
|
|
|
+ static void deformHeadsTails(const Skeleton& skeleton,
|
|
|
+ const std::vector<Vec3>& boneTranslations,
|
|
|
+ const std::vector<Mat3>& boneRotations,
|
|
|
+ std::vector<Vec3>& heads, std::vector<Vec3>& tails);
|
|
|
};
|
|
|
|
|
|
|