culling fixes for HighlightOverlay
This commit is contained in:
@@ -4,54 +4,62 @@
|
|||||||
|
|
||||||
#include "SceneManager.hpp"
|
#include "SceneManager.hpp"
|
||||||
|
|
||||||
namespace thermion_filament {
|
namespace thermion_filament
|
||||||
|
{
|
||||||
|
|
||||||
SceneManager::HighlightOverlay::HighlightOverlay(
|
SceneManager::HighlightOverlay::HighlightOverlay(
|
||||||
EntityId entityId,
|
EntityId entityId,
|
||||||
SceneManager* const sceneManager,
|
SceneManager *const sceneManager,
|
||||||
Engine* engine,
|
Engine *engine,
|
||||||
float r,
|
float r,
|
||||||
float g,
|
float g,
|
||||||
float b) : _sceneManager(sceneManager), _engine(engine) {
|
float b) : _sceneManager(sceneManager), _engine(engine)
|
||||||
|
{
|
||||||
auto& rm = engine->getRenderableManager();
|
|
||||||
|
auto &rm = engine->getRenderableManager();
|
||||||
auto& tm = engine->getTransformManager();
|
|
||||||
|
auto &tm = engine->getTransformManager();
|
||||||
|
|
||||||
// Create the outline/highlight material instance
|
// Create the outline/highlight material instance
|
||||||
filament::gltfio::MaterialKey dummyKey; // We're not using the key for this simple material
|
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
|
filament::gltfio::UvMap dummyUvMap; // We're not using UV mapping for this simple material
|
||||||
|
|
||||||
auto materialProvider = sceneManager->unlitMaterialProvider();
|
auto materialProvider = sceneManager->unlitMaterialProvider();
|
||||||
|
|
||||||
_highlightMaterialInstance = materialProvider->createMaterialInstance(&dummyKey, &dummyUvMap);
|
_highlightMaterialInstance = materialProvider->createMaterialInstance(&dummyKey, &dummyUvMap);
|
||||||
|
_highlightMaterialInstance->setDoubleSided(false);
|
||||||
_highlightMaterialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
_highlightMaterialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
||||||
_highlightMaterialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::KEEP);
|
_highlightMaterialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::KEEP);
|
||||||
_highlightMaterialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::KEEP);
|
_highlightMaterialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::REPLACE);
|
||||||
_highlightMaterialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::NE);
|
_highlightMaterialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::NE);
|
||||||
_highlightMaterialInstance->setStencilReferenceValue(1);
|
_highlightMaterialInstance->setStencilReferenceValue(1);
|
||||||
_highlightMaterialInstance->setParameter("color", filament::math::float3 { r, g, b });
|
|
||||||
_highlightMaterialInstance->setParameter("scale", 1.05f);
|
_highlightMaterialInstance->setParameter("color", filament::math::float3{r, g, b});
|
||||||
|
_highlightMaterialInstance->setParameter("scale", 1.04f);
|
||||||
|
_highlightMaterialInstance->setCullingMode(filament::backend::CullingMode::FRONT);
|
||||||
|
|
||||||
|
|
||||||
auto scene = sceneManager->getScene();
|
auto scene = sceneManager->getScene();
|
||||||
|
|
||||||
_isGeometryEntity = sceneManager->isGeometryEntity(entityId);
|
_isGeometryEntity = sceneManager->isGeometryEntity(entityId);
|
||||||
_isGltfAsset = sceneManager->isGltfAsset(entityId);
|
_isGltfAsset = sceneManager->isGltfAsset(entityId);
|
||||||
|
|
||||||
if(!(_isGeometryEntity || _isGltfAsset)) {
|
if (!(_isGeometryEntity || _isGltfAsset))
|
||||||
|
{
|
||||||
Log("Failed to set stencil outline for entity %d: the entity is a child of another entity. "
|
Log("Failed to set stencil outline for entity %d: the entity is a child of another entity. "
|
||||||
"Currently, we only support outlining top-level entities."
|
"Currently, we only support outlining top-level entities."
|
||||||
"Call getAncestor() to get the ancestor of this entity, then set on that", entityId);
|
"Call getAncestor() to get the ancestor of this entity, then set on that",
|
||||||
|
entityId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_isGeometryEntity) {
|
if (_isGeometryEntity)
|
||||||
|
{
|
||||||
|
|
||||||
Log("Entity %d is geometry", entityId);
|
Log("Entity %d is geometry", entityId);
|
||||||
|
|
||||||
auto geometryEntity = Entity::import(entityId);
|
auto geometryEntity = Entity::import(entityId);
|
||||||
auto renderable = rm.getInstance(geometryEntity);
|
auto renderable = rm.getInstance(geometryEntity);
|
||||||
|
|
||||||
auto materialInstance = rm.getMaterialInstanceAt(renderable, 0);
|
auto materialInstance = rm.getMaterialInstanceAt(renderable, 0);
|
||||||
|
|
||||||
@@ -60,37 +68,40 @@ namespace thermion_filament {
|
|||||||
materialInstance->setDepthWrite(true);
|
materialInstance->setDepthWrite(true);
|
||||||
materialInstance->setStencilReferenceValue(1);
|
materialInstance->setStencilReferenceValue(1);
|
||||||
materialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
materialInstance->setStencilOpStencilFail(filament::backend::StencilOperation::KEEP);
|
||||||
materialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::REPLACE);
|
materialInstance->setStencilOpDepthFail(filament::backend::StencilOperation::KEEP);
|
||||||
materialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::REPLACE);
|
materialInstance->setStencilOpDepthStencilPass(filament::backend::StencilOperation::KEEP);
|
||||||
materialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::A);
|
materialInstance->setStencilCompareFunction(filament::backend::SamplerCompareFunc::A);
|
||||||
|
// materialInstance->setCullingMode(filament::MaterialInstance::CullingMode::BACK);
|
||||||
|
|
||||||
auto geometry = sceneManager->getGeometry(entityId);
|
auto geometry = sceneManager->getGeometry(entityId);
|
||||||
|
|
||||||
_entity = utils::EntityManager::get().create();
|
_entity = utils::EntityManager::get().create();
|
||||||
RenderableManager::Builder builder(1);
|
RenderableManager::Builder builder(1);
|
||||||
builder.boundingBox(geometry->getBoundingBox())
|
builder.boundingBox(geometry->getBoundingBox())
|
||||||
.geometry(0, geometry->primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, geometry->numIndices)
|
.geometry(0, geometry->primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, geometry->numIndices)
|
||||||
.culling(true)
|
.culling(true)
|
||||||
.material(0, _highlightMaterialInstance)
|
.material(0, _highlightMaterialInstance)
|
||||||
.receiveShadows(false)
|
.priority(0)
|
||||||
.castShadows(false);
|
.receiveShadows(false)
|
||||||
|
.castShadows(false);
|
||||||
|
|
||||||
builder.build(*engine, _entity);
|
builder.build(*engine, _entity);
|
||||||
|
|
||||||
scene->addEntity(_entity);
|
scene->addEntity(_entity);
|
||||||
auto outlineTransformInstance = tm.getInstance(_entity);
|
auto outlineTransformInstance = tm.getInstance(_entity);
|
||||||
auto entityTransformInstance = tm.getInstance(geometryEntity);
|
auto entityTransformInstance = tm.getInstance(geometryEntity);
|
||||||
tm.setParent(outlineTransformInstance, entityTransformInstance);
|
tm.setParent(outlineTransformInstance, entityTransformInstance);
|
||||||
} else if(_isGltfAsset) {
|
}
|
||||||
|
else if (_isGltfAsset)
|
||||||
|
{
|
||||||
Log("Entity %d is gltf", entityId);
|
Log("Entity %d is gltf", entityId);
|
||||||
auto *asset = sceneManager->getAssetByEntityId(entityId);
|
auto *asset = sceneManager->getAssetByEntityId(entityId);
|
||||||
|
|
||||||
if (asset)
|
if (asset)
|
||||||
{
|
{
|
||||||
|
|
||||||
Log("Found glTF FilamentAsset with %d material instances", asset->getInstance()->getMaterialInstanceCount());
|
Log("Found glTF FilamentAsset with %d material instances", asset->getInstance()->getMaterialInstanceCount());
|
||||||
|
|
||||||
|
|
||||||
auto materialInstance = asset->getInstance()->getMaterialInstances()[0];
|
auto materialInstance = asset->getInstance()->getMaterialInstances()[0];
|
||||||
|
|
||||||
// set stencil write on the existing material
|
// set stencil write on the existing material
|
||||||
@@ -108,55 +119,66 @@ namespace thermion_filament {
|
|||||||
|
|
||||||
auto newTransformInstance = tm.getInstance(_entity);
|
auto newTransformInstance = tm.getInstance(_entity);
|
||||||
|
|
||||||
auto entityTransformInstance = tm.getInstance(asset->getRoot());
|
auto entityTransformInstance = tm.getInstance(asset->getRoot());
|
||||||
tm.setParent(newTransformInstance, entityTransformInstance);
|
tm.setParent(newTransformInstance, entityTransformInstance);
|
||||||
if(!_newInstance) {
|
if (!_newInstance)
|
||||||
|
{
|
||||||
Log("Couldn't create new instance");
|
Log("Couldn't create new instance");
|
||||||
} else {
|
}
|
||||||
for(int i = 0; i < _newInstance->getEntityCount(); i++) {
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _newInstance->getEntityCount(); i++)
|
||||||
|
{
|
||||||
auto entity = _newInstance->getEntities()[i];
|
auto entity = _newInstance->getEntities()[i];
|
||||||
auto renderableInstance = rm.getInstance(entity);
|
auto renderableInstance = rm.getInstance(entity);
|
||||||
rm.setPriority(renderableInstance, 7);
|
rm.setPriority(renderableInstance, 7);
|
||||||
if(renderableInstance.isValid()) {
|
if (renderableInstance.isValid())
|
||||||
for(int primitiveIndex = 0; primitiveIndex < rm.getPrimitiveCount(renderableInstance); primitiveIndex++) {
|
{
|
||||||
|
for (int primitiveIndex = 0; primitiveIndex < rm.getPrimitiveCount(renderableInstance); primitiveIndex++)
|
||||||
|
{
|
||||||
rm.setMaterialInstanceAt(renderableInstance, primitiveIndex, _highlightMaterialInstance);
|
rm.setMaterialInstanceAt(renderableInstance, primitiveIndex, _highlightMaterialInstance);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log("Not renderable, ignoring");
|
Log("Not renderable, ignoring");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scene->addEntities(_newInstance->getEntities(), _newInstance->getEntityCount());
|
scene->addEntities(_newInstance->getEntities(), _newInstance->getEntityCount());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log("Not FilamentAsset");
|
Log("Not FilamentAsset");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneManager::HighlightOverlay::~HighlightOverlay()
|
||||||
}
|
{
|
||||||
|
if (_entity.isNull())
|
||||||
SceneManager::HighlightOverlay::~HighlightOverlay() {
|
{
|
||||||
Log("Destructor");
|
Log("Null entity");
|
||||||
if (_entity.isNull()) {
|
return;
|
||||||
Log("Null entity");
|
}
|
||||||
return;
|
|
||||||
}
|
if (_isGltfAsset)
|
||||||
|
|
||||||
if (_isGltfAsset)
|
|
||||||
{
|
{
|
||||||
Log("Erasing new instance");
|
|
||||||
_sceneManager->getScene()->removeEntities(_newInstance->getEntities(), _newInstance->getEntityCount());
|
_sceneManager->getScene()->removeEntities(_newInstance->getEntities(), _newInstance->getEntityCount());
|
||||||
_newInstance->detachMaterialInstances();
|
_newInstance->detachMaterialInstances();
|
||||||
_engine->destroy(_highlightMaterialInstance);
|
_engine->destroy(_highlightMaterialInstance);
|
||||||
} else if(_isGeometryEntity) {
|
}
|
||||||
Log("Erasing new geometry");
|
else if (_isGeometryEntity)
|
||||||
auto& tm = _engine->getTransformManager();
|
{
|
||||||
|
auto &tm = _engine->getTransformManager();
|
||||||
auto transformInstance = tm.getInstance(_entity);
|
auto transformInstance = tm.getInstance(_entity);
|
||||||
_sceneManager->getScene()->remove(_entity);
|
_sceneManager->getScene()->remove(_entity);
|
||||||
utils::EntityManager::get().destroy(_entity);
|
utils::EntityManager::get().destroy(_entity);
|
||||||
_engine->destroy(_entity);
|
_engine->destroy(_entity);
|
||||||
_engine->destroy(_highlightMaterialInstance);
|
_engine->destroy(_highlightMaterialInstance);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log("FATAL: Unknown highlight overlay entity type");
|
Log("FATAL: Unknown highlight overlay entity type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user