feat: move HighlightOverlay to nested class, move createGeometry to SceneManager, add queueRelativePositionUpdateFromViewportVector
This commit is contained in:
46
thermion_dart/native/include/CustomGeometry.hpp
Normal file
46
thermion_dart/native/include/CustomGeometry.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/VertexBuffer.h>
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/Frustum.h>
|
||||
|
||||
namespace thermion_filament
|
||||
{
|
||||
|
||||
using namespace filament;
|
||||
|
||||
// CustomGeometry.h
|
||||
class CustomGeometry {
|
||||
public:
|
||||
CustomGeometry(float* vertices, uint32_t numVertices, uint16_t* indices, uint32_t numIndices, RenderableManager::PrimitiveType primitiveType, Engine* engine);
|
||||
~CustomGeometry();
|
||||
|
||||
void computeBoundingBox();
|
||||
VertexBuffer* vertexBuffer();
|
||||
IndexBuffer* indexBuffer();
|
||||
Box getBoundingBox() const;
|
||||
|
||||
float* vertices;
|
||||
uint32_t numVertices;
|
||||
uint16_t* indices;
|
||||
uint32_t numIndices;
|
||||
Box boundingBox;
|
||||
RenderableManager::PrimitiveType primitiveType;
|
||||
|
||||
private:
|
||||
Engine* _engine;
|
||||
bool _vertexBufferFreed = false;
|
||||
bool _indexBufferFreed = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <filament/InstanceBuffer.h>
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "material/gizmo.h"
|
||||
#include "utils/NameComponentManager.h"
|
||||
|
||||
#include "CustomGeometry.hpp"
|
||||
#include "Gizmo.hpp"
|
||||
|
||||
#include "GridOverlay.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "components/CollisionComponentManager.hpp"
|
||||
@@ -46,10 +49,33 @@ namespace thermion_filament
|
||||
const ResourceLoaderWrapperImpl *const loader,
|
||||
Engine *engine,
|
||||
Scene *scene,
|
||||
Scene *highlightScene,
|
||||
const char *uberArchivePath);
|
||||
~SceneManager();
|
||||
|
||||
class HighlightOverlay {
|
||||
public:
|
||||
HighlightOverlay(EntityId id, SceneManager* const sceneManager, Engine* const engine, float r, float g, float b);
|
||||
~HighlightOverlay();
|
||||
|
||||
bool isValid() {
|
||||
return !_entity.isNull();
|
||||
}
|
||||
|
||||
private:
|
||||
MaterialInstance* _highlightMaterialInstance;
|
||||
CustomGeometry* _newGeometry;
|
||||
FilamentInstance* _newInstance;
|
||||
Entity _entity;
|
||||
Engine* const _engine;
|
||||
SceneManager* const _sceneManager;
|
||||
};
|
||||
|
||||
////
|
||||
/// @brief Load the glTF file from the specified path and adds all entities to the scene.
|
||||
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
|
||||
/// @param relativeResourcePath the (relative) path to the asset's resources.
|
||||
/// @return the glTF entity.
|
||||
///
|
||||
EntityId loadGltf(const char *uri, const char *relativeResourcePath, bool keepData = false);
|
||||
|
||||
////
|
||||
@@ -77,6 +103,7 @@ namespace thermion_filament
|
||||
void queuePositionUpdate(EntityId e, float x, float y, float z, bool relative);
|
||||
void queueRotationUpdate(EntityId e, float rads, float x, float y, float z, float w, bool relative);
|
||||
void queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z);
|
||||
void queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY);
|
||||
const utils::Entity *getCameraEntities(EntityId e);
|
||||
size_t getCameraEntityCount(EntityId e);
|
||||
const utils::Entity *getLightEntities(EntityId e) noexcept;
|
||||
@@ -158,7 +185,15 @@ namespace thermion_filament
|
||||
bool addAnimationComponent(EntityId entity);
|
||||
void removeAnimationComponent(EntityId entity);
|
||||
|
||||
void setStencilHighlight(EntityId entity);
|
||||
/// @brief renders an outline around the specified entity.
|
||||
///
|
||||
///
|
||||
void setStencilHighlight(EntityId entity, float r, float g, float b);
|
||||
|
||||
/// @brief removes the outline around the specified entity.
|
||||
///
|
||||
///
|
||||
void removeStencilHighlight(EntityId entity);
|
||||
|
||||
/// @brief returns the number of instances of the FilamentAsset represented by the given entity.
|
||||
/// @param entityId
|
||||
@@ -188,16 +223,56 @@ namespace thermion_filament
|
||||
///
|
||||
void setLayerEnabled(int layer, bool enabled);
|
||||
|
||||
///
|
||||
/// Creates an entity with the specified geometry/material and adds to the scene.
|
||||
/// If [keepData] is true, stores
|
||||
///
|
||||
EntityId createGeometry(
|
||||
float *vertices,
|
||||
uint32_t numVertices,
|
||||
uint16_t *indices,
|
||||
uint32_t numIndices,
|
||||
filament::RenderableManager::PrimitiveType primitiveType = RenderableManager::PrimitiveType::TRIANGLES,
|
||||
const char *materialPath = nullptr,
|
||||
bool keepData = false
|
||||
);
|
||||
|
||||
friend class FilamentViewer;
|
||||
|
||||
Gizmo* gizmo = nullptr;
|
||||
|
||||
gltfio::MaterialProvider * const unlitMaterialProvider() {
|
||||
return _unlitMaterialProvider;
|
||||
}
|
||||
|
||||
bool isGeometryEntity(EntityId entity) {
|
||||
return _geometry.find(entity) != _geometry.end();
|
||||
}
|
||||
|
||||
CustomGeometry* const getGeometry(EntityId entityId) {
|
||||
return _geometry[entityId];
|
||||
}
|
||||
|
||||
Scene* const getScene() {
|
||||
return _scene;
|
||||
}
|
||||
|
||||
bool isGltfAsset(EntityId entity) {
|
||||
return getAssetByEntityId(entity) != nullptr;
|
||||
}
|
||||
|
||||
gltfio::FilamentInstance *getInstanceByEntityId(EntityId entityId);
|
||||
gltfio::FilamentAsset *getAssetByEntityId(EntityId entityId);
|
||||
|
||||
gltfio::FilamentInstance *createGltfAssetInstance(FilamentAsset* asset) {
|
||||
return _assetLoader->createInstance(asset);
|
||||
}
|
||||
|
||||
private:
|
||||
gltfio::AssetLoader *_assetLoader = nullptr;
|
||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||
Engine *_engine = nullptr;
|
||||
Scene *_scene = nullptr;
|
||||
Scene *_highlightScene = nullptr;
|
||||
View* _view = nullptr;
|
||||
|
||||
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
|
||||
@@ -214,19 +289,20 @@ namespace thermion_filament
|
||||
gltfio::FilamentInstance *>
|
||||
_instances;
|
||||
tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
|
||||
tsl::robin_map<EntityId, CustomGeometry*> _geometry;
|
||||
tsl::robin_map<EntityId, HighlightOverlay *> _highlighted;
|
||||
|
||||
tsl::robin_map<EntityId, std::tuple<math::float3, bool, math::quatf, bool, float>> _transformUpdates;
|
||||
|
||||
AnimationComponentManager *_animationComponentManager = nullptr;
|
||||
CollisionComponentManager *_collisionComponentManager = nullptr;
|
||||
|
||||
gltfio::FilamentInstance *getInstanceByEntityId(EntityId entityId);
|
||||
gltfio::FilamentAsset *getAssetByEntityId(EntityId entityId);
|
||||
|
||||
utils::Entity findEntityByName(
|
||||
const gltfio::FilamentInstance *instance,
|
||||
const char *entityName);
|
||||
|
||||
GridOverlay* _gridOverlay = nullptr;
|
||||
GridOverlay* _gridOverlay = nullptr;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
92
thermion_dart/native/src/CustomGeometry.cpp
Normal file
92
thermion_dart/native/src/CustomGeometry.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/Frustum.h>
|
||||
|
||||
#include "CustomGeometry.hpp"
|
||||
|
||||
namespace thermion_filament {
|
||||
|
||||
using namespace filament;
|
||||
|
||||
CustomGeometry::CustomGeometry(
|
||||
float* vertices,
|
||||
uint32_t numVertices,
|
||||
uint16_t* indices,
|
||||
uint32_t numIndices,
|
||||
RenderableManager::PrimitiveType primitiveType,
|
||||
Engine* engine)
|
||||
: numVertices(numVertices), numIndices(numIndices), _engine(engine) {
|
||||
this->primitiveType = primitiveType;
|
||||
this->vertices = new float[numVertices];
|
||||
std::memcpy(this->vertices, vertices, numVertices * sizeof(float));
|
||||
|
||||
this->indices = new uint16_t[numIndices];
|
||||
std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t));
|
||||
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
IndexBuffer* CustomGeometry::indexBuffer() {
|
||||
IndexBuffer::BufferDescriptor::Callback indexCallback = [](void *buf, size_t,
|
||||
void *data)
|
||||
{
|
||||
// free((void *)buf);
|
||||
};
|
||||
|
||||
auto indexBuffer = IndexBuffer::Builder()
|
||||
.indexCount(numIndices)
|
||||
.bufferType(IndexBuffer::IndexType::USHORT)
|
||||
.build(*_engine);
|
||||
|
||||
indexBuffer->setBuffer(*_engine, IndexBuffer::BufferDescriptor(
|
||||
this->indices, indexBuffer->getIndexCount() * sizeof(uint16_t), indexCallback));
|
||||
return indexBuffer;
|
||||
}
|
||||
|
||||
VertexBuffer* CustomGeometry::vertexBuffer() {
|
||||
VertexBuffer::BufferDescriptor::Callback vertexCallback = [](void *buf, size_t,
|
||||
void *data)
|
||||
{
|
||||
// free((void *)buf);
|
||||
};
|
||||
|
||||
auto vertexBuffer = VertexBuffer::Builder()
|
||||
.vertexCount(numVertices)
|
||||
.bufferCount(1)
|
||||
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
|
||||
.build(*_engine);
|
||||
|
||||
vertexBuffer->setBufferAt(*_engine, 0, VertexBuffer::BufferDescriptor(
|
||||
this->vertices, vertexBuffer->getVertexCount() * sizeof(math::float3), vertexCallback));
|
||||
return vertexBuffer;
|
||||
}
|
||||
|
||||
CustomGeometry::~CustomGeometry() {
|
||||
delete[] vertices;
|
||||
delete[] indices;
|
||||
}
|
||||
|
||||
void CustomGeometry::computeBoundingBox() {
|
||||
float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX;
|
||||
float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX;
|
||||
|
||||
for (uint32_t i = 0; i < numVertices; i += 3) {
|
||||
minX = std::min(vertices[i], minX);
|
||||
minY = std::min(vertices[i + 1], minY);
|
||||
minZ = std::min(vertices[i + 2], minZ);
|
||||
maxX = std::max(vertices[i], maxX);
|
||||
maxY = std::max(vertices[i + 1], maxY);
|
||||
maxZ = std::max(vertices[i + 2], maxZ);
|
||||
}
|
||||
|
||||
boundingBox = Box{{minX, minY, minZ}, {maxX, maxY, maxZ}};
|
||||
}
|
||||
|
||||
Box CustomGeometry::getBoundingBox() const {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
}
|
||||
183
thermion_dart/native/src/HighlightOverlay.cpp
Normal file
183
thermion_dart/native/src/HighlightOverlay.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <filament/Material.h>
|
||||
#include <filament/MaterialInstance.h>
|
||||
|
||||
#include "SceneManager.hpp"
|
||||
|
||||
namespace thermion_filament {
|
||||
|
||||
SceneManager::HighlightOverlay::HighlightOverlay(
|
||||
EntityId entityId,
|
||||
SceneManager* const sceneManager,
|
||||
Engine* engine,
|
||||
float r,
|
||||
float g,
|
||||
float b) : _sceneManager(sceneManager), _engine(engine) {
|
||||
|
||||
auto& rm = engine->getRenderableManager();
|
||||
|
||||
auto& tm = engine->getTransformManager();
|
||||
|
||||
// Create the outline/highlight material instance
|
||||
filament::gltfio::MaterialKey dummyKey; // We're not using the key for this simple material
|
||||
filament::gltfio::UvMap dummyUvMap; // We're not using UV mapping for this simple material
|
||||
|
||||
auto materialProvider = sceneManager->unlitMaterialProvider();
|
||||
|
||||
_highlightMaterialInstance = materialProvider->createMaterialInstance(&dummyKey, &dummyUvMap);
|
||||
|
||||
_highlightMaterialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
||||
_highlightMaterialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::KEEP);
|
||||
_highlightMaterialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::KEEP);
|
||||
_highlightMaterialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::NE);
|
||||
_highlightMaterialInstance->setStencilReferenceValue(1);
|
||||
_highlightMaterialInstance->setParameter("color", filament::math::float3 { r, g, b });
|
||||
_highlightMaterialInstance->setParameter("scale", 1.05f);
|
||||
|
||||
auto scene = sceneManager->getScene();
|
||||
|
||||
if(sceneManager->isGeometryEntity(entityId)) {
|
||||
|
||||
auto geometryEntity = Entity::import(entityId);
|
||||
auto renderable = rm.getInstance(geometryEntity);
|
||||
|
||||
auto materialInstance = rm.getMaterialInstanceAt(renderable, 0);
|
||||
|
||||
// set stencil write on the existing material
|
||||
materialInstance->setStencilWrite(true);
|
||||
materialInstance->setDepthWrite(true);
|
||||
materialInstance->setStencilReferenceValue(1);
|
||||
materialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
||||
materialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::REPLACE);
|
||||
materialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::REPLACE);
|
||||
materialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::A);
|
||||
|
||||
auto geometry = sceneManager->getGeometry(entityId);
|
||||
|
||||
_entity = utils::EntityManager::get().create();
|
||||
RenderableManager::Builder builder(1);
|
||||
builder.boundingBox(geometry->getBoundingBox())
|
||||
.geometry(0, geometry->primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, geometry->numIndices)
|
||||
.culling(true)
|
||||
.material(0, _highlightMaterialInstance)
|
||||
.receiveShadows(false)
|
||||
.castShadows(false);
|
||||
|
||||
builder.build(*engine, _entity);
|
||||
|
||||
scene->addEntity(_entity);
|
||||
auto outlineTransformInstance = tm.getInstance(_entity);
|
||||
auto entityTransformInstance = tm.getInstance(geometryEntity);
|
||||
tm.setParent(outlineTransformInstance, entityTransformInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("Not geometry");
|
||||
|
||||
if(sceneManager->isGltfAsset(entityId)) {
|
||||
|
||||
auto *asset = sceneManager->getAssetByEntityId(entityId);
|
||||
|
||||
if (asset)
|
||||
{
|
||||
|
||||
Log("Found glTF FilamentAsset with %d material instances", asset->getInstance()->getMaterialInstanceCount());
|
||||
|
||||
|
||||
auto materialInstance = asset->getInstance()->getMaterialInstances()[0];
|
||||
|
||||
// set stencil write on the existing material
|
||||
materialInstance->setStencilWrite(true);
|
||||
materialInstance->setDepthWrite(true);
|
||||
materialInstance->setStencilReferenceValue(1);
|
||||
materialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
||||
materialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::REPLACE);
|
||||
materialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::REPLACE);
|
||||
materialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::A);
|
||||
|
||||
auto newInstance = sceneManager->createGltfAssetInstance(asset);
|
||||
|
||||
_entity = newInstance->getRoot();
|
||||
|
||||
if(!newInstance) {
|
||||
Log("Couldn't create new instance");
|
||||
} else {
|
||||
auto& tm = engine->getTransformManager();
|
||||
for(int i = 0; i < newInstance->getEntityCount(); i++) {
|
||||
auto entity = newInstance->getEntities()[i];
|
||||
auto renderableInstance = rm.getInstance(entity);
|
||||
rm.setPriority(renderableInstance, 7);
|
||||
if(renderableInstance.isValid()) {
|
||||
for(int primitiveIndex = 0; primitiveIndex < rm.getPrimitiveCount(renderableInstance); primitiveIndex++) {
|
||||
rm.setMaterialInstanceAt(renderableInstance, primitiveIndex, _highlightMaterialInstance);
|
||||
}
|
||||
} else {
|
||||
Log("Not renderable, ignoring");
|
||||
}
|
||||
}
|
||||
scene->addEntities(newInstance->getEntities(), newInstance->getEntityCount());
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Log("Not FilamentAsset");
|
||||
}
|
||||
}
|
||||
|
||||
Log("Looking for parent");
|
||||
|
||||
auto renderable = rm.getInstance(Entity::import(entityId));
|
||||
auto transformInstance = tm.getInstance(Entity::import(entityId));
|
||||
if(!transformInstance.isValid()) {
|
||||
Log("Unknown entity type");
|
||||
return;
|
||||
}
|
||||
|
||||
Entity parent;
|
||||
while(true) {
|
||||
auto newParent = tm.getParent(transformInstance);
|
||||
if(newParent.isNull()) {
|
||||
break;
|
||||
}
|
||||
parent = newParent;
|
||||
transformInstance = tm.getInstance(parent);
|
||||
}
|
||||
if(parent.isNull()) {
|
||||
Log("Unknown entity type");
|
||||
return;
|
||||
}
|
||||
|
||||
sceneManager->setStencilHighlight(Entity::smuggle(parent), r, g, b);
|
||||
}
|
||||
|
||||
SceneManager::HighlightOverlay::~HighlightOverlay() {
|
||||
Log("DEsturctor called!");
|
||||
if (_entity.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& rm = _engine->getRenderableManager();
|
||||
auto& tm = _engine->getTransformManager();
|
||||
|
||||
_sceneManager->getScene()->remove(_entity);
|
||||
|
||||
|
||||
// If this was a glTF asset instance, we need to destroy it
|
||||
if (_newInstance) {
|
||||
for(int i =0 ; i < _newInstance->getEntityCount(); i++) {
|
||||
auto entity =_newInstance->getEntities()[i];
|
||||
_sceneManager->getScene()->remove(entity);
|
||||
rm.destroy(entity);
|
||||
}
|
||||
}
|
||||
|
||||
tm.destroy(_entity);
|
||||
|
||||
_engine->destroy(_highlightMaterialInstance);
|
||||
|
||||
// Destroy the entity
|
||||
utils::EntityManager::get().destroy(_entity);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
#include <gltfio/TextureProvider.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include <gltfio/materials/uberarchive.h>
|
||||
#include <imageio/ImageDecoder.h>
|
||||
|
||||
#include "material/FileMaterialProvider.hpp"
|
||||
@@ -30,8 +30,7 @@
|
||||
#include "StreamBufferAdapter.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "SceneManager.hpp"
|
||||
|
||||
#include "gltfio/materials/uberarchive.h"
|
||||
#include "CustomGeometry.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -52,13 +51,11 @@ namespace thermion_filament
|
||||
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
|
||||
Engine *engine,
|
||||
Scene *scene,
|
||||
Scene *highlightScene,
|
||||
const char *uberArchivePath)
|
||||
: _view(view),
|
||||
_resourceLoaderWrapper(resourceLoaderWrapper),
|
||||
_engine(engine),
|
||||
_scene(scene),
|
||||
_highlightScene(highlightScene)
|
||||
_scene(scene)
|
||||
{
|
||||
|
||||
_stbDecoder = createStbProvider(_engine);
|
||||
@@ -112,11 +109,9 @@ namespace thermion_filament
|
||||
|
||||
SceneManager::~SceneManager()
|
||||
{
|
||||
|
||||
destroyAll();
|
||||
|
||||
gizmo->destroy();
|
||||
delete gizmo;
|
||||
_gridOverlay->destroy();
|
||||
destroyAll();
|
||||
|
||||
_gltfResourceLoader->asyncCancelLoad();
|
||||
_ubershaderProvider->destroyMaterials();
|
||||
@@ -1830,6 +1825,55 @@ namespace thermion_filament
|
||||
tm.setTransform(transformInstance, newTransform);
|
||||
}
|
||||
|
||||
void SceneManager::queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY)
|
||||
{
|
||||
// Get the camera and viewport
|
||||
const auto &camera = _view->getCamera();
|
||||
const auto &vp = _view->getViewport();
|
||||
|
||||
// Convert viewport coordinates to NDC space
|
||||
float ndcX = (2.0f * viewportCoordX) / vp.width - 1.0f;
|
||||
float ndcY = 1.0f - (2.0f * viewportCoordY) / vp.height;
|
||||
|
||||
Log("ndc X ndcY %f %f", ndcX, ndcY );
|
||||
// Get the current position of the entity
|
||||
auto &tm = _engine->getTransformManager();
|
||||
auto entity = Entity::import(entityId);
|
||||
auto transformInstance = tm.getInstance(entity);
|
||||
auto currentTransform = tm.getTransform(transformInstance);
|
||||
|
||||
// get entity model origin in camera space
|
||||
auto entityPositionInCameraSpace = camera.getViewMatrix() * currentTransform * filament::math::float4 { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
// get entity model origin in clip space
|
||||
auto entityPositionInClipSpace = camera.getProjectionMatrix() * entityPositionInCameraSpace;
|
||||
auto entityPositionInNdcSpace = entityPositionInClipSpace / entityPositionInClipSpace.w;
|
||||
|
||||
Log("entityPositionInCameraSpace %f %f %f %f", entityPositionInCameraSpace.x, entityPositionInCameraSpace.y, entityPositionInCameraSpace.z, entityPositionInCameraSpace.w);
|
||||
Log("entityPositionInClipSpace %f %f %f %f", entityPositionInClipSpace.x, entityPositionInClipSpace.y, entityPositionInClipSpace.z, entityPositionInClipSpace.w);
|
||||
Log("entityPositionInNdcSpace %f %f %f %f", entityPositionInNdcSpace.x, entityPositionInNdcSpace.y, entityPositionInNdcSpace.z, entityPositionInNdcSpace.w);
|
||||
|
||||
// Viewport coords in NDC space (use entity position in camera space Z to project onto near plane)
|
||||
math::float4 ndcNearPlanePos = {ndcX, ndcY, -1.0f, 1.0f};
|
||||
math::float4 ndcFarPlanePos = {ndcX, ndcY, 0.99f, 1.0f};
|
||||
math::float4 ndcEntityPlanePos = {ndcX, ndcY, entityPositionInNdcSpace.z, 1.0f};
|
||||
|
||||
// Get viewport coords in clip space
|
||||
math::float4 nearPlaneInClipSpace = Camera::inverseProjection(camera.getProjectionMatrix()) * ndcNearPlanePos;
|
||||
auto nearPlaneInCameraSpace = nearPlaneInClipSpace / nearPlaneInClipSpace.w;
|
||||
math::float4 farPlaneInClipSpace = Camera::inverseProjection(camera.getProjectionMatrix()) * ndcFarPlanePos;
|
||||
auto farPlaneInCameraSpace = farPlaneInClipSpace / farPlaneInClipSpace.w;
|
||||
math::float4 entityPlaneInClipSpace = Camera::inverseProjection(camera.getProjectionMatrix()) * ndcEntityPlanePos;
|
||||
auto entityPlaneInCameraSpace = entityPlaneInClipSpace / entityPlaneInClipSpace.w;
|
||||
auto entityPlaneInWorldSpace = camera.getModelMatrix() * entityPlaneInCameraSpace;
|
||||
|
||||
Log("nearPlaneInClipSpace %f %f %f %f",nearPlaneInClipSpace.x, nearPlaneInClipSpace.y, nearPlaneInClipSpace.z, nearPlaneInClipSpace.w);
|
||||
Log("nearPlaneInCameraSpace %f %f %f %f",nearPlaneInCameraSpace.x, nearPlaneInCameraSpace.y, nearPlaneInCameraSpace.z, nearPlaneInCameraSpace.w);
|
||||
Log("entityPlaneInCameraSpace %f %f %f %f",entityPlaneInCameraSpace.x, entityPlaneInCameraSpace.y, entityPlaneInCameraSpace.z, entityPlaneInCameraSpace.w);
|
||||
Log("entityPlaneInWorldSpace %f %f %f %f",entityPlaneInWorldSpace.x, entityPlaneInWorldSpace.y, entityPlaneInWorldSpace.z, entityPlaneInWorldSpace.w);
|
||||
|
||||
// Queue the position update (as a relative movement)
|
||||
queuePositionUpdate(entityId, entityPlaneInWorldSpace.x, entityPlaneInWorldSpace.y, entityPlaneInWorldSpace.z, false);
|
||||
}
|
||||
void SceneManager::queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z)
|
||||
{
|
||||
auto worldAxis = math::float3{x, y, z};
|
||||
@@ -2212,7 +2256,6 @@ void SceneManager::queueRelativePositionUpdateWorldAxis(EntityId entity, float v
|
||||
return;
|
||||
}
|
||||
rm.setPriority(renderableInstance, priority);
|
||||
Log("Set instance renderable priority to %d", priority);
|
||||
}
|
||||
|
||||
Aabb2 SceneManager::getBoundingBox(EntityId entityId)
|
||||
@@ -2292,8 +2335,71 @@ void SceneManager::queueRelativePositionUpdateWorldAxis(EntityId entity, float v
|
||||
_view->setLayerEnabled(layer, enabled);
|
||||
}
|
||||
|
||||
|
||||
void SceneManager::removeStencilHighlight(EntityId entityId) {
|
||||
auto found = _highlighted.find(entityId);
|
||||
if(found == _highlighted.end()) {
|
||||
return;
|
||||
}
|
||||
delete found->second;
|
||||
_highlighted.erase(entityId);
|
||||
}
|
||||
|
||||
void SceneManager::setStencilHighlight(EntityId entityId, float r, float g, float b) {
|
||||
|
||||
auto highlightEntity = new HighlightOverlay(entityId, this, _engine, r, g, b);
|
||||
|
||||
if(!highlightEntity->isValid()) {
|
||||
delete highlightEntity;
|
||||
} else {
|
||||
_highlighted.emplace(entityId, highlightEntity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EntityId SceneManager::createGeometry(
|
||||
float *vertices,
|
||||
uint32_t numVertices,
|
||||
uint16_t *indices,
|
||||
uint32_t numIndices,
|
||||
RenderableManager::PrimitiveType primitiveType,
|
||||
const char *materialPath,
|
||||
bool keepData
|
||||
) {
|
||||
|
||||
auto geometry = new CustomGeometry(vertices, numVertices, indices, numIndices, primitiveType, _engine);
|
||||
|
||||
filament::Material* mat = nullptr;
|
||||
if (materialPath) {
|
||||
auto matData = _resourceLoaderWrapper->load(materialPath);
|
||||
mat = Material::Builder().package(matData.data, matData.size).build(*_engine);
|
||||
_resourceLoaderWrapper->free(matData);
|
||||
}
|
||||
|
||||
auto renderable = utils::EntityManager::get().create();
|
||||
RenderableManager::Builder builder(1);
|
||||
|
||||
builder.boundingBox(geometry->getBoundingBox())
|
||||
.geometry(0, primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, numIndices)
|
||||
.culling(true)
|
||||
.receiveShadows(false)
|
||||
.castShadows(false);
|
||||
|
||||
if (mat) {
|
||||
builder.material(0, mat->getDefaultInstance());
|
||||
}
|
||||
|
||||
builder.build(*_engine, renderable);
|
||||
|
||||
_scene->addEntity(renderable);
|
||||
|
||||
auto entityId = Entity::smuggle(renderable);
|
||||
|
||||
_geometry.emplace(entityId, geometry);
|
||||
|
||||
return entityId;
|
||||
}
|
||||
|
||||
} // namespace thermion_filament
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user