Skip to content

Commit 484c1f2

Browse files
Decouple bind poses from skeleton, provide per-joint AABB computation
1 parent 4ff5021 commit 484c1f2

File tree

9 files changed

+587
-375
lines changed

9 files changed

+587
-375
lines changed

examples_tests/04.Keyframe/main.cpp

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -90,31 +90,37 @@ int main()
9090
auto* smgr = device->getSceneManager();
9191

9292
//
93-
constexpr uint32_t kJointCount = 2u;
94-
asset::SBufferBinding<asset::ICPUBuffer> parentIDs,inverseBindPoses;
93+
asset::SBufferBinding<asset::ICPUBuffer> inverseBindPoses,jointAABBs;
94+
core::smart_refctd_ptr<asset::ICPUSkeleton> skeleton;
9595
{
96-
parentIDs.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(asset::ICPUSkeleton)*kJointCount);
96+
constexpr uint32_t kJointCount = 2u;
97+
asset::SBufferBinding<asset::ICPUBuffer> parentIDs,defaultTransforms,inverseBindPoses,jointAABBs;
9798
{
98-
asset::ICPUSkeleton::joint_id_t parentJointIDs[] = { asset::ICPUSkeleton::invalid_joint_id,0u };
99-
memcpy(parentIDs.buffer->getPointer(),parentJointIDs,sizeof(parentJointIDs));
100-
}
101-
inverseBindPoses.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(matrix3x4SIMD)*kJointCount);
102-
{
103-
auto* invBindPoses = reinterpret_cast<matrix3x4SIMD*>(inverseBindPoses.buffer->getPointer());
104-
for (auto i=0u; i<kJointCount; i++)
99+
parentIDs.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(asset::ICPUSkeleton)*kJointCount);
100+
{
101+
asset::ICPUSkeleton::joint_id_t parentJointIDs[] = { asset::ICPUSkeleton::invalid_joint_id,0u };
102+
memcpy(parentIDs.buffer->getPointer(),parentJointIDs,sizeof(parentJointIDs));
103+
}
104+
defaultTransforms.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(matrix3x4SIMD)*kJointCount);
105+
inverseBindPoses.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(matrix3x4SIMD)*kJointCount);
105106
{
106-
matrix3x4SIMD tmp;
107-
tmp.setTranslation(core::vectorSIMDf(0.f,float(i)*2.f-1.f,0.f));
108-
tmp.getInverse(invBindPoses[i]);
107+
auto* dftTransforms = reinterpret_cast<matrix3x4SIMD*>(defaultTransforms.buffer->getPointer());
108+
auto* invBindPoses = reinterpret_cast<matrix3x4SIMD*>(inverseBindPoses.buffer->getPointer());
109+
for (auto i=0u; i<kJointCount; i++)
110+
{
111+
dftTransforms[i] = matrix3x4SIMD();
112+
dftTransforms[i].setTranslation(core::vectorSIMDf(0.f,float(i)*2.f-1.f,0.f));
113+
dftTransforms[i].getInverse(invBindPoses[i]);
114+
}
109115
}
116+
jointAABBs.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(aabbox3df)*kJointCount);
110117
}
118+
const char* jointNames[] = {"root","bendy"};
119+
skeleton = core::make_smart_refctd_ptr<asset::ICPUSkeleton>(std::move(parentIDs),std::move(defaultTransforms),&jointNames[0],&jointNames[0]+kJointCount);
111120
}
112-
const char* jointNames[] = {"root","bendy"};
113-
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)->begin()[0];
115121

