Problem: GltfLoad.cpp hides data about nodes transformation. #65
Labels
Data
Issues related to data (structures, formats, ...)
Enhancement
New feature or improvement
Idea
To be considered; may need testing and/or time
I'm trying to use RaZ in a simulator project.
I need the ability to transform Meshes imported from a Gltf file in Runtime.
For example:
We have a model of a clock:
node1 {transform, mesh} - watch case
node2 {transform, mesh} - hour hand
node3 {transform, mesh} - minutes hand
node4 {transform, mesh} - seconds hand
After exporting the model, you need to be able to:
model.getNodeTransform(node2.name).setRotation(hours_value)
model.getNodeTransform(node2.name).setRotation(minutes_value)
model.getNodeTransform(node2.name).setRotation(seconds_value)
Possible Solution.
In RaZ:
Add two modules: GltfSceneFormat (from GltfLoad.cpp) SceneRenderer (new component).
// GltfSceneFormat.cpp
void loadVertices(...)
{
...
//if (transform.has_value()) {
// for (Vertex& vert : submesh.getVertices()) {
// vert.position = transform->getPosition() + transform->getRotation() * (vert.position * transform->getScale());
// vert.normal = (transform->getRotation() * vert.normal).normalize();
// vert.tangent = (transform->getRotation() * vert.tangent).normalize();
// }
//}
}
std::vector<std::optional> loadTransforms(
SceneRenderer & sceneRenderer,
const std::vectorfastgltf::Node& nodes,
std::size_t meshCount)
{
std::vector<std::optional> transforms;
transforms.resize(meshCount);
for (const fastgltf::Node& node : nodes)
{
Transform transform = loadTransform(node);
sceneRenderer.m_transforms.emplace_back(transform);
//computeNodeTransform(node, std::nullopt, nodes, transforms);
}
return transforms;
}
void loadNodes(SceneRenderer & sceneRenderer, const std::vectorfastgltf::Node& nodes)
{
unsigned long transformIndex = 0;
}
std::pair<Mesh, MeshRenderer> loadMeshes(...)
{
...
Mesh loadedMesh;
MeshRenderer loadedMeshRenderer;
for (const fastgltf::Primitive& primitive : meshes[meshIndex].primitives) {
...
Submesh& submesh = loadedMesh.addSubmesh();
SubmeshRenderer& submeshRenderer = loadedMeshRenderer.addSubmeshRenderer();
...
loadedMeshRenderer.getMaterials().emplace_back(std::move(Material(MaterialType::COOK_TORRANCE)));
...
}
...
}
SceneRenderer load(const FilePath& filePath) {
...
const std::vector<std::optional> transforms = loadTransforms(sceneRenderer, asset->nodes, asset->meshes.size());
loadNodes(sceneRenderer, asset->nodes);
for (auto & node : asset->nodes)
{
if (node.meshIndex.has_value())
{
auto [mesh, meshRenderer] = loadMeshes(asset->meshes, node.meshIndex.value(), asset->buffers, asset->bufferViews, asset->accessors, transforms);
sceneRenderer.m_meshRenderers.emplace_back(std::move(meshRenderer));
}
}
const std::vector<std::optional> images = loadImages(asset->images, asset->buffers, asset->bufferViews, parentPath);
for (auto & meshRenderer : sceneRenderer.m_meshRenderers)
loadMaterials(asset->materials, asset->textures, images, meshRenderer);
...
return sceneRenderer;
}
And:
// RendererSystem.cpp
void RenderSystem::linkEntity(const EntityPtr& entity) {
...
}
void RenderSystem::initialize() {
// add GltfRenderer
registerComponents<Camera, Light, MeshRenderer, SceneRenderer>();
...
// add GltfRenderer
if (entity->hasComponent())
{
auto & gltfrenderer = entity->getComponent();
//for (auto & meshrenderer : gltfrenderer.getMeshRenderers())
for (auto & meshrenderer : gltfrenderer.m_meshRenderers)
updateMaterials(meshrenderer);
}
}
// RenderGph.cpp
void RenderGraph::execute(RenderSystem& renderSystem) {
...
// add GltfRenderer
}
else if (entity->hasComponent())
{
if (!entity->isEnabled() || !entity->hasComponent())
continue;
}
In App:
Raz::Entity& clock = world.addEntityWithComponentRaz::Transform();
auto & clockRenderer = clock.addComponentRaz::SceneRenderer(Raz::GltfSceneFormat::load(RAZ_ROOT "assets/watch_case.gltf"));
auto hours = clockRenderer.getTransformNode("hours_hend");
auto minutes = clockRenderer.getTransformNode("hours_hend");
auto seconds = clockRenderer.getTransformNode("hours_hend");
app.run([&] (float deltaTime) {
// get current hours_value, minutes_value, seconds_value
hours.value()->setRotation(hours_value);
minutes.value()->setRotation(minutes_value);
seconds.value()->setRotation(seconds_value);
});
Example implementation in attached files:
This really works.
You are free to use this code as you wish.
Vladimir Razumov.
updatedfiles.zip
The text was updated successfully, but these errors were encountered: