rename numInstances to initialInstances in loadGltf methods.
when initialInstances > 0, don't wait for createInstance to be called to create corresponding GltfSceneAsset
This commit is contained in:
@@ -890,7 +890,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
Future<ThermionAsset> loadGltfFromBuffer(
|
Future<ThermionAsset> loadGltfFromBuffer(
|
||||||
Uint8List data, Pointer animationManager,
|
Uint8List data, Pointer animationManager,
|
||||||
{int numInstances = 1,
|
{int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
@@ -914,7 +914,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
var filamentAsset = await withPointerCallback<TFilamentAsset>((cb) =>
|
||||||
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader,
|
GltfAssetLoader_loadRenderThread(engine, gltfAssetLoader,
|
||||||
data.address, data.length, numInstances, cb));
|
data.address, data.length, initialInstances, cb));
|
||||||
|
|
||||||
if (filamentAsset == nullptr) {
|
if (filamentAsset == nullptr) {
|
||||||
throw Exception("An error occurred loading the asset");
|
throw Exception("An error occurred loading the asset");
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:thermion_dart/src/filament/src/interface/scene.dart';
|
|||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
export 'geometry.dart';
|
export 'geometry.dart';
|
||||||
export 'gltf.dart';
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A high-level interface for a renderable object
|
/// A high-level interface for a renderable object
|
||||||
|
|||||||
@@ -291,11 +291,11 @@ abstract class FilamentApp<T> {
|
|||||||
Future setClearOptions(double r, double g, double b, double a,
|
Future setClearOptions(double r, double g, double b, double a,
|
||||||
{int clearStencil = 0, bool discard = false, bool clear = true});
|
{int clearStencil = 0, bool discard = false, bool clear = true});
|
||||||
|
|
||||||
///
|
/// See [FilamentViewerFFI.loadGltf] for details.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data, T animationManager,
|
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data, T animationManager,
|
||||||
{int numInstances = 1,
|
{int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
class GLTF {
|
|
||||||
final String uri;
|
|
||||||
final int numInstances;
|
|
||||||
|
|
||||||
GLTF(this.uri, this.numInstances);
|
|
||||||
}
|
|
||||||
@@ -457,7 +457,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future<ThermionAsset> loadGltf(
|
Future<ThermionAsset> loadGltf(
|
||||||
String path, {
|
String path, {
|
||||||
bool addToScene = true,
|
bool addToScene = true,
|
||||||
int numInstances = 1,
|
int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
String? resourceUri,
|
String? resourceUri,
|
||||||
bool loadAsync = false,
|
bool loadAsync = false,
|
||||||
@@ -475,7 +475,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
return loadGltfFromBuffer(
|
return loadGltfFromBuffer(
|
||||||
data,
|
data,
|
||||||
addToScene: addToScene,
|
addToScene: addToScene,
|
||||||
numInstances: numInstances,
|
initialInstances: initialInstances,
|
||||||
keepData: keepData,
|
keepData: keepData,
|
||||||
resourceUri: resourceUri,
|
resourceUri: resourceUri,
|
||||||
loadResourcesAsync: loadAsync,
|
loadResourcesAsync: loadAsync,
|
||||||
@@ -489,7 +489,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future<ThermionAsset> loadGltfFromBuffer(
|
Future<ThermionAsset> loadGltfFromBuffer(
|
||||||
Uint8List data, {
|
Uint8List data, {
|
||||||
bool addToScene = true,
|
bool addToScene = true,
|
||||||
int numInstances = 1,
|
int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
@@ -499,7 +499,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
var asset = await FilamentApp.instance!.loadGltfFromBuffer(
|
var asset = await FilamentApp.instance!.loadGltfFromBuffer(
|
||||||
data,
|
data,
|
||||||
animationManager,
|
animationManager,
|
||||||
numInstances: numInstances,
|
initialInstances: initialInstances,
|
||||||
keepData: keepData,
|
keepData: keepData,
|
||||||
priority: priority,
|
priority: priority,
|
||||||
layer: layer,
|
layer: layer,
|
||||||
|
|||||||
@@ -151,37 +151,38 @@ abstract class ThermionViewer {
|
|||||||
/// If [addToScene] is [true], all renderable entities (including lights)
|
/// If [addToScene] is [true], all renderable entities (including lights)
|
||||||
/// in the asset will be added to the scene.
|
/// in the asset will be added to the scene.
|
||||||
///
|
///
|
||||||
/// If you want to dynamically create instances of this asset after it is
|
/// The [initialInstances] argument determines the number of
|
||||||
/// instantiated, pass [kee]
|
/// instances created when the asset is first instantiated. If [keepData] is
|
||||||
|
/// false, no further instances will be able to be created.
|
||||||
/// Alternatively, specifying [numInstances] will pre-allocate the specified
|
///
|
||||||
/// number of instances. This is more efficient than dynamically instantating at a later time.
|
/// If [keepData] is true, additional instances can be created by calling
|
||||||
/// You can then retrieve the created instances with [getInstances].
|
/// [createInstance] on the returned asset.
|
||||||
///
|
///
|
||||||
/// If [keepData] is false and [numInstances] is 1,
|
/// Creating instances at asset load time is more efficient than dynamically
|
||||||
/// the source glTF data will be released and [createInstance]
|
/// instantating at a later time.
|
||||||
/// will throw an exception.
|
|
||||||
///
|
///
|
||||||
|
/// Instances can be retrieved with [getInstances].
|
||||||
|
///
|
||||||
|
/// If [loadResourcesAsync] is true, resources (textures, materials, etc) will
|
||||||
|
/// be loaded asynchronously. Some material/texture pop-in is expected.
|
||||||
///
|
///
|
||||||
Future<ThermionAsset> loadGltf(String uri,
|
Future<ThermionAsset> loadGltf(String uri,
|
||||||
{bool addToScene = true,
|
{bool addToScene = true,
|
||||||
int numInstances = 1,
|
int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
String? resourceUri,
|
String? resourceUri,
|
||||||
bool loadAsync = false});
|
bool loadAsync = false});
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Load the .glb asset from the specified buffer, adding all entities to the scene.
|
/// Loads a gltf asset from the specified buffer (which contains the contents
|
||||||
/// Specify [numInstances] to create multiple instances (this is more efficient than dynamically instantating at a later time). You can then retrieve the created instances with [getInstances].
|
/// of a .glb file).
|
||||||
/// If you want to be able to call [createInstance] at a later time, you must pass true for [keepData].
|
///
|
||||||
/// If [keepData] is false, the source glTF data will be released and [createInstance] will throw an exception.
|
/// See the [loadGltf] method for documentation on arguments.
|
||||||
/// If [loadResourcesAsync] is true, resources (textures, materials, etc) will
|
|
||||||
/// be loaded asynchronously (so expect some material/texture pop-in);
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data,
|
Future<ThermionAsset> loadGltfFromBuffer(Uint8List data,
|
||||||
{String? resourceUri,
|
{String? resourceUri,
|
||||||
int numInstances = 1,
|
int initialInstances = 1,
|
||||||
bool keepData = false,
|
bool keepData = false,
|
||||||
int priority = 4,
|
int priority = 4,
|
||||||
int layer = 0,
|
int layer = 0,
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ namespace thermion
|
|||||||
Engine *engine,
|
Engine *engine,
|
||||||
utils::NameComponentManager* ncm,
|
utils::NameComponentManager* ncm,
|
||||||
MaterialInstance **materialInstances = nullptr,
|
MaterialInstance **materialInstances = nullptr,
|
||||||
size_t materialInstanceCount = 0,
|
size_t materialInstanceCount = 0);
|
||||||
int instanceIndex = 0);
|
|
||||||
|
|
||||||
~GltfSceneAsset();
|
~GltfSceneAsset();
|
||||||
|
|
||||||
|
|||||||
@@ -33,15 +33,16 @@ namespace thermion
|
|||||||
Engine *engine,
|
Engine *engine,
|
||||||
utils::NameComponentManager* ncm,
|
utils::NameComponentManager* ncm,
|
||||||
MaterialInstance **materialInstances,
|
MaterialInstance **materialInstances,
|
||||||
size_t materialInstanceCount,
|
size_t materialInstanceCount) : _asset(asset),
|
||||||
int instanceIndex) : _asset(asset),
|
|
||||||
_assetLoader(assetLoader),
|
_assetLoader(assetLoader),
|
||||||
_engine(engine),
|
_engine(engine),
|
||||||
_ncm(ncm),
|
_ncm(ncm),
|
||||||
_materialInstances(materialInstances),
|
_materialInstances(materialInstances),
|
||||||
_materialInstanceCount(materialInstanceCount)
|
_materialInstanceCount(materialInstanceCount)
|
||||||
{
|
{
|
||||||
createInstance();
|
for(int i = 0; i < asset->getAssetInstanceCount(); i++) {
|
||||||
|
createInstance();
|
||||||
|
}
|
||||||
TRACE("Created GltfSceneAsset from FilamentAsset %d with %d reserved instances", asset, asset->getAssetInstanceCount());
|
TRACE("Created GltfSceneAsset from FilamentAsset %d with %d reserved instances", asset, asset->getAssetInstanceCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,11 +56,20 @@ void main() async {
|
|||||||
}, bg: kRed);
|
}, bg: kRed);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('gltf assets always create one instance', () async {
|
test('gltf assets are created with initialInstances instances', () async {
|
||||||
await testHelper.withViewer((viewer) async {
|
await testHelper.withViewer((viewer) async {
|
||||||
var asset =
|
var asset = await viewer.loadGltf(
|
||||||
await viewer.loadGltf("file://${testHelper.testDir}/assets/cube.glb");
|
"file://${testHelper.testDir}/assets/cube.glb",
|
||||||
|
initialInstances: 1);
|
||||||
expect(await asset.getInstanceCount(), 1);
|
expect(await asset.getInstanceCount(), 1);
|
||||||
|
|
||||||
|
asset = await viewer.loadGltf(
|
||||||
|
"file://${testHelper.testDir}/assets/cube.glb",
|
||||||
|
initialInstances: 2);
|
||||||
|
expect(await asset.getInstanceCount(), 2);
|
||||||
|
|
||||||
|
await expectLater(asset.createInstance(), throwsA(isA<Exception>()));
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,11 +86,12 @@ void main() async {
|
|||||||
var asset = await viewer.loadGltf(
|
var asset = await viewer.loadGltf(
|
||||||
"file://${testHelper.testDir}/assets/cube.glb",
|
"file://${testHelper.testDir}/assets/cube.glb",
|
||||||
addToScene: false,
|
addToScene: false,
|
||||||
numInstances: 2, keepData: true);
|
initialInstances: 2,
|
||||||
|
keepData: true);
|
||||||
var defaultInstance = await asset.getInstance(0);
|
var defaultInstance = await asset.getInstance(0);
|
||||||
await viewer.addToScene(defaultInstance);
|
await viewer.addToScene(defaultInstance);
|
||||||
await testHelper.capture(viewer.view, "gltf_without_instance");
|
await testHelper.capture(viewer.view, "gltf_without_instance");
|
||||||
|
|
||||||
var instance = await asset.createInstance();
|
var instance = await asset.createInstance();
|
||||||
await instance.setTransform(Matrix4.translation(Vector3(1, 0, 0)));
|
await instance.setTransform(Matrix4.translation(Vector3(1, 0, 0)));
|
||||||
await testHelper.capture(viewer.view, "gltf_instance_created");
|
await testHelper.capture(viewer.view, "gltf_instance_created");
|
||||||
@@ -91,13 +101,12 @@ void main() async {
|
|||||||
await testHelper.capture(viewer.view, "gltf_instance_remove_from_scene");
|
await testHelper.capture(viewer.view, "gltf_instance_remove_from_scene");
|
||||||
|
|
||||||
// above, we pre-allocated two instances and have used all of them
|
// above, we pre-allocated two instances and have used all of them
|
||||||
// calling createInstance now will still create another instance, but will be slower than allocating.
|
// calling createInstance now will still create another instance, but
|
||||||
|
// will be slower than specifying initialInstances on load.
|
||||||
var instance2 = await asset.createInstance();
|
var instance2 = await asset.createInstance();
|
||||||
await instance2.setTransform(Matrix4.translation(Vector3(-1, 0, 0)));
|
await instance2.setTransform(Matrix4.translation(Vector3(-1, 0, 0)));
|
||||||
await viewer.addToScene(instance2);
|
await viewer.addToScene(instance2);
|
||||||
await testHelper.capture(viewer.view, "gltf_instance2_add_to_scene");
|
await testHelper.capture(viewer.view, "gltf_instance2_add_to_scene");
|
||||||
|
|
||||||
|
|
||||||
}, addSkybox: true);
|
}, addSkybox: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user