Skip to content

Commit 6a6c46a

Browse files
added ICPUAnimationLibrary and IGPUAnimationLibrary
1 parent 0b8c582 commit 6a6c46a

File tree

8 files changed

+348
-61
lines changed

8 files changed

+348
-61
lines changed

examples_tests/04.Keyframe/main.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,32 @@ int main()
118118
const char* jointNames[] = {"root","bendy"};
119119
skeleton = core::make_smart_refctd_ptr<asset::ICPUSkeleton>(std::move(parentIDs),std::move(defaultTransforms),&jointNames[0],&jointNames[0]+kJointCount);
120120
}
121+
core::smart_refctd_ptr<asset::ICPUAnimationLibrary> animations;
122+
{
123+
constexpr uint32_t kKeyframeCount = 16u;
124+
constexpr uint32_t kAnimationCount = 3u;
125+
{
126+
asset::SBufferBinding<asset::ICPUBuffer> keyframes = {0ull,core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(asset::ICPUAnimationLibrary::Keyframe)*kKeyframeCount)};
127+
asset::SBufferBinding<asset::ICPUBuffer> timestamps = {0ull,core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(asset::ICPUAnimationLibrary::timestamp_t)*kKeyframeCount)};
128+
asset::SBufferRange<asset::ICPUBuffer> namedAnims;
129+
namedAnims.offset = 0ull;
130+
namedAnims.size = sizeof(asset::ICPUAnimationLibrary::Animation)*kAnimationCount;
131+
namedAnims.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(namedAnims.size);
132+
animations = core::make_smart_refctd_ptr<asset::ICPUAnimationLibrary>(std::move(keyframes),std::move(timestamps),kKeyframeCount,std::move(namedAnims));
133+
}
134+
{
135+
const uint32_t animationOffsets[] = { 0u,1u,2u };
136+
const asset::ICPUAnimationLibrary::Animation anims[] = {
137+
{0u,kKeyframeCount,asset::ICPUAnimationLibrary::Animation::EIM_NEAREST},
138+
{0u,kKeyframeCount,asset::ICPUAnimationLibrary::Animation::EIM_LINEAR},
139+
{0u,kKeyframeCount,asset::ICPUAnimationLibrary::Animation::EIM_CUBIC},
140+
};
141+
for (auto i=0u; i<kAnimationCount; i++)
142+
animations->getAnimation(animationOffsets[i]) = anims[i];
143+
const char* animationNames[] = { "moveNearest","moveLinear","moveCubic" };
144+
animations->addAnimationNames(animationNames,animationNames+kAnimationCount,animationOffsets);
145+
}
146+
}
121147

122148
//
123149
core::smart_refctd_ptr<video::IGPUMeshBuffer> gpumb;

include/nbl/asset/IAnimationLibrary.h

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ template <class BufferType>
2323
class IAnimationLibrary : public virtual core::IReferenceCounted
2424
{
2525
public:
26+
using timestamp_t = uint32_t;
2627
struct alignas(8) Keyframe
2728
{
28-
Keyframe() : quat(), scale(0ull)
29+
Keyframe() : quat(), scale(0ull) // TODO: initialize scale to 1.f
2930
{
3031
translation[2] = translation[1] = translation[0] = 0.f;
3132
}
@@ -51,7 +52,7 @@ class IAnimationLibrary : public virtual core::IReferenceCounted
5152

5253
private:
5354
float translation[3];
54-
CDirQuantCacheBase::Vector8u4 quat;
55+
CQuantQuaternionCache::Vector8u4 quat;
5556
uint64_t scale;
5657
};
5758
struct alignas(8) Animation
@@ -63,6 +64,18 @@ class IAnimationLibrary : public virtual core::IReferenceCounted
6364
EIM_CUBIC=2u<<30u,
6465
EIM_MASK=3u<<30u
6566
};
67+
68+
inline Animation()
69+
{
70+
data[0] = data[1] = 0xffffffffu;
71+
}
72+
inline Animation(const uint32_t keyframeOffset, const uint32_t keyframeCount, const E_INTERPOLATION_MODE interpolation)
73+
{
74+
data[0] = keyframeOffset;
75+
assert(keyframeCount<0x4fffffffu);
76+
data[1] = keyframeCount|interpolation;
77+
}
78+
6679
inline uint32_t getKeyframeOffset() const
6780
{
6881
return data[0];
@@ -79,48 +92,62 @@ class IAnimationLibrary : public virtual core::IReferenceCounted
7992
{
8093
return data[1]&EIM_MASK;
8194
}
95+
8296
private:
8397
uint32_t data[2];
8498
};
8599

86-
inline const auto& getNameToAnimationMap() const
100+
//
101+
inline const SBufferBinding<const BufferType>& getKeyframeStorageBinding() const
87102
{
88-
return m_nameToAnimation;
103+
return reinterpret_cast<const SBufferBinding<const BufferType>*>(m_keyframeStorageBinding);
89104
}
90-
inline uint32_t getAnimationOffsetFromName(const char* animationName) const
105+
inline const SBufferBinding<const BufferType>& getTimestampStorageBinding() const
91106
{
92-
auto found = m_nameToAnimation.find(animationName);
93-
if (found != m_nameToAnimation.end())
94-
return found->second;
95-
return getAnimationCapacity();
107+
return reinterpret_cast<const SBufferBinding<const BufferType>*>(m_timestampStorageBinding);
108+
}
109+
110+
//
111+
inline const SBufferRange<const BufferType>& getAnimationStorageRange() const
112+
{
113+
return reinterpret_cast<const SBufferRange<const BufferType>*>(m_animationStorageRange);
96114
}
97115

116+
//
98117
inline uint32_t getAnimationCapacity() const
99118
{
100-
return m_animationStorageRange.size()/sizeof(Animation);
119+
return m_animationStorageRange.size() / sizeof(Animation);
101120
}
102121

103-
inline const SBufferRange<const BufferType>& getKeyframeStorageRange() const
122+
inline uint32_t getAnimationOffsetFromName(const char* animationName) const
104123
{
105-
return reinterpret_cast<const SBufferRange<const BufferType>*>(m_keyframeStorageRange);
124+
auto found = m_nameToAnimation.find(animationName);
125+
if (found != m_nameToAnimation.end())
126+
return found->second;
127+
return getAnimationCapacity();
106128
}
107-
inline const SBufferRange<const BufferType>& getAnimationStorageRange() const
129+
130+
inline const auto& getNameToAnimationMap() const
108131
{
109-
return reinterpret_cast<const SBufferRange<const BufferType>*>(m_animationStorageRange);
132+
return m_nameToAnimation;
110133
}
111134

112135

113136
protected:
114-
IAnimationLibrary(SBufferRange<BufferType>&& _keyframeStorageRange, SBufferRange<BufferType>&& _animationStorageRange) :
115-
m_stringPool(), m_nameToAnimation(StringComparator(&m_stringPool)), m_keyframeStorageRange(std::move(_keyframeStorageRange)),
116-
m_animationStorageRange(std::move(_animationStorageRange))
137+
IAnimationLibrary(SBufferBinding<BufferType>&& _keyframeStorageBinding, SBufferBinding<BufferType>&& _timestampStorageBinding, uint32_t _keyframeCount, SBufferRange<BufferType>&& _animationStorageRange) :
138+
m_stringPool(), m_nameToAnimation(StringComparator(&m_stringPool)), m_keyframeStorageBinding(std::move(_keyframeStorageRange)), m_timestampStorageBinding(std::move(_timestampStorageBinding)),
139+
m_animationStorageRange(std::move(_animationStorageRange)), m_keyframeCount(_keyframeCount)
117140
{
118-
assert(m_keyframeStorageRange.isValid() && (m_keyframeStorageRange.offset%sizeof(Keyframe)==0u) && m_keyframeStorageRange.size>=sizeof(Keyframe));
119-
assert(m_animationStorageRange.isValid() && (m_animationStorageRange.offset%sizeof(Animation)==0u) && m_animationStorageRange.size>=sizeof(Animation));
141+
assert(m_keyframeStorageBinding.buffer && (m_keyframeStorageBinding.offset%sizeof(Keyframe)==0u) && m_keyframeStorageBinding.offset+sizeof(Keyframe)*m_keyframeCount<=m_keyframeStorageBinding.buffer->getSize());
142+
assert(m_timestampStorageBinding.buffer && (m_timestampStorageBinding.offset%sizeof(Keyframe)==0u) && m_timestampStorageBinding.offset+sizeof(Keyframe)*m_keyframeCount<=m_timestampStorageBinding.buffer->getSize());
143+
144+
if (!m_animationStorageRange.isValid())
145+
return;
146+
assert((m_animationStorageRange.offset%sizeof(Animation)==0u) && m_animationStorageRange.size>=sizeof(Animation));
120147
}
121148
virtual ~IAnimationLibrary()
122149
{
123-
m_nameToAnimation.clear();
150+
clearAnimationNames();
124151
}
125152

