Skip to content

Commit 4ff5021

Browse files
Add Skeleton to MeshBuffer
1 parent d5e0587 commit 4ff5021

File tree

8 files changed

+138
-83
lines changed

8 files changed

+138
-83
lines changed

examples_tests/04.Keyframe/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ int main()
111111
}
112112
const char* jointNames[] = {"root","bendy"};
113113
auto skeleton = core::make_smart_refctd_ptr<asset::ICPUSkeleton>(std::move(parentIDs),std::move(inverseBindPoses),&jointNames[0],&jointNames[0]+kJointCount);
114-
//auto gpuSkeleton = driver->getGPUObjectsFromAssets<asset::ICPUSkeleton>(&skeleton,&skeleton+1u); // TODO: Test conversion path, linker error
114+
auto gpuSkeleton = driver->getGPUObjectsFromAssets<asset::ICPUSkeleton>(&skeleton,&skeleton+1u)->begin()[0];
115115

116116
//
117117
core::smart_refctd_ptr<video::IGPUMeshBuffer> mb;
@@ -182,7 +182,7 @@ int main()
182182

183183
asset::SBufferBinding<video::IGPUBuffer> bindings[video::IGPUMeshBuffer::MAX_ATTR_BUF_BINDING_COUNT];
184184
bindings[0u] = {0u,driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(vertices),vertices)};
185-
mb = core::make_smart_refctd_ptr<video::IGPUMeshBuffer>(std::move(pipeline),nullptr,bindings,asset::SBufferBinding<video::IGPUBuffer>{0u,driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(indices_indexed16),indices_indexed16)});
185+
mb = core::make_smart_refctd_ptr<video::IGPUMeshBuffer>(std::move(pipeline),nullptr,std::move(gpuSkeleton),bindings,asset::SBufferBinding<video::IGPUBuffer>{0u,driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(indices_indexed16),indices_indexed16)});
186186
{
187187
mb->setIndexType(asset::EIT_16BIT);
188188
mb->setIndexCount(2*3*6);

include/nbl/asset/ICPUMeshBuffer.h

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define __NBL_ASSET_I_CPU_MESH_BUFFER_H_INCLUDED__
77

88
#include "nbl/asset/IMeshBuffer.h"
9+
#include "nbl/asset/ICPUSkeleton.h"
910
#include "nbl/asset/ICPUDescriptorSet.h"
1011
#include "nbl/asset/ICPURenderpassIndependentPipeline.h"
1112
#include "nbl/asset/bawformat/blobs/MeshBufferBlob.h"
@@ -57,29 +58,27 @@ namespace impl
5758
}
5859
}
5960

60-
class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURenderpassIndependentPipeline>, public BlobSerializable, public IAsset
61+
class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer,ICPUDescriptorSet,ICPURenderpassIndependentPipeline,ICPUSkeleton>, public BlobSerializable, public IAsset
6162
{
62-
using base_t = IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURenderpassIndependentPipeline>;
63+
using base_t = IMeshBuffer<ICPUBuffer,ICPUDescriptorSet,ICPURenderpassIndependentPipeline,ICPUSkeleton>;
6364
// knowing the position attribute ID is important for AABB computations etc.
6465
uint32_t posAttrId : 5;
6566
uint32_t normalAttrId : 5;
6667
// by having one attribute only, we limit the number of bones per vertex to 4
6768
uint32_t jointIDAttrId : 5;
6869
uint32_t jointWeightAttrId : 5;
69-
uint32_t maxJointsPerVx : 3;
7070

7171
protected:
7272
virtual ~ICPUMeshBuffer() = default;
7373

7474
public:
7575
//! Default constructor (initializes pipeline, desc set and buffer bindings to nullptr)
76-
ICPUMeshBuffer() : base_t(nullptr, nullptr, nullptr, SBufferBinding<ICPUBuffer>{})
76+
ICPUMeshBuffer() : base_t(nullptr, nullptr, nullptr, nullptr, SBufferBinding<ICPUBuffer>{})
7777
{
7878
posAttrId = 0u;
7979
normalAttrId = MAX_VERTEX_ATTRIB_COUNT;
8080
jointIDAttrId = MAX_VERTEX_ATTRIB_COUNT;
8181
jointWeightAttrId = MAX_VERTEX_ATTRIB_COUNT;
82-
maxJointsPerVx = 0u;
8382
}
8483
using base_t::base_t;
8584

@@ -94,6 +93,8 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
9493
clone_common(cp.get());
9594
cp->m_descriptorSet = (_depth > 0u && m_descriptorSet) ? core::smart_refctd_ptr_static_cast<ICPUDescriptorSet>(m_descriptorSet->clone(_depth - 1u)) : m_descriptorSet;
9695
cp->m_pipeline = (_depth > 0u && m_pipeline) ? core::smart_refctd_ptr_static_cast<ICPURenderpassIndependentPipeline>(m_pipeline->clone(_depth - 1u)) : m_pipeline;
96+
cp->m_skeleton = (_depth > 0u && m_skeleton) ? core::smart_refctd_ptr_static_cast<ICPUSkeleton>(m_skeleton->clone(_depth - 1u)) : m_skeleton;
97+
cp->maxJointsPerVx = maxJointsPerVx;
9798

9899
cp->boundingBox = boundingBox;
99100
cp->indexType = indexType;
@@ -107,7 +108,6 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
107108
cp->normalAttrId = normalAttrId;
108109
cp->jointIDAttrId = jointIDAttrId;
109110
cp->jointWeightAttrId = jointWeightAttrId;
110-
cp->maxJointsPerVx = maxJointsPerVx;
111111

112112
cp->m_indexBufferBinding.offset = m_indexBufferBinding.offset;
113113
cp->m_indexBufferBinding.buffer = (_depth > 0u && m_indexBufferBinding.buffer) ?
@@ -136,6 +136,8 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
136136
m_vertexBufferBindings[i].buffer->convertToDummyObject(referenceLevelsBelowToConvert);
137137
if (m_indexBufferBinding.buffer)
138138
m_indexBufferBinding.buffer->convertToDummyObject(referenceLevelsBelowToConvert);
139+
if (m_skeleton)
140+
m_skeleton->convertToDummyObject(referenceLevelsBelowToConvert);
139141
if (m_descriptorSet)
140142
m_descriptorSet->convertToDummyObject(referenceLevelsBelowToConvert);
141143
if (m_pipeline)
@@ -194,13 +196,30 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
194196
m_indexBufferBinding = std::move(bufferBinding);
195197
}
196198

