filament icon indicating copy to clipboard operation
filament copied to clipboard

Manipulator for FilamentInstance

Open ThomasGorisse opened this issue 3 years ago • 6 comments

Do you planed any Gesture detection on Asset Entities instead of only on Camera ?

ThomasGorisse avatar Mar 19 '21 10:03 ThomasGorisse

Hi Thomas, this is not something we are planning for right now. Can you be more specific about the feature request?

By the way, thank you for your work in the open source community!

prideout avatar Mar 19 '21 16:03 prideout

Hi Philip,

Concretely, it will be great to have GestureDetectors on the SurfaceView which apply translations, scales, and rotations to a FilamentInstane based on it BoundingBox directly in filament-utils-android

Thanks for your work too. I don't have a lot of time for maintaining a version of my Sceneform fork this times because I'm near to release a fresh new, from scratch, Kotlin, ARCore/Filament module much more like RealityKit.

Entities management are directly delegated to the Filament enties via the original Builders/Loaders. Mostly thanks to typealias Enity = Int and typealias EnityInstance = Int and some extensions coming around it. The only class I have to wrap is the Scene since there is no getEntities() function available on it and the constructor is private.

Speaking about it, is there any enhancements on the FilamentInstance creation from a FilamentAsset after a first call to get a finished number of instances?

I let you know when the new framework is online.

Have a good day.

ThomasGorisse avatar Mar 19 '21 19:03 ThomasGorisse

Thanks Thomas, I think I understand your manipulator feature request.

Also, I think we could add a getEntities to Scene if that makes your life easier.

I did not quite understand the question about "finished number of instances". Are you referring the asynchronous loading functionality in ResourceLoader? The resources that it loads are shared amongst instances.

@romainguy might be interested in your Kotlin toolkit, sounds cool.

prideout avatar Mar 22 '21 15:03 prideout

Hi Philip,

Also, I think we could add a getEntities to Scene if that makes your life easier.

That's would be great !!! And even more if we can get entities by type.

For this:

I did not quite understand the question about "finished number of instances". Are you referring the asynchronous loading functionality in ResourceLoader? The resources that it loads are shared amongst instances.

I was talking about this part of the AssetLoader:

 /**
  * Consumes the contents of a glTF 2.0 file and produces a primary asset with one or more
  * instances.
  *
  * The given instance array must be sized to the desired number of instances. If successful,
  * this method will populate the array with secondary instances whose resources are shared with
  * the primary asset.
  */
 @Nullable
 @SuppressWarnings("unused")
 public FilamentAsset createInstancedAsset(@NonNull Buffer buffer,
         @NonNull FilamentInstance[] instances) {
     long[] nativeInstances = new long[instances.length];
     long nativeAsset = nCreateInstancedAsset(mNativeObject, buffer, buffer.remaining(),
             nativeInstances);
     if (nativeAsset == 0) {
         return null;
     }
     for (int i = 0; i < nativeInstances.length; i++) {
         instances[i] = new FilamentInstance(nativeInstances[i]);
     }
     return new FilamentAsset(mEngine, nativeAsset);
 }

 /**
  * Adds a new instance to an instanced asset.
  *
  * Use this with caution. It is more efficient to pre-allocate a max number of instances, and
  * gradually add them to the scene as needed. Instances can also be "recycled" by removing and
  * re-adding them to the scene.
  *
  * NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
  * entity lists and instance lists, which would be slow to shift. We also wish to discourage
  * create/destroy churn, as noted above.
  *
  * This cannot be called after FilamentAsset#releaseSourceData().
  * This cannot be called on a non-instanced asset.
  * Animation is not supported in new instances.
  * See also AssetLoader#createInstancedAsset().
  */
 @Nullable
 @SuppressWarnings("unused")
 public FilamentInstance createInstance(@NonNull FilamentAsset asset) {
     long nativeInstance = nCreateInstance(mNativeObject, asset.getNativeObject());
     if (nativeInstance == 0) {
         return null;
     }
     return new FilamentInstance(nativeInstance);
 }

My problem is manly based on the fact that on an AR context, developers may not know how much FilamentInstance will the user add to the Scene.

Here is my current implementation:

fun loadGlb(buffer: Buffer): FilamentAsset? {
    val instances = arrayOfNulls<FilamentInstance>(CACHED_INSTANCES_SIZE)
    return assetLoader.createInstancedAsset(buffer, instances)?.also { asset ->
        resourceLoader.asyncBeginLoad(asset)
        asset.cachedInstances = instances.filterNotNull().toMutableList()
        ResourceManager.handleAsset(asset)
    }
}

internal var FilamentAsset.cachedInstances: MutableList<FilamentInstance>? by extensionProperty(
    mutableListOf()
) { instances ->
    instances?.forEach { it.asset = this }
}

val FilamentAsset.instances: MutableList<FilamentInstance> by extensionProperty(mutableListOf())

fun FilamentAsset.createInstance(): FilamentInstance? =
    cachedInstances?.firstOrNull().also { cachedInstances?.remove(it) }
        ?: assetLoader.createInstance(
            this
        )

I'm a little bit afraid of this:

  • Use this with caution. It is more efficient to pre-allocate a max number of instances, and
  • gradually add them to the scene as needed. Instances can also be "recycled" by removing and
  • re-adding them to the scene.
  • NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
  • entity lists and instance lists, which would be slow to shift. We also wish to discourage
  • create/destroy churn, as noted above.
  • This cannot be called after FilamentAsset#releaseSourceData().
  • This cannot be called on a non-instanced asset.
  • Animation is not supported in new instances.

I cannot make a new call to assetLoader.createInstancedAsset(buffer, instances) when every cached FilamentInstance has been used since I will have to create a new FilamentAsset.

My last issue with this is that I can never make the call to asset.releaseSourceData()

Thanks

ThomasGorisse avatar Mar 22 '21 17:03 ThomasGorisse

That's would be great !!! And even more if we can get entities by type.

Note that entities can exist in several managers (i.e. have several types), so it's a bit tricky.

pixelflinger avatar Mar 24 '21 00:03 pixelflinger

Hi Filamen,

If you are interested, I started pushing a new ARCore/Filament SDK here : RealityCore

Mostly everything is ready and tested but I prefer checking and being sure everything is clean and well documented instead of pushing everything at one time. So I'll push the SDK files by files next coming days if you want to have a look.

ThomasGorisse avatar May 17 '21 12:05 ThomasGorisse

@pixelflinger since Thomas is doing a great job with his higher level library, I am guessing this is out of scope for us. Closing.

prideout avatar Nov 01 '22 18:11 prideout