reimplement grid as SceneAsset
This commit is contained in:
@@ -57,8 +57,9 @@ extern "C"
|
||||
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAll(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *sceneAsset);
|
||||
EMSCRIPTEN_KEEPALIVE TNameComponentManager *SceneManager_getNameComponentManager(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getOverlayEntityCount(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_getOverlayEntityAt(TSceneManager *tSceneManager, size_t index);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGrid(TSceneManager *tSceneManager);
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_isGridEntity(TSceneManager *tSceneManager, EntityId entityId);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,49 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Material.h>
|
||||
#include <filament/MaterialInstance.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include <gltfio/AssetLoader.h>
|
||||
#include <gltfio/FilamentAsset.h>
|
||||
#include <gltfio/FilamentInstance.h>
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <filament/InstanceBuffer.h>
|
||||
#include <utils/Entity.h>
|
||||
#include "scene/SceneAsset.hpp"
|
||||
|
||||
namespace thermion {
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
class GridOverlay {
|
||||
public:
|
||||
GridOverlay(Engine& engine);
|
||||
void destroy();
|
||||
class GridOverlay : public SceneAsset {
|
||||
public:
|
||||
GridOverlay(Engine& engine);
|
||||
~GridOverlay();
|
||||
|
||||
utils::Entity sphere() {
|
||||
return _sphereEntity;
|
||||
}
|
||||
SceneAssetType getType() override { return SceneAsset::SceneAssetType::Gizmo; }
|
||||
bool isInstance() override { return false; }
|
||||
|
||||
SceneAsset* createInstance(MaterialInstance** materialInstances = nullptr,
|
||||
size_t materialInstanceCount = 0) override;
|
||||
|
||||
MaterialInstance** getMaterialInstances() override { return &_materialInstance; }
|
||||
size_t getMaterialInstanceCount() override { return 1; }
|
||||
|
||||
void addAllEntities(Scene* scene) override;
|
||||
void removeAllEntities(Scene* scene) override;
|
||||
|
||||
void setPriority(RenderableManager& rm, int priority) override;
|
||||
void setLayer(RenderableManager& rm, int layer) override;
|
||||
|
||||
utils::Entity grid() {
|
||||
return _gridEntity;
|
||||
}
|
||||
|
||||
private:
|
||||
Engine &_engine;
|
||||
utils::Entity _gridEntity;
|
||||
utils::Entity _sphereEntity;
|
||||
Material* _material;
|
||||
MaterialInstance* _materialInstance;
|
||||
MaterialInstance* _sphereMaterialInstance;
|
||||
size_t getInstanceCount() override { return _instances.size(); }
|
||||
SceneAsset* getInstanceByEntity(utils::Entity entity) override;
|
||||
SceneAsset* getInstanceAt(size_t index) override;
|
||||
size_t getChildEntityCount() override { return 2; }
|
||||
const Entity* getChildEntities() override;
|
||||
Entity findEntityByName(const char* name) override;
|
||||
|
||||
private:
|
||||
Engine& _engine;
|
||||
utils::Entity _gridEntity;
|
||||
utils::Entity _sphereEntity;
|
||||
Entity _childEntities[2];
|
||||
Material* _material;
|
||||
MaterialInstance* _materialInstance;
|
||||
std::vector<std::unique_ptr<GridOverlay>> _instances;
|
||||
|
||||
void createGrid();
|
||||
void createSphere();
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace thermion
|
||||
@@ -299,21 +299,9 @@ namespace thermion
|
||||
return _ncm;
|
||||
}
|
||||
|
||||
Entity getOverlayEntity(size_t index) {
|
||||
if(index == 0) {
|
||||
return _gridOverlay->grid();
|
||||
} else if(index == 1) {
|
||||
return _gridOverlay->sphere();
|
||||
} else {
|
||||
return Entity();
|
||||
}
|
||||
}
|
||||
|
||||
size_t getOverlayEntityCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
SceneAsset *createGrid();
|
||||
|
||||
bool isGridEntity(utils::Entity entity);
|
||||
|
||||
private:
|
||||
gltfio::AssetLoader *_assetLoader = nullptr;
|
||||
@@ -345,7 +333,7 @@ namespace thermion
|
||||
std::unique_ptr<AnimationManager> _animationManager = std::nullptr_t();
|
||||
std::unique_ptr<CollisionComponentManager> _collisionComponentManager = std::nullptr_t();
|
||||
|
||||
GridOverlay *_gridOverlay = std::nullptr_t();
|
||||
std::unique_ptr<GridOverlay> _grid = std::nullptr_t();
|
||||
|
||||
void _updateTransforms();
|
||||
};
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
#ifdef _WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include "scene/GridOverlay.hpp"
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/EntityManager.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include "material/grid.h"
|
||||
#include "scene/SceneManager.hpp"
|
||||
#include "material/grid.h"
|
||||
#include "Log.hpp"
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
using namespace filament::gltfio;
|
||||
|
||||
GridOverlay::GridOverlay(Engine &engine) : _engine(engine)
|
||||
{
|
||||
auto &entityManager = EntityManager::get();
|
||||
auto &transformManager = engine.getTransformManager();
|
||||
createGrid();
|
||||
createSphere();
|
||||
_childEntities[0] = _gridEntity;
|
||||
_childEntities[1] = _sphereEntity;
|
||||
}
|
||||
|
||||
GridOverlay::~GridOverlay()
|
||||
{
|
||||
auto &rm = _engine.getRenderableManager();
|
||||
auto &tm = _engine.getTransformManager();
|
||||
|
||||
rm.destroy(_sphereEntity);
|
||||
rm.destroy(_gridEntity);
|
||||
tm.destroy(_sphereEntity);
|
||||
tm.destroy(_gridEntity);
|
||||
_engine.destroy(_sphereEntity);
|
||||
_engine.destroy(_gridEntity);
|
||||
_engine.destroy(_materialInstance);
|
||||
_engine.destroy(_material);
|
||||
}
|
||||
|
||||
void GridOverlay::createGrid()
|
||||
{
|
||||
const int gridSize = 100;
|
||||
const float gridSpacing = 1.0f;
|
||||
int vertexCount = (gridSize + 1) * 4; // 2 axes, 2 vertices per line
|
||||
@@ -61,10 +66,10 @@ namespace thermion
|
||||
.vertexCount(vertexCount)
|
||||
.bufferCount(1)
|
||||
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
|
||||
.build(engine);
|
||||
.build(_engine);
|
||||
|
||||
vb->setBufferAt(engine, 0, VertexBuffer::BufferDescriptor(gridVertices, vertexCount * sizeof(filament::math::float3), [](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<float *>(buffer); }));
|
||||
vb->setBufferAt(_engine, 0, VertexBuffer::BufferDescriptor(gridVertices, vertexCount * sizeof(math::float3), [](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<float *>(buffer); }));
|
||||
|
||||
uint32_t *gridIndices = new uint32_t[vertexCount];
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
@@ -75,22 +80,22 @@ namespace thermion
|
||||
auto ib = IndexBuffer::Builder()
|
||||
.indexCount(vertexCount)
|
||||
.bufferType(IndexBuffer::IndexType::UINT)
|
||||
.build(engine);
|
||||
.build(_engine);
|
||||
|
||||
ib->setBuffer(engine, IndexBuffer::BufferDescriptor(
|
||||
gridIndices, vertexCount * sizeof(uint32_t),
|
||||
[](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<uint32_t *>(buffer); }));
|
||||
ib->setBuffer(_engine, IndexBuffer::BufferDescriptor(
|
||||
gridIndices,
|
||||
vertexCount * sizeof(uint32_t),
|
||||
[](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<uint32_t *>(buffer); }));
|
||||
|
||||
_gridEntity = entityManager.create();
|
||||
_gridEntity = utils::EntityManager::get().create();
|
||||
_material = Material::Builder()
|
||||
.package(GRID_PACKAGE, GRID_GRID_SIZE)
|
||||
.build(engine);
|
||||
.build(_engine);
|
||||
|
||||
_materialInstance = _material->createInstance();
|
||||
|
||||
_materialInstance->setParameter("maxDistance", 50.0f); // Adjust as needed
|
||||
_materialInstance->setParameter("color", math::float3{0.05f, 0.05f, 0.05f}); // Gray color for the grid
|
||||
_materialInstance->setParameter("maxDistance", 50.0f);
|
||||
_materialInstance->setParameter("color", math::float3{0.05f, 0.05f, 0.05f});
|
||||
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{-gridSize * gridSpacing / 2, 0, -gridSize * gridSpacing / 2},
|
||||
@@ -102,12 +107,16 @@ namespace thermion
|
||||
.culling(true)
|
||||
.receiveShadows(false)
|
||||
.castShadows(false)
|
||||
.build(engine, _gridEntity);
|
||||
.build(_engine, _gridEntity);
|
||||
}
|
||||
|
||||
void GridOverlay::createSphere()
|
||||
{
|
||||
const float sphereRadius = 0.05f;
|
||||
const int sphereSegments = 16;
|
||||
const int sphereRings = 16;
|
||||
|
||||
vertexCount = (sphereRings + 1) * (sphereSegments + 1);
|
||||
int vertexCount = (sphereRings + 1) * (sphereSegments + 1);
|
||||
int indexCount = sphereRings * sphereSegments * 6;
|
||||
|
||||
math::float3 *vertices = new math::float3[vertexCount];
|
||||
@@ -158,22 +167,23 @@ namespace thermion
|
||||
.vertexCount(vertexCount)
|
||||
.bufferCount(1)
|
||||
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
|
||||
.build(engine);
|
||||
.build(_engine);
|
||||
|
||||
sphereVb->setBufferAt(engine, 0, VertexBuffer::BufferDescriptor(vertices, vertexCount * sizeof(math::float3), [](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<math::float3 *>(buffer); }));
|
||||
sphereVb->setBufferAt(_engine, 0, VertexBuffer::BufferDescriptor(vertices, vertexCount * sizeof(math::float3), [](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<math::float3 *>(buffer); }));
|
||||
|
||||
auto sphereIb = IndexBuffer::Builder()
|
||||
.indexCount(indexCount)
|
||||
.bufferType(IndexBuffer::IndexType::UINT)
|
||||
.build(engine);
|
||||
.build(_engine);
|
||||
|
||||
sphereIb->setBuffer(engine, IndexBuffer::BufferDescriptor(
|
||||
indices, indexCount * sizeof(uint32_t),
|
||||
[](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<uint32_t *>(buffer); }));
|
||||
sphereIb->setBuffer(_engine, IndexBuffer::BufferDescriptor(
|
||||
indices,
|
||||
indexCount * sizeof(uint32_t),
|
||||
[](void *buffer, size_t size, void *)
|
||||
{ delete[] static_cast<uint32_t *>(buffer); }));
|
||||
|
||||
_sphereEntity = entityManager.create();
|
||||
_sphereEntity = utils::EntityManager::get().create();
|
||||
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{-sphereRadius, -sphereRadius, -sphereRadius},
|
||||
@@ -184,19 +194,70 @@ namespace thermion
|
||||
.culling(true)
|
||||
.receiveShadows(false)
|
||||
.castShadows(false)
|
||||
.build(engine, _sphereEntity);
|
||||
.build(_engine, _sphereEntity);
|
||||
}
|
||||
|
||||
void GridOverlay::destroy()
|
||||
SceneAsset *GridOverlay::createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount)
|
||||
{
|
||||
auto &rm = _engine.getRenderableManager();
|
||||
auto &tm = _engine.getTransformManager();
|
||||
rm.destroy(_sphereEntity);
|
||||
rm.destroy(_gridEntity);
|
||||
tm.destroy(_sphereEntity);
|
||||
tm.destroy(_gridEntity);
|
||||
_engine.destroy(_sphereEntity);
|
||||
_engine.destroy(_gridEntity);
|
||||
auto instance = std::make_unique<GridOverlay>(_engine);
|
||||
auto *raw = instance.get();
|
||||
_instances.push_back(std::move(instance));
|
||||
return reinterpret_cast<SceneAsset*>(raw);
|
||||
}
|
||||
|
||||
void GridOverlay::addAllEntities(Scene *scene)
|
||||
{
|
||||
scene->addEntity(_gridEntity);
|
||||
scene->addEntity(_sphereEntity);
|
||||
}
|
||||
|
||||
void GridOverlay::removeAllEntities(Scene *scene)
|
||||
{
|
||||
scene->remove(_gridEntity);
|
||||
scene->remove(_sphereEntity);
|
||||
}
|
||||
|
||||
void GridOverlay::setPriority(RenderableManager &rm, int priority)
|
||||
{
|
||||
auto gridInstance = rm.getInstance(_gridEntity);
|
||||
rm.setPriority(gridInstance, priority);
|
||||
auto sphereInstance = rm.getInstance(_sphereEntity);
|
||||
rm.setPriority(sphereInstance, priority);
|
||||
}
|
||||
|
||||
void GridOverlay::setLayer(RenderableManager &rm, int layer)
|
||||
{
|
||||
auto gridInstance = rm.getInstance(_gridEntity);
|
||||
rm.setLayerMask(gridInstance, 0xFF, 1u << (uint8_t)layer);
|
||||
auto sphereInstance = rm.getInstance(_sphereEntity);
|
||||
rm.setLayerMask(sphereInstance, 0xFF, 1u << (uint8_t)layer);
|
||||
}
|
||||
|
||||
SceneAsset *GridOverlay::getInstanceByEntity(utils::Entity entity)
|
||||
{
|
||||
for (auto &instance : _instances)
|
||||
{
|
||||
if (instance->_gridEntity == entity || instance->_sphereEntity == entity)
|
||||
{
|
||||
return instance.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SceneAsset *GridOverlay::getInstanceAt(size_t index)
|
||||
{
|
||||
return _instances[index].get();
|
||||
}
|
||||
|
||||
const Entity *GridOverlay::getChildEntities()
|
||||
{
|
||||
return _childEntities;
|
||||
}
|
||||
|
||||
Entity GridOverlay::findEntityByName(const char *name)
|
||||
{
|
||||
return Entity(); // Not implemented
|
||||
}
|
||||
|
||||
} // namespace thermion
|
||||
@@ -207,13 +207,15 @@ extern "C"
|
||||
return reinterpret_cast<TNameComponentManager*>(sceneManager->getNameComponentManager());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getOverlayEntityCount(TSceneManager *tSceneManager) {
|
||||
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGrid(TSceneManager *tSceneManager) {
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
return sceneManager->getOverlayEntityCount();
|
||||
auto *grid = sceneManager->createGrid();
|
||||
return reinterpret_cast<TSceneAsset*>(grid);
|
||||
}
|
||||
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_getOverlayEntityAt(TSceneManager *tSceneManager, size_t index) {
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE bool SceneManager_isGridEntity(TSceneManager *tSceneManager, EntityId entityId) {
|
||||
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||
auto entity = sceneManager->getOverlayEntity(index);
|
||||
return utils::Entity::smuggle(entity);
|
||||
return sceneManager->isGridEntity(utils::Entity::import(entityId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,11 +107,6 @@ namespace thermion
|
||||
|
||||
_animationManager = std::make_unique<AnimationManager>(_engine, _scene);
|
||||
|
||||
_gridOverlay = new GridOverlay(*_engine);
|
||||
|
||||
_scene->addEntity(_gridOverlay->sphere());
|
||||
_scene->addEntity(_gridOverlay->grid());
|
||||
|
||||
_unlitFixedSizeMaterial =
|
||||
Material::Builder()
|
||||
.package(UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_DATA, UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE)
|
||||
@@ -131,8 +126,8 @@ namespace thermion
|
||||
|
||||
_engine->destroy(_unlitFixedSizeMaterial);
|
||||
_cameras.clear();
|
||||
|
||||
_gridOverlay->destroy();
|
||||
|
||||
_grid = nullptr;
|
||||
|
||||
_gltfResourceLoader->asyncCancelLoad();
|
||||
_ubershaderProvider->destroyMaterials();
|
||||
@@ -148,6 +143,28 @@ namespace thermion
|
||||
AssetLoader::destroy(&_assetLoader);
|
||||
}
|
||||
|
||||
SceneAsset *SceneManager::createGrid() {
|
||||
if(!_grid) {
|
||||
_grid = std::make_unique<GridOverlay>(*_engine);
|
||||
}
|
||||
return _grid.get();
|
||||
}
|
||||
|
||||
bool SceneManager::isGridEntity(utils::Entity entity) {
|
||||
if(!_grid) {
|
||||
return false;
|
||||
}
|
||||
if(entity == _grid->getEntity()) {
|
||||
return true;
|
||||
}
|
||||
for(int i =0; i < _grid->getChildEntityCount(); i++) {
|
||||
if(entity == _grid->getChildEntities()[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Gizmo *SceneManager::createGizmo(View *view, Scene *scene)
|
||||
{
|
||||
auto gizmo = std::make_unique<Gizmo>(_engine, view, scene, _unlitFixedSizeMaterial);
|
||||
|
||||
Reference in New Issue
Block a user