116122
//
117-
core::smart_refctd_ptr<video::IGPUMeshBuffer> mb;
123+
core::smart_refctd_ptr<video::IGPUMeshBuffer> gpumb;
118124
{
119125
VertexStruct vertices[8];
120126
vertices[0] = VertexStruct{{-1.f,-1.f,-1.f},{ 0, 0}};
@@ -125,6 +131,8 @@ int main()
125131
vertices[5] = VertexStruct{{ 1.f,-1.f, 1.f},{255,127}};
126132
vertices[6] = VertexStruct{{-1.f, 1.f, 1.f},{ 0,255}};
127133
vertices[7] = VertexStruct{{ 1.f, 1.f, 1.f},{127,255}};
134+
asset::SBufferBinding<asset::ICPUBuffer> bindings[asset::ICPUMeshBuffer::MAX_ATTR_BUF_BINDING_COUNT];
135+
bindings[0u] = {0u,core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>>>(sizeof(vertices),vertices,core::adopt_memory)};
128136

129137
uint16_t indices_indexed16[] =
130138
{
@@ -135,27 +143,28 @@ int main()
135143
0,2,4,2,4,6,
136144
1,3,5,3,5,7
137145
};
146+
asset::SBufferBinding<asset::ICPUBuffer> indexBinding{0u,core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>>>(sizeof(indices_indexed16),indices_indexed16,core::adopt_memory)};
138147

139148
asset::SPushConstantRange range[1] = {asset::ISpecializedShader::ESS_VERTEX,0u,sizeof(core::matrix4SIMD)};
140149

141-
auto createGPUSpecializedShaderFromSource = [=](const char* source, asset::ISpecializedShader::E_SHADER_STAGE stage)
150+
auto createSpecializedShaderFromSource = [=](const char* source, asset::ISpecializedShader::E_SHADER_STAGE stage)
142151
{
143152
auto spirv = device->getAssetManager()->getGLSLCompiler()->createSPIRVFromGLSL(source, stage, "main", "runtimeID");
144-
auto unspec = driver->createGPUShader(std::move(spirv));
145-
return driver->createGPUSpecializedShader(unspec.get(), { nullptr,nullptr,"main",stage });
153+
return core::make_smart_refctd_ptr<asset::ICPUSpecializedShader>(std::move(spirv),asset::ICPUSpecializedShader::SInfo{ nullptr,nullptr,"main",stage });
146154
};
147155
// origFilepath is only relevant when you have filesystem #includes in your shader
148-
auto createGPUSpecializedShaderFromSourceWithIncludes = [&](const char* source, asset::ISpecializedShader::E_SHADER_STAGE stage, const char* origFilepath)
156+
auto createSpecializedShaderFromSourceWithIncludes = [&](const char* source, asset::ISpecializedShader::E_SHADER_STAGE stage, const char* origFilepath)
149157
{
150158
auto resolved_includes = device->getAssetManager()->getGLSLCompiler()->resolveIncludeDirectives(source, stage, origFilepath);
151-
return createGPUSpecializedShaderFromSource(reinterpret_cast<const char*>(resolved_includes->getSPVorGLSL()->getPointer()), stage);
159+
return createSpecializedShaderFromSource(reinterpret_cast<const char*>(resolved_includes->getSPVorGLSL()->getPointer()), stage);
152160
};
153-
core::smart_refctd_ptr<video::IGPUSpecializedShader> shaders[2] =
161+
constexpr uint32_t kShaderCount = 2u;
162+
core::smart_refctd_ptr<asset::ICPUSpecializedShader> shaders[kShaderCount] =
154163
{
155-
createGPUSpecializedShaderFromSourceWithIncludes(vertexSource,asset::ISpecializedShader::ESS_VERTEX, "shader.vert"),
156-
createGPUSpecializedShaderFromSource(fragmentSource,asset::ISpecializedShader::ESS_FRAGMENT)
164+
createSpecializedShaderFromSourceWithIncludes(vertexSource,asset::ISpecializedShader::ESS_VERTEX, "shader.vert"),
165+
createSpecializedShaderFromSource(fragmentSource,asset::ISpecializedShader::ESS_FRAGMENT)
157166
};
158-
auto shadersPtr = reinterpret_cast<video::IGPUSpecializedShader**>(shaders);
167+
auto shadersPtr = reinterpret_cast<asset::ICPUSpecializedShader**>(shaders);
159168

160169
asset::SVertexInputParams inputParams;
161170
inputParams.enabledAttribFlags = 0b11u;
@@ -176,17 +185,19 @@ int main()
176185
asset::SStencilOpParams defaultStencil;
177186
asset::SRasterizationParams rasterParams;
178187
rasterParams.faceCullingMode = asset::EFCM_NONE;
179-
auto pipeline = driver->createGPURenderpassIndependentPipeline( nullptr,driver->createGPUPipelineLayout(range,range+1u,nullptr,nullptr,nullptr,nullptr),
180-
shadersPtr,shadersPtr+sizeof(shaders)/sizeof(core::smart_refctd_ptr<video::IGPUSpecializedShader>),
181-
inputParams,blendParams,assemblyParams,rasterParams);
182-
183-
asset::SBufferBinding<video::IGPUBuffer> bindings[video::IGPUMeshBuffer::MAX_ATTR_BUF_BINDING_COUNT];
184-
bindings[0u] = {0u,driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(vertices),vertices)};
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)});
188+
auto pipeline = core::make_smart_refctd_ptr<asset::ICPURenderpassIndependentPipeline>(
189+
core::make_smart_refctd_ptr<asset::ICPUPipelineLayout>(range,range+1u,nullptr,nullptr,nullptr,nullptr),
190+
shadersPtr,shadersPtr+kShaderCount,
191+
inputParams,blendParams,assemblyParams,rasterParams
192+
);
193+
194+
auto mb = core::make_smart_refctd_ptr<asset::ICPUMeshBuffer>(std::move(pipeline),nullptr,bindings,std::move(indexBinding));
186195
{
196+
mb->setSkin(std::move(inverseBindPoses),std::move(jointAABBs),std::move(skeleton),1u);
187197
mb->setIndexType(asset::EIT_16BIT);
188198
mb->setIndexCount(2*3*6);
189199
}
200+
gpumb = driver->getGPUObjectsFromAssets<asset::ICPUMeshBuffer>(&mb,&mb+1u)->begin()[0];
190201
}
191202

192203

@@ -211,9 +222,9 @@ int main()
211222

212223
//! Stress test for memleaks aside from demo how to create meshes that live on the GPU RAM
213224
{
214-
driver->bindGraphicsPipeline(mb->getPipeline());
215-
driver->pushConstants(mb->getPipeline()->getLayout(), asset::ISpecializedShader::ESS_VERTEX, 0u, sizeof(core::matrix4SIMD), mvp.pointer());
216-
driver->drawMeshBuffer(mb.get());
225+
driver->bindGraphicsPipeline(gpumb->getPipeline());
226+
driver->pushConstants(gpumb->getPipeline()->getLayout(), asset::ISpecializedShader::ESS_VERTEX, 0u, sizeof(core::matrix4SIMD), mvp.pointer());
227+
driver->drawMeshBuffer(gpumb.get());
217228
}
218229
driver->endScene();
219230

0 commit comments

Comments
 (0)