move setStencilHighlight/removeStencilHighlight to Scene
This commit is contained in:
@@ -190,89 +190,6 @@ class FFIAsset extends ThermionAsset {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
@override
|
|
||||||
Future removeStencilHighlight() async {
|
|
||||||
throw UnimplementedError();
|
|
||||||
// if (_highlight != null) {
|
|
||||||
// SceneManager_removeFromScene(sceneManager, _highlight!.entity);
|
|
||||||
// final childEntities = await _highlight!.getChildEntities();
|
|
||||||
// for (final child in childEntities) {
|
|
||||||
// SceneManager_removeFromScene(sceneManager, child);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
@override
|
|
||||||
Future setStencilHighlight(
|
|
||||||
{double r = 1.0,
|
|
||||||
double g = 0.0,
|
|
||||||
double b = 0.0,
|
|
||||||
int? entityIndex}) async {
|
|
||||||
if (_highlight == null) {
|
|
||||||
var targetEntity = this.entity;
|
|
||||||
if (entityIndex != null) {
|
|
||||||
final childEntities = await this.getChildEntities();
|
|
||||||
targetEntity = childEntities[entityIndex];
|
|
||||||
}
|
|
||||||
var sourceMaterialInstance = FFIMaterialInstance(
|
|
||||||
RenderableManager_getMaterialInstanceAt(
|
|
||||||
app.renderableManager, targetEntity, 0),
|
|
||||||
app);
|
|
||||||
|
|
||||||
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
|
||||||
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
|
||||||
await sourceMaterialInstance
|
|
||||||
.setStencilOpDepthStencilPass(StencilOperation.REPLACE);
|
|
||||||
|
|
||||||
await sourceMaterialInstance.setStencilReferenceValue(1);
|
|
||||||
throw Exception("TODO");
|
|
||||||
// final materialInstancePtr =
|
|
||||||
// await withPointerCallback<TMaterialInstance>((cb) {
|
|
||||||
|
|
||||||
// MaterialProvider_createMaterialInstanceRenderThread(
|
|
||||||
// app.ubershaderMaterialProvider, , cb);
|
|
||||||
// });
|
|
||||||
// final highlightMaterialInstance =
|
|
||||||
// FFIMaterialInstance(materialInstancePtr, app);
|
|
||||||
// await highlightMaterialInstance
|
|
||||||
// .setStencilCompareFunction(SamplerCompareFunction.NE);
|
|
||||||
// await highlightMaterialInstance.setStencilReferenceValue(1);
|
|
||||||
|
|
||||||
// await highlightMaterialInstance.setDepthCullingEnabled(false);
|
|
||||||
|
|
||||||
// await highlightMaterialInstance.setParameterFloat4(
|
|
||||||
// "baseColorFactor", r, g, b, 1.0);
|
|
||||||
|
|
||||||
// var highlightInstance = await this
|
|
||||||
// .createInstance(materialInstances: [highlightMaterialInstance]);
|
|
||||||
// _highlight = highlightInstance;
|
|
||||||
|
|
||||||
// await highlightMaterialInstance.setStencilReferenceValue(1);
|
|
||||||
// RenderableManager_setPriority(app.renderableManager, targetEntity, 0);
|
|
||||||
|
|
||||||
// TransformManager_setParent(
|
|
||||||
// app.transformManager, _highlight!.entity, entity, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
var targetHighlightEntity = _highlight!.entity;
|
|
||||||
|
|
||||||
if (entityIndex != null) {
|
|
||||||
var highlightChildEntities = await _highlight!.getChildEntities();
|
|
||||||
targetHighlightEntity = highlightChildEntities[entityIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderableManager_setPriority(
|
|
||||||
app.renderableManager, targetHighlightEntity, 7);
|
|
||||||
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1177,4 +1177,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
}
|
}
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
@override
|
||||||
|
Future setPriority(ThermionEntity entity, int priority) async {
|
||||||
|
RenderableManager_setPriority(renderableManager, entity, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,70 @@ class FFIScene extends Scene {
|
|||||||
Future remove(covariant FFIAsset asset) async {
|
Future remove(covariant FFIAsset asset) async {
|
||||||
SceneAsset_removeFromScene(asset.asset, scene);
|
SceneAsset_removeFromScene(asset.asset, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _outlines = <ThermionAsset, FFIAsset>{};
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
@override
|
||||||
|
Future removeStencilHighlight(ThermionAsset asset) async {
|
||||||
|
if (_outlines.containsKey(asset)) {
|
||||||
|
final highlight = _outlines[asset]!;
|
||||||
|
await remove(highlight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
@override
|
||||||
|
Future setStencilHighlight(ThermionAsset asset,
|
||||||
|
{double r = 1.0,
|
||||||
|
double g = 0.0,
|
||||||
|
double b = 0.0,
|
||||||
|
int? entity,
|
||||||
|
int primitiveIndex = 0}) async {
|
||||||
|
entity ??= asset.entity;
|
||||||
|
|
||||||
|
if (!_outlines.containsKey(asset)) {
|
||||||
|
var sourceMaterialInstance =
|
||||||
|
await asset.getMaterialInstanceAt(entity: entity);
|
||||||
|
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
||||||
|
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
||||||
|
await sourceMaterialInstance
|
||||||
|
.setStencilOpDepthStencilPass(StencilOperation.REPLACE);
|
||||||
|
await sourceMaterialInstance
|
||||||
|
.setStencilCompareFunction(SamplerCompareFunction.A);
|
||||||
|
|
||||||
|
await sourceMaterialInstance
|
||||||
|
.setStencilReferenceValue(View.STENCIL_HIGHLIGHT_REFERENCE_VALUE);
|
||||||
|
|
||||||
|
var highlightMaterialInstance =
|
||||||
|
await FilamentApp.instance!.createUnlitMaterialInstance();
|
||||||
|
|
||||||
|
await highlightMaterialInstance
|
||||||
|
.setStencilCompareFunction(SamplerCompareFunction.NE);
|
||||||
|
await highlightMaterialInstance
|
||||||
|
.setStencilReferenceValue(View.STENCIL_HIGHLIGHT_REFERENCE_VALUE);
|
||||||
|
await highlightMaterialInstance.setDepthCullingEnabled(false);
|
||||||
|
await highlightMaterialInstance.setParameterFloat4(
|
||||||
|
"baseColorFactor", r, g, b, 1.0);
|
||||||
|
|
||||||
|
var highlightInstance = await asset
|
||||||
|
.createInstance(materialInstances: [highlightMaterialInstance]);
|
||||||
|
await add(highlightInstance as FFIAsset);
|
||||||
|
_outlines[asset] = highlightInstance as FFIAsset;
|
||||||
|
|
||||||
|
var transform = await FilamentApp.instance!
|
||||||
|
.getWorldTransform(highlightInstance.entity);
|
||||||
|
|
||||||
|
await FilamentApp.instance!.setTransform(highlightInstance.entity,
|
||||||
|
Matrix4.diagonal3(Vector3(1.1, 1.1, 1.1)) * transform);
|
||||||
|
|
||||||
|
await FilamentApp.instance!.setPriority(highlightInstance.entity, 7);
|
||||||
|
|
||||||
|
await FilamentApp.instance!.setParent(highlightInstance.entity, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,17 +87,6 @@ abstract class ThermionAsset {
|
|||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders an outline around [entity] with the given color.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
Future setStencilHighlight(
|
|
||||||
{double r = 1.0, double g = 0.0, double b = 0.0, int? entityIndex});
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes the outline around [entity]. Noop if there was no highlight.
|
|
||||||
///
|
|
||||||
Future removeStencilHighlight();
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The dimensions of the bounding box for this asset.
|
/// The dimensions of the bounding box for this asset.
|
||||||
/// This is independent of the boundingBoxAsset (which is used to visualize
|
/// This is independent of the boundingBoxAsset (which is used to visualize
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
abstract class Scene {
|
abstract class Scene {
|
||||||
|
|
||||||
/// Adds all renderable entities in [asset] to this scene.
|
/// Adds all renderable entities in [asset] to this scene.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future add(covariant ThermionAsset asset);
|
Future add(covariant ThermionAsset asset);
|
||||||
|
|
||||||
/// Adds [entity] to this scene (which is assumed to have a Renderable
|
/// Adds [entity] to this scene (which is assumed to have a Renderable
|
||||||
/// component).
|
/// component).
|
||||||
///
|
///
|
||||||
Future addEntity(ThermionEntity entity);
|
Future addEntity(ThermionEntity entity);
|
||||||
@@ -15,4 +14,19 @@ abstract class Scene {
|
|||||||
/// Removes all renderable entities in [asset] from this scene.
|
/// Removes all renderable entities in [asset] from this scene.
|
||||||
///
|
///
|
||||||
Future remove(covariant ThermionAsset asset);
|
Future remove(covariant ThermionAsset asset);
|
||||||
|
|
||||||
|
|
||||||
|
/// Renders an outline around [entity] with the given color.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future setStencilHighlight(ThermionAsset asset,{double r = 1.0,
|
||||||
|
double g = 0.0,
|
||||||
|
double b = 0.0,
|
||||||
|
int? entity,
|
||||||
|
int primitiveIndex = 0});
|
||||||
|
|
||||||
|
/// Removes the outline around [entity]. Noop if there was no highlight.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
Future removeStencilHighlight(ThermionAsset asset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ enum QualityLevel { LOW, MEDIUM, HIGH, ULTRA }
|
|||||||
|
|
||||||
abstract class View {
|
abstract class View {
|
||||||
|
|
||||||
|
static int STENCIL_HIGHLIGHT_REFERENCE_VALUE = 1;
|
||||||
|
|
||||||
/// Gets the scene currently associated with this View.
|
/// Gets the scene currently associated with this View.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -79,7 +81,7 @@ abstract class View {
|
|||||||
Future setShadowsEnabled(bool enabled);
|
Future setShadowsEnabled(bool enabled);
|
||||||
Future setLayerVisibility(VisibilityLayers layer, bool visible);
|
Future setLayerVisibility(VisibilityLayers layer, bool visible);
|
||||||
|
|
||||||
/// Sets the fog options for this view.
|
/// Sets the fog options for this view.
|
||||||
/// Fog is disabled by default
|
/// Fog is disabled by default
|
||||||
///
|
///
|
||||||
Future setFogOptions(FogOptions options);
|
Future setFogOptions(FogOptions options);
|
||||||
|
|||||||
@@ -592,8 +592,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setPriority(ThermionEntity entityId, int priority) async {
|
Future setPriority(ThermionEntity entity, int priority) async {
|
||||||
RenderableManager_setPriority(app.renderableManager, entityId, priority);
|
return FilamentApp.instance!.setPriority(entity, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void main() async {
|
|||||||
await mi.setStencilCompareFunction(
|
await mi.setStencilCompareFunction(
|
||||||
SamplerCompareFunction.N, StencilFace.FRONT_AND_BACK);
|
SamplerCompareFunction.N, StencilFace.FRONT_AND_BACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// should be totally empty
|
// should be totally empty
|
||||||
await testHelper.capture(viewer.view, "stencil_never");
|
await testHelper.capture(viewer.view, "stencil_never");
|
||||||
|
|
||||||
@@ -113,30 +113,30 @@ void main() async {
|
|||||||
|
|
||||||
// set the blue cube to always pass the stencil test
|
// set the blue cube to always pass the stencil test
|
||||||
await blueMaterialInstance.setStencilCompareFunction(
|
await blueMaterialInstance.setStencilCompareFunction(
|
||||||
SamplerCompareFunction.A, StencilFace.FRONT_AND_BACK);
|
SamplerCompareFunction.A, StencilFace.FRONT_AND_BACK);
|
||||||
// when blue cube passes depth + stencil, replace the default stencil value (0) with 1
|
// when blue cube passes depth + stencil, replace the default stencil value (0) with 1
|
||||||
await blueMaterialInstance.setStencilOpDepthStencilPass(StencilOperation.REPLACE);
|
await blueMaterialInstance
|
||||||
|
.setStencilOpDepthStencilPass(StencilOperation.REPLACE);
|
||||||
await blueMaterialInstance.setStencilReferenceValue(1);
|
await blueMaterialInstance.setStencilReferenceValue(1);
|
||||||
|
|
||||||
// set the green cube to only pass the stencil test where stencil value is
|
// set the green cube to only pass the stencil test where stencil value is
|
||||||
// not equal to 0
|
// not equal to 0
|
||||||
await greenMaterialInstance.setStencilCompareFunction(
|
await greenMaterialInstance.setStencilCompareFunction(
|
||||||
SamplerCompareFunction.NE, StencilFace.FRONT_AND_BACK);
|
SamplerCompareFunction.NE, StencilFace.FRONT_AND_BACK);
|
||||||
await greenMaterialInstance.setStencilReferenceValue(0);
|
await greenMaterialInstance.setStencilReferenceValue(0);
|
||||||
|
|
||||||
// green cube will only be rendered where it overlaps with blue cube
|
// green cube will only be rendered where it overlaps with blue cube
|
||||||
await testHelper.capture(viewer.view, "stencil_ne");
|
await testHelper.capture(viewer.view, "stencil_ne");
|
||||||
|
|
||||||
// set the green cube to only pass the stencil test where stencil value is
|
// set the green cube to only pass the stencil test where stencil value is
|
||||||
// equal to 0
|
// equal to 0
|
||||||
await greenMaterialInstance.setStencilCompareFunction(
|
await greenMaterialInstance.setStencilCompareFunction(
|
||||||
SamplerCompareFunction.E, StencilFace.FRONT_AND_BACK);
|
SamplerCompareFunction.E, StencilFace.FRONT_AND_BACK);
|
||||||
|
|
||||||
// green cube renders where it does not overlap with blue cube (same as if
|
// green cube renders where it does not overlap with blue cube (same as if
|
||||||
// we had disabled depth writes and rendered the green cube, then the blue
|
// we had disabled depth writes and rendered the green cube, then the blue
|
||||||
// cube)
|
// cube)
|
||||||
await testHelper.capture(viewer.view, "stencil_eq");
|
await testHelper.capture(viewer.view, "stencil_eq");
|
||||||
|
|
||||||
},
|
},
|
||||||
bg: null,
|
bg: null,
|
||||||
postProcessing: true,
|
postProcessing: true,
|
||||||
@@ -144,32 +144,5 @@ void main() async {
|
|||||||
createRenderTarget: false);
|
createRenderTarget: false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('fail stencil not equal', () async {
|
|
||||||
// await testHelper.withViewer((viewer) async {
|
|
||||||
// final (
|
|
||||||
// :blueCube,
|
|
||||||
// :blueMaterialInstance,
|
|
||||||
// :greenCube,
|
|
||||||
// :greenMaterialInstance
|
|
||||||
// ) = await setup(viewer);
|
|
||||||
|
|
||||||
// // this ensures the blue cube is rendered before the green cube
|
|
||||||
// await viewer.setPriority(blueCube.entity, 0);
|
|
||||||
// await viewer.setPriority(greenCube.entity, 1);
|
|
||||||
|
|
||||||
// await blueMaterialInstance.setStencilWriteEnabled(true);
|
|
||||||
// await blueMaterialInstance.setStencilReferenceValue(1);
|
|
||||||
// await blueMaterialInstance
|
|
||||||
// .setStencilCompareFunction(SamplerCompareFunction.A);
|
|
||||||
// await blueMaterialInstance
|
|
||||||
// .setStencilOpDepthStencilPass(StencilOperation.REPLACE);
|
|
||||||
|
|
||||||
// await greenMaterialInstance.setStencilReferenceValue(1);
|
|
||||||
// await greenMaterialInstance
|
|
||||||
// .setStencilCompareFunction(SamplerCompareFunction.E);
|
|
||||||
|
|
||||||
// // green cube is only rendered where it intersects with the blue cube
|
|
||||||
// await testHelper.capture(viewer.view, "fail_stencil_ne");
|
|
||||||
// }, postProcessing: true);
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|||||||
30
thermion_dart/test/scene_tests.dart
Normal file
30
thermion_dart/test/scene_tests.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'helpers.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
final testHelper = TestHelper("scene");
|
||||||
|
await testHelper.setup();
|
||||||
|
|
||||||
|
test('show stencil highlight', () async {
|
||||||
|
await testHelper.withViewer((viewer) async {
|
||||||
|
await viewer.view.setStencilBufferEnabled(true);
|
||||||
|
final cube = await viewer.createGeometry(
|
||||||
|
GeometryHelper.cube(
|
||||||
|
normals: true,
|
||||||
|
uvs: true,
|
||||||
|
),
|
||||||
|
keepData: true,
|
||||||
|
materialInstances: []);
|
||||||
|
|
||||||
|
await viewer.addToScene(cube);
|
||||||
|
|
||||||
|
final scene = await viewer.view.getScene();
|
||||||
|
await scene.setStencilHighlight(cube);
|
||||||
|
|
||||||
|
await testHelper.capture(viewer.view, "stencil_highlight");
|
||||||
|
await scene.removeStencilHighlight(cube);
|
||||||
|
await testHelper.capture(viewer.view, "stencil_highlight_removed");
|
||||||
|
}, createStencilBuffer: true);
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user