126153
template <typename>
@@ -167,7 +194,7 @@ class IAnimationLibrary : public virtual core::IReferenceCounted
167194
}
168195
}
169196
//
170-
inline clearAnimationNames()
197+
inline void clearAnimationNames()
171198
{
172199
m_nameToAnimation.clear();
173200
m_stringPool.clear();
@@ -188,7 +215,9 @@ class IAnimationLibrary : public virtual core::IReferenceCounted
188215
core::vector<char> m_stringPool;
189216
core::map<uint32_t,uint32_t,StringComparator> m_nameToAnimation;
190217

191-
SBufferRange<BufferType> m_keyframeStorageRange,m_animationStorageRange;
218+
SBufferBinding<BufferType> m_keyframeStorageBinding,m_timestampStorageBinding;
219+
SBufferRange<BufferType> m_animationStorageRange;
220+
uint32_t m_keyframeCount;
192221
};
193222

194223
} // end namespace asset
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#ifndef __NBL_ASSET_I_CPU_ANIMATION_LIBRARY_H_INCLUDED__
6+
#define __NBL_ASSET_I_CPU_ANIMATION_LIBRARY_H_INCLUDED__
7+
8+
#include "nbl/asset/IAnimationLibrary.h"
9+
#include "nbl/asset/ICPUBuffer.h"
10+
11+
namespace nbl
12+
{
13+
namespace asset
14+
{
15+
16+
class ICPUAnimationLibrary final : public IAnimationLibrary<ICPUBuffer>, /*TODO: public BlobSerializable, */public IAsset
17+
{
18+
public:
19+
using base_t = IAnimationLibrary<ICPUBuffer>;
20+
21+
template<typename... Args>
22+
inline ICPUAnimationLibrary(Args&&... args) : base_t(std::forward<Args>(args)...) {}
23+
24+
//
25+
inline const SBufferBinding<ICPUBuffer>& getKeyframeStorageBinding() const
26+
{
27+
return m_keyframeStorageBinding;
28+
}
29+
inline const SBufferBinding<ICPUBuffer>& getTimestampStorageBinding() const
30+
{
31+
return m_timestampStorageBinding;
32+
}
33+
34+
//
35+
inline const SBufferRange<ICPUBuffer>& getAnimationStorageRange() const
36+
{
37+
return m_animationStorageRange;
38+
}
39+
40+
//!
41+
inline const Keyframe& getKeyframe(uint32_t keyframeOffset) const
42+
{
43+
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(m_keyframeStorageBinding.buffer->getPointer());
44+
return reinterpret_cast<const Keyframe*>(ptr+m_keyframeStorageBinding.offset)[keyframeOffset];
45+
}
46+
inline Keyframe& getKeyframe(uint32_t keyframeOffset)
47+
{
48+
assert(!isImmutable_debug());
49+
return const_cast<Keyframe&>(const_cast<const ICPUAnimationLibrary*>(this)->getKeyframe(keyframeOffset));
50+
}
51+
//!
52+
inline const timestamp_t& getTimestamp(uint32_t keyframeOffset) const
53+
{
54+
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(m_timestampStorageBinding.buffer->getPointer());
55+
return reinterpret_cast<const timestamp_t*>(ptr+m_timestampStorageBinding.offset)[keyframeOffset];
56+
}
57+
inline timestamp_t& getTimestamp(uint32_t keyframeOffset)
58+
{
59+
assert(!isImmutable_debug());
60+
return const_cast<timestamp_t&>(const_cast<const ICPUAnimationLibrary*>(this)->getTimestamp(keyframeOffset));
61+
}
62+
63+
//!
64+
inline const Animation& getAnimation(uint32_t animationOffset) const
65+
{
66+
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(m_animationStorageRange.buffer->getPointer());
67+
return reinterpret_cast<const Animation*>(ptr+m_animationStorageRange.offset)[animationOffset];
68+
}
69+
inline Animation& getAnimation(uint32_t animationOffset)
70+
{
71+
assert(!isImmutable_debug());
72+
return const_cast<Animation&>(const_cast<const ICPUAnimationLibrary*>(this)->getAnimation(animationOffset));
73+
}
74+
75+
//!
76+
template<typename NameIterator, typename OffsetIterator>
77+
inline void addAnimationNames(NameIterator nameBegin, NameIterator nameEnd, OffsetIterator offsetBegin)
78+
{
79+
base_t::addAnimationNames(nameBegin,nameEnd,offsetBegin);
80+
}
81+
inline void clearAnimationNames()
82+
{
83+
base_t::clearAnimationNames();
84+
}
85+
86+
//! Serializes animation library to blob for *.nbl file format.
87+
/** @param _stackPtr Optional pointer to stack memory to write blob on. If _stackPtr==NULL, sufficient amount of memory will be allocated.
88+
@param _stackSize Size of stack memory pointed by _stackPtr.
89+
@returns Pointer to memory on which blob was written.
90+
* TODO
91+
virtual void* serializeToBlob(void* _stackPtr = NULL, const size_t& _stackSize = 0) const override
92+
{
93+
return CorrespondingBlobTypeFor<ICPUAnimationLibrary>::type::createAndTryOnStack(this, _stackPtr, _stackSize);
94+
}
95+
*/
96+
97+
core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override
98+
{
99+
SBufferBinding<ICPUBuffer> _keyframeStorageBinding = {m_keyframeStorageBinding.offset,_depth>0u ? core::smart_refctd_ptr_static_cast<ICPUBuffer>(m_keyframeStorageBinding.buffer->clone(_depth-1u)):m_keyframeStorageBinding.buffer};
100+
SBufferBinding<ICPUBuffer> _timestampStorageBinding = {m_timestampStorageBinding.offset,_depth>0u ? core::smart_refctd_ptr_static_cast<ICPUBuffer>(m_timestampStorageBinding.buffer->clone(_depth-1u)):m_timestampStorageBinding.buffer};
101+
102+
SBufferRange<ICPUBuffer> _animationStorageRange = {m_animationStorageRange.offset,m_animationStorageRange.size,_depth>0u&&m_animationStorageRange.buffer ? core::smart_refctd_ptr_static_cast<ICPUBuffer>(m_animationStorageRange.buffer->clone(_depth-1u)):m_animationStorageRange.buffer};
103+
104+
auto cp = core::make_smart_refctd_ptr<ICPUAnimationLibrary>(std::move(_keyframeStorageBinding),std::move(_timestampStorageBinding),m_keyframeCount,std::move(_animationStorageRange));
105+
clone_common(cp.get());
106+
cp->setAnimationNames(this);
107+
108+
return cp;
109+
}
110+
111+
virtual void convertToDummyObject(uint32_t referenceLevelsBelowToConvert=0u) override
112+
{
113+
convertToDummyObject_common(referenceLevelsBelowToConvert);
114+
115+
if (referenceLevelsBelowToConvert)
116+
{
117+
m_keyframeStorageBinding.buffer->convertToDummyObject(referenceLevelsBelowToConvert-1u);
118+
m_timestampStorageBinding.buffer->convertToDummyObject(referenceLevelsBelowToConvert-1u);
119+
m_animationStorageRange.buffer->convertToDummyObject(referenceLevelsBelowToConvert-1u);
120+
}
121+
}
122+
123+
_NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_ANIMATION_LIBRARY;
124+
inline E_TYPE getAssetType() const override { return AssetType; }
125+
126+
virtual size_t conservativeSizeEstimate() const override
127+
{
128+
size_t estimate = sizeof(SBufferBinding<ICPUBuffer>)*2ull;
129+
estimate += sizeof(SBufferRange<ICPUBuffer>);
130+
estimate += sizeof(uint32_t);
131+
estimate += m_stringPoolSize;
132+
estimate += m_nameToAnimation.size()*sizeof(std::pair<uint32_t,uint32_t>);
133+
// do we add other things to the size estimate?
134+
return estimate;
135+
}
136+
137+
bool canBeRestoredFrom(const IAsset* _other) const override
138+
{
139+
auto other = static_cast<const ICPUAnimationLibrary*>(_other);
140+
if (m_keyframeCount != other->m_keyframeCount)
141+
return false;
142+
143+
if (m_keyframeStorageBinding.offset != other->m_keyframeStorageBinding.offset)
144+
return false;
145+
if (m_keyframeStorageBinding.buffer->canBeRestoredFrom(other->m_keyframeStorageBinding.buffer.get()))
146+
return false;
147+
if (m_timestampStorageBinding.offset != other->m_timestampStorageBinding.offset)
148+
return false;
149+
if (m_timestampStorageBinding.buffer->canBeRestoredFrom(other->m_timestampStorageBinding.buffer.get()))
150+
return false;
151+
152+
if (m_animationStorageRange.offset != other->m_animationStorageRange.offset)
153+
return false;
154+
if (m_animationStorageRange.size != other->m_animationStorageRange.size)
155+
return false;
156+
if ((!m_animationStorageRange.buffer) != (!other->m_animationStorageRange.buffer))
157+
return false;
158+
if (m_animationStorageRange.buffer && !m_animationStorageRange.buffer->canBeRestoredFrom(other->m_animationStorageRange.buffer.get()))
159+
return false;
160+
161+
return true;
162+
}
163+
164+
protected:
165+
void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) override
166+
{
167+
auto* other = static_cast<ICPUSkeleton*>(_other);
168+
169+
if (_levelsBelow)
170+
{
171+
--_levelsBelow;
172+
173+
if (m_keyframeStorageBinding.buffer)
174+
restoreFromDummy_impl_call(m_keyframeStorageBinding.buffer.get(),other->m_keyframeStorageBinding.buffer.get(),_levelsBelow);
175+
if (m_timestampStorageBinding.buffer)
176+
restoreFromDummy_impl_call(m_timestampStorageBinding.buffer.get(),other->m_timestampStorageBinding.buffer.get(),_levelsBelow);
177+
178+
if (m_animationStorageRange.buffer)
179+
restoreFromDummy_impl_call(m_animationStorageRange.buffer.get(),other->m_animationStorageRange.buffer.get(),_levelsBelow);
180+
}
181+
}
182+
183+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
184+
{
185+
--_levelsBelow;
186+
if (m_keyframeStorageBinding.buffer && m_keyframeStorageBinding.buffer->isAnyDependencyDummy(_levelsBelow))
187+
return true;
188+
if (m_timestampStorageBinding.buffer && m_timestampStorageBinding.buffer->isAnyDependencyDummy(_levelsBelow))
189+
return true;
190+
191+
return m_animationStorageRange.buffer && m_animationStorageRange.buffer->isAnyDependencyDummy(_levelsBelow);
192+
}
193+
};
194+
195+
}
196+
}
197+
198+
#endif

include/nbl/asset/asset.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
// pipelines
5151

5252
// skinning
53+
#include "nbl/asset/ICPUAnimationLibrary.h"
5354
#include "nbl/asset/ICPUSkeleton.h"
5455

5556
// meshes

0 commit comments

Comments
 (0)