Skip to content

Commit

Permalink
[incremental commit] for review
Browse files Browse the repository at this point in the history
  • Loading branch information
bartleyryan committed Mar 22, 2016
1 parent e5875a8 commit 935b039
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 108 deletions.
8 changes: 4 additions & 4 deletions samples/Test/src/TestApp.cpp
Expand Up @@ -26,7 +26,7 @@ class TestApp : public App {

std::shared_ptr<BoxAnimated> mBoxAnimated;
SkeletonRef mSkeleton;
SkeletonAnimRef mSkeletonAnim;
Skeleton::AnimRef mSkeletonAnim;

gl::BatchRef mBatch;
CameraPersp mCam;
Expand Down Expand Up @@ -56,8 +56,8 @@ void TestApp::setup()
mSkeleton = skin.createSkeleton();
const auto &animations = file->getAnimations();
std::vector<Clip<Transform>> skeletonAnims;
skeletonAnims.reserve( mSkeleton->jointArray.size() );
for( auto &boneName : mSkeleton->jointNames ) {
skeletonAnims.reserve( mSkeleton->getNumJoints() );
for( auto &boneName : mSkeleton->getJointNames() ) {
auto found = std::find_if( animations.begin(), animations.end(),
[boneName]( const std::pair<std::string, gltf::Animation> &animation ){
return animation.second.target == boneName;
Expand All @@ -67,7 +67,7 @@ void TestApp::setup()
skeletonAnims.emplace_back( gltf::Animation::createTransformClip( params ) );
}
}
mSkeletonAnim.reset( new SkeletonAnim( mSkeleton, move( skeletonAnims ) ) );
mSkeletonAnim.reset( new Skeleton::Anim( move( skeletonAnims ) ) );
auto mesh = gltf::MeshLoader( file, &file->getMeshInfo( "Cylinder-mesh" ) );
mTrimesh = ci::TriMesh::create( mesh, TriMesh::Format().boneIndex().boneWeight().positions().normals() );
mDrawable = ci::TriMesh::create( *mTrimesh, TriMesh::Format().positions().colors( 3 ) );
Expand Down
70 changes: 1 addition & 69 deletions src/Skeleton.cpp
Expand Up @@ -48,72 +48,4 @@ const std::string* Skeleton::getJointName( uint8_t nameId ) const
{
CI_ASSERT( nameId < mJointNames.size() );
return &mJointNames[nameId];
}

void SkeletonAnim::get( double time, std::vector<ci::mat4> &offsetMatrices ) const
{
offsetMatrices.resize( numJoints );
// get transforms from animations
std::vector<Transform> localTransforms;
getPreInverse( time, localTransforms );

std::vector<ci::mat4> globalStack;
calcGlobalStack( localTransforms, globalStack );

calcMatrixPalette( globalStack, offsetMatrices);
}

void SkeletonAnim::getLooped( double time, std::vector<ci::mat4> &offsetMatrices ) const
{
offsetMatrices.resize( numJoints );
// get transforms from animations
std::vector<Transform> localTransforms;
getLoopedPreInverse( time, localTransforms );

std::vector<ci::mat4> globalStack( numJoints );
calcGlobalStack( localTransforms, globalStack );

calcMatrixPalette( globalStack, offsetMatrices);
}

void SkeletonAnim::calcGlobalStack( const std::vector<Transform> &preInverseTransforms,
std::vector<ci::mat4> &globalCache ) const
{
auto &joints = mSkeleton->getJoints();
// Derive root
globalCache[0] = preInverseTransforms[0].getTRS();
// Derive children
for( int i = 1; i < numJoints; i++ ) {
globalCache[i] = globalCache[joints[i].getParentId()] * preInverseTransforms[i].getTRS();
}
}

void SkeletonAnim::calcMatrixPalette( const std::vector<ci::mat4> &globalCache,
std::vector<ci::mat4> &offsetMatrices ) const
{
auto &joints = mSkeleton->getJoints();
// Derive root
offsetMatrices[0] = joints[0].getInverseBindMatrix() * globalCache[0];
// Derive children
for( int i = 1; i < numJoints; i++ ) {
offsetMatrices[i] = joints[i].getInverseBindMatrix() * globalCache[i];
}
}

void SkeletonAnim::getPreInverse( double time, std::vector<Transform> &preInverseBakedTransforms ) const
{
preInverseBakedTransforms.resize( numJoints );
int i = 0;
for( auto & jointClip : jointClips ) {
preInverseBakedTransforms[i++] = jointClip.get( time );
}
}

void SkeletonAnim::getLoopedPreInverse( double time, std::vector<Transform> &preInverseBakedTransforms ) const
{
preInverseBakedTransforms.resize( numJoints );
int i = 0;
for( auto &jointClip : jointClips ) {
preInverseBakedTransforms[i++] = jointClip.getLooped( time );
}
}
}
98 changes: 63 additions & 35 deletions src/Skeleton.h
Expand Up @@ -46,26 +46,29 @@ class Skeleton {
void calcMatrixPalette( std::vector<ci::mat4> &offsetMatrices );
void calcGlobalStack();

const std::vector<Transform>& getLocalPoses() const { return mLocalPoseTransforms; }
std::vector<Transform>& getLocalPoses() { return mLocalPoseTransforms; }
const std::vector<ci::mat4>& getGlobalMatrices() const { return mGlobalPose; }
std::vector<ci::mat4>& getGlobalMatrices() { return mGlobalPose; }
const std::vector<Transform>& getLocalJointTransforms() const { return mLocalJointTransforms; }
std::vector<Transform>& getLocalJointTransforms() { return mLocalJointTransforms; }
const std::vector<ci::mat4>& getGlobalJointMatrices() const { return mGlobalJointMatrices; }
std::vector<ci::mat4>& getGlobalJointMatrices() { return mGlobalJointMatrices; }
bool needsGlobalCache() const { return mNeedsGlobalCache; }
void setNeedsGlobalCache( bool needsCache ) { mNeedsGlobalCache = needsCache; }

private:
Skeleton *mSkeleton = nullptr;
std::vector<Transform> mLocalPoseTransforms;
std::vector<ci::mat4> mGlobalPose;
std::vector<Transform> mLocalJointTransforms;
std::vector<ci::mat4> mGlobalJointMatrices;
bool mNeedsGlobalCache;
};

struct Anim {
using AnimRef = std::shared_ptr<class Anim>;
class Anim {
public:
Anim( const std::vector<Clip<Transform>> &jointClips );

void get( double time, Pose &localJointTransforms ) const;
void getLooped( double time, Pose &localJointTransforms ) const;

public:
private:
std::vector<Clip<Transform>> mJointClips;
};

Expand All @@ -75,52 +78,77 @@ class Skeleton {
bool hasJoint( const std::string& name ) const;
size_t getNumJoints() { return mJointArray.size(); }

const Pose& getBindPose() const { return mBindPose; }
Pose& getBindPose() { return mBindPose; }

const std::string* getJointName( const Joint &joint ) const;
const std::string* getJointName( uint8_t nameId ) const;

const std::vector<Joint>& getJoints() const { return mJointArray; }
const std::vector<std::string>& getJointNames() const { return mJointNames; }
std::vector<Joint>& getJoints() { return mJointArray; }

ci::AxisAlignedBox calcBoundingBox() const;
const std::vector<std::string>& getJointNames() const { return mJointNames; }

void calcGlobalStack( const Pose &jointLocalTransforms,
std::vector<ci::mat4> &globalStack );
void calcMatrixPalette( const std::vector<ci::mat4> &globalCache,
std::vector<ci::mat4> &offsetMatrices ) const;

const Pose& getBindPose() { return mBindPose; }
ci::AxisAlignedBox calcBoundingBox() const;

private:
std::vector<Joint> mJointArray;
Pose mBindPose;
std::vector<std::string> mJointNames;
};

using SkeletonAnimRef = std::shared_ptr<class SkeletonAnim>;

class SkeletonAnim {
public:
SkeletonAnim( SkeletonRef skeleton, std::vector<Clip<Transform>> animations )
: mSkeleton( skeleton ), jointClips( std::move( animations ) ), numJoints( jointClips.size() ) {}

void get( double time, std::vector<ci::mat4> &offsetMatrices ) const;
void getLooped( double time, std::vector<ci::mat4> &offsetMatrices ) const;
void getPreInverse( double time, std::vector<Transform> &preInverseBakedTransforms ) const;
void getLoopedPreInverse( double time, std::vector<Transform> &preInverseBakedTransforms ) const;

void traverse( std::function<void( const Skeleton::Joint& )> visit ) const;
static void traverse( const Skeleton::Joint& node, std::function<void( const Skeleton::Joint& )> visit );
inline void Skeleton::Pose::calcMatrixPalette( std::vector<ci::mat4> &offsetMatrices )
{
if( mNeedsGlobalCache )
calcGlobalStack();

private:
void calcGlobalStack( const std::vector<Transform> &preInverseTransforms,
std::vector<ci::mat4> &globalCache ) const;
void calcMatrixPalette( const std::vector<ci::mat4> &globalCache,
std::vector<ci::mat4> &offsetMatrices ) const;
auto numJoints = mGlobalJointMatrices.size();
offsetMatrices.resize( numJoints );

SkeletonRef mSkeleton;
std::vector<Clip<Transform>> jointClips;
uint32_t numJoints;
std::function<void()> postProcessor;
};
auto &joints = mSkeleton->getJoints();
// Derive root
offsetMatrices[0] = joints[0].getInverseBindMatrix() * mGlobalJointMatrices[0];
// Derive children
for( int i = 1; i < numJoints; i++ ) {
offsetMatrices[i] = joints[i].getInverseBindMatrix() * mGlobalJointMatrices[i];
}
}

inline void Skeleton::Pose::calcGlobalStack()
{
auto numJoints = mGlobalJointMatrices.size();
auto &joints = mSkeleton->getJoints();
// Derive root
mGlobalJointMatrices[0] = mLocalJointTransforms[0].getTRS();
// Derive children
for( int i = 1; i < numJoints; i++ ) {
mGlobalJointMatrices[i] = mGlobalJointMatrices[joints[i].getParentId()] * mLocalJointTransforms[i].getTRS();
}
}

inline void Skeleton::Anim::get( double time, Skeleton::Pose &localJointTransforms ) const
{
auto &jointTransforms = localJointTransforms.getLocalJointTransforms();
CI_ASSERT( jointTransforms.size() == mJointClips.size() );
int i = 0;
for( auto & jointClip : mJointClips ) {
jointTransforms[i++] = jointClip.get( time );
}
localJointTransforms.setNeedsGlobalCache( true );
}

inline void Skeleton::Anim::getLooped( double time, Skeleton::Pose &localJointTransforms ) const
{
auto &jointTransforms = localJointTransforms.getLocalJointTransforms();
CI_ASSERT( jointTransforms.size() == mJointClips.size() );
int i = 0;
for( auto &jointClip : mJointClips ) {
jointTransforms[i++] = jointClip.getLooped( time );
}
localJointTransforms.setNeedsGlobalCache( true );
}

0 comments on commit 935b039

Please sign in to comment.