199+
//!
200+
inline const ICPUSkeleton* getSkeleton() const
201+
{
202+
return base_t::getSkeleton();
203+
}
204+
inline ICPUSkeleton* getSkeleton()
205+
{
206+
assert(!isImmutable_debug());
207+
return m_skeleton.get();
208+
}
209+
inline void setSkeleton(core::smart_refctd_ptr<ICPUSkeleton>&& skeleton)
210+
{
211+
assert(!isImmutable_debug());
212+
m_skeleton = std::move(skeleton);
213+
}
214+
197215
//!
198216
inline const ICPUDescriptorSet* getAttachedDescriptorSet() const
199217
{
200218
return base_t::getAttachedDescriptorSet();
201219
}
202220
inline ICPUDescriptorSet* getAttachedDescriptorSet()
203221
{
222+
//assert(!isImmutable_debug()); // TODO? @Crisspl?
204223
return m_descriptorSet.get();
205224
}
206225
inline void setAttachedDescriptorSet(core::smart_refctd_ptr<ICPUDescriptorSet>&& descriptorSet)
@@ -299,9 +318,6 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
299318
return core::min(safelyGetAttributeFormatChannelCount(jointIDAttrId),safelyGetAttributeFormatChannelCount(jointWeightAttrId)+1u);
300319
}
301320

302-
//! Returns max joint influences
303-
inline uint32_t getMaxJointsPerVertex() const { return maxJointsPerVx; }
304-
305321
//! Sets max joint influences
306322
inline uint32_t setMaxJointsPerVertex(const uint32_t _maxJointsPerVx)
307323
{
@@ -310,7 +326,7 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
310326
}
311327

312328
//! Tells us if the mesh is skinned
313-
inline bool isSkinned() const { return deduceMaxJointsPerVertex()>0u && getMaxJointsPerVertex()>0u; }
329+
inline bool isSkinned() const override { return base_t::isSkinned() && deduceMaxJointsPerVertex()>0u; }
314330

315331
//! Get access to Indices.
316332
/** \return Pointer to indices array. */
@@ -636,15 +652,16 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
636652
return false;
637653
}
638654

655+
if ((!m_skeleton) != (!other->m_skeleton))
656+
return false;
657+
if (m_skeleton && !m_skeleton->canBeRestoredFrom(other->m_skeleton.get()))
658+
return false;
659+
639660
if ((!m_descriptorSet) != (!other->m_descriptorSet))
640661
return false;
641662
if (m_descriptorSet && !m_descriptorSet->canBeRestoredFrom(other->m_descriptorSet.get()))
642663
return false;
643664

644-
/*
645-
if ((!m_pipeline || !other->m_pipeline) && m_pipeline != other->m_pipeline)
646-
return false;
647-
*/
648665
// pipeline is not optional
649666
if (!m_pipeline->canBeRestoredFrom(other->m_pipeline.get()))
650667
return false;
@@ -666,6 +683,9 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
666683
if (m_descriptorSet)
667684
restoreFromDummy_impl_call(m_descriptorSet.get(), other->m_descriptorSet.get(), _levelsBelow);
668685

686+
if (m_skeleton)
687+
restoreFromDummy_impl_call(m_skeleton.get(), other->m_skeleton.get(), _levelsBelow);
688+
669689
for (uint32_t i = 0u; i < MAX_ATTR_BUF_BINDING_COUNT; ++i)
670690
if (m_vertexBufferBindings[i].buffer)
671691
restoreFromDummy_impl_call(m_vertexBufferBindings[i].buffer.get(), other->m_vertexBufferBindings[i].buffer.get(), _levelsBelow);
@@ -681,6 +701,8 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
681701
return true;
682702
if (m_descriptorSet && m_descriptorSet->isAnyDependencyDummy(_levelsBelow))
683703
return true;
704+
if (m_skeleton && m_skeleton->isAnyDependencyDummy(_levelsBelow))
705+
return true;
684706

685707
for (uint32_t i = 0u; i < MAX_ATTR_BUF_BINDING_COUNT; ++i)
686708
if (m_vertexBufferBindings[i].buffer && m_vertexBufferBindings[i].buffer->isAnyDependencyDummy(_levelsBelow))

include/nbl/asset/IMeshBuffer.h

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ namespace asset
1414
{
1515

1616
//! Where to move it so its not floating around scopeless?
17-
enum E_INDEX_TYPE
17+
enum E_INDEX_TYPE : uint32_t
1818
{
1919
EIT_16BIT = 0,
2020
EIT_32BIT,
2121
EIT_UNKNOWN
2222
};
2323

24-
template <class BufferType, class DescSetType, class PipelineType>
24+
template <class BufferType, class DescSetType, class PipelineType, class SkeletonType>
2525
class IMeshBuffer : public virtual core::IReferenceCounted
2626
{
2727
public:
@@ -33,32 +33,44 @@ class IMeshBuffer : public virtual core::IReferenceCounted
3333
protected:
3434
virtual ~IMeshBuffer() = default;
3535

36-
core::aabbox3df boundingBox;
36+
alignas(32) core::aabbox3df boundingBox;
3737

3838
SBufferBinding<BufferType> m_vertexBufferBindings[MAX_ATTR_BUF_BINDING_COUNT];
3939
SBufferBinding<BufferType> m_indexBufferBinding;
4040

41+
//! Skeleton
42+
core::smart_refctd_ptr<SkeletonType> m_skeleton;
43+
4144
//! Descriptor set which goes to set=3
4245
core::smart_refctd_ptr<DescSetType> m_descriptorSet;
46+
47+
alignas(64) uint8_t m_pushConstantsData[MAX_PUSH_CONSTANT_BYTESIZE]{};//by putting m_pushConstantsData here, alignas(64) takes no extra place
48+
49+
//! Pipeline for drawing
4350
core::smart_refctd_ptr<PipelineType> m_pipeline;
4451

52+
uint32_t maxJointsPerVx;
4553
//indices
4654
E_INDEX_TYPE indexType;
4755
int32_t baseVertex;
48-
alignas(64) uint8_t m_pushConstantsData[MAX_PUSH_CONSTANT_BYTESIZE]{};//by putting m_pushConstantsData here, alignas(64) takes no extra place
49-
uint64_t indexCount;
50-
//
51-
size_t instanceCount;
56+
uint32_t indexCount;
57+
// instances
58+
uint32_t instanceCount;
5259
uint32_t baseInstance;
5360

5461
public:
5562
//! Constructor.
56-
IMeshBuffer(core::smart_refctd_ptr<PipelineType>&& _pipeline, core::smart_refctd_ptr<DescSetType>&& _ds,
63+
IMeshBuffer(core::smart_refctd_ptr<PipelineType>&& _pipeline,
64+
core::smart_refctd_ptr<DescSetType>&& _ds,
65+
core::smart_refctd_ptr<SkeletonType>&& _skeleton,
5766
SBufferBinding<BufferType> _vtxBindings[MAX_ATTR_BUF_BINDING_COUNT],
5867
SBufferBinding<BufferType>&& _indexBinding
59-
) : boundingBox(), m_indexBufferBinding(std::move(_indexBinding)), m_descriptorSet(std::move(_ds)), m_pipeline(std::move(_pipeline)),
60-
indexType(EIT_UNKNOWN), baseVertex(0), indexCount(0u),
61-
instanceCount(1ull), baseInstance(0u)
68+
) : boundingBox(), m_indexBufferBinding(std::move(_indexBinding)),
69+
m_skeleton(),
70+
m_descriptorSet(std::move(_ds)), m_pipeline(std::move(_pipeline)),
71+
maxJointsPerVx(0u),
72+
indexType(EIT_UNKNOWN), baseVertex(0), indexCount(0u),
73+
instanceCount(1u), baseInstance(0u)
6274
{
6375
if (_vtxBindings)
6476
std::copy(_vtxBindings, _vtxBindings+MAX_ATTR_BUF_BINDING_COUNT, m_vertexBufferBindings);
@@ -136,48 +148,58 @@ class IMeshBuffer : public virtual core::IReferenceCounted
136148
{
137149
return reinterpret_cast<const SBufferBinding<const BufferType>&>(m_indexBufferBinding);
138150
}
139-
inline const PipelineType* getPipeline() const
151+
152+
//!
153+
inline const SkeletonType* getSkeleton() const
140154
{
141-
return m_pipeline.get();
155+
return m_skeleton.get();
142156
}
157+
158+
//! Returns max joint influences
159+
inline auto getMaxJointsPerVertex() const { return maxJointsPerVx; }
160+
161+
//!
162+
virtual inline bool isSkinned() const
163+
{
164+
return m_skeleton.get() && maxJointsPerVx>0u;
165+
}
166+
167+
//!
143168
inline const DescSetType* getAttachedDescriptorSet() const
144169
{
145170
return m_descriptorSet.get();
146171
}
147172

173+
//!
174+
inline const PipelineType* getPipeline() const
175+
{
176+
return m_pipeline.get();
177+
}
178+
148179
//! Get type of index data which is stored in this meshbuffer.
149180
/** \return Index type of this buffer. */
150-
inline const E_INDEX_TYPE& getIndexType() const {return indexType;}
151-
inline void setIndexType(const E_INDEX_TYPE& type)
181+
inline E_INDEX_TYPE getIndexType() const {return indexType;}
182+
inline void setIndexType(const E_INDEX_TYPE type)
152183
{
153184
indexType = type;
154185
}
155186

156187
//! Get amount of indices in this meshbuffer.
157188
/** \return Number of indices in this buffer. */
158-
inline const uint64_t& getIndexCount() const {return indexCount;}
189+
inline auto getIndexCount() const {return indexCount;}
159190
//! It sets amount of indices - value that is being passed to glDrawArrays as vertices amount or to glDrawElements as index amount.
160191
/** @returns Whether set amount exceeds mapped buffer's size. Regardless of result the amount is set. */
161-
inline bool setIndexCount(const uint64_t &newIndexCount)
192+
inline bool setIndexCount(const uint32_t newIndexCount)
162193
{
163-
/*
164-
#ifdef _NBL_DEBUG
165-
if (size<0x7fffffffffffffffuLL&&ixbuf&&(ixbuf->getSize()>size+offset))
166-
{
167-
os::Printer::log("MeshBuffer map vertex buffer overflow!\n",ELL_ERROR);
168-
return;
169-
}
170-
#endif // _NBL_DEBUG
171-
*/
172194
indexCount = newIndexCount;
173195
if (m_indexBufferBinding.buffer)
174196
{
175197
switch (indexType)
176198
{
177199
case EIT_16BIT:
178-
return indexCount*2+m_indexBufferBinding.offset < m_indexBufferBinding.buffer->getSize();
200+
return indexCount*sizeof(uint16_t)+m_indexBufferBinding.offset < m_indexBufferBinding.buffer->getSize();
179201
case EIT_32BIT:
180-
return indexCount*4+m_indexBufferBinding.offset < m_indexBufferBinding.buffer->getSize();
202+
return indexCount*sizeof(uint32_t)+m_indexBufferBinding.offset < m_indexBufferBinding.buffer->getSize();
181203
default:
182204
return false;
183205
}
@@ -188,21 +210,21 @@ class IMeshBuffer : public virtual core::IReferenceCounted
188210

189211
//! Accesses base vertex number.
190212
/** @returns base vertex number. */
191-
inline const int32_t& getBaseVertex() const {return baseVertex;}
213+
inline int32_t getBaseVertex() const {return baseVertex;}
192214
//! Sets base vertex.
193-
inline void setBaseVertex(const int32_t& baseVx)
215+
inline void setBaseVertex(const int32_t baseVx)
194216
{
195217
baseVertex = baseVx;
196218
}
197219

198-
inline size_t getInstanceCount() const {return instanceCount;}
199-
inline void setInstanceCount(const size_t& count)
220+
inline uint32_t getInstanceCount() const {return instanceCount;}
221+
inline void setInstanceCount(const uint32_t count)
200222
{
201223
instanceCount = count;
202224
}
203225

204226
inline uint32_t getBaseInstance() const {return baseInstance;}
205-
inline void setBaseInstance(const uint32_t& base)
227+
inline void setBaseInstance(const uint32_t base)
206228
{
207229
baseInstance = base;
208230
}

0 commit comments

Comments
 (0)