Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asset loading #13

Merged
merged 76 commits into from
Mar 5, 2024
Merged

Asset loading #13

merged 76 commits into from
Mar 5, 2024

Conversation

hannojg
Copy link
Member

@hannojg hannojg commented Feb 26, 2024

Todo

  • iOS asset loading bridgen
  • Rename loadAsset in proxy to smth else
  • Clean up create indirect light function
  • Fix assets / resources not loading completely
  • Set camera focal length / point correctly

Changes

Goal of this PR is to make it possible to load assets and add them to the scene.
Note that we also need assets to load ktx files for lighting.

Right now the assets need to be bundled within the app's assets / bundle (there is no loading from JS code yet).

@hannojg hannojg changed the title [🚧 WIP] Asset loading Asset loading Feb 28, 2024
Base automatically changed from feat/first-render-api to main February 29, 2024 08:48
Comment on lines 59 to 63
// Allocate a *direct* ByteBuffer and put the bytes into it.
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
buffer.put(bytes);
// Reset position to 0 to be ready for reading
buffer.flip();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrousavy I had to do this for the buffer to work as I am using fbjni ByteBuffer implementation which only supports direct(?) buffers. And I think in this step I am copying the buffer again.
In general I am wondering whether I am doing this here the most efficient way (I doubt it). Would appreciate if you could take a stab at making this as copy-less as possible 😄

std::shared_ptr<FilamentBuffer> JFilamentProxy::getAssetByteBuffer(const std::string& path) {
static const auto method = javaClassLocal()->getMethod<jni::alias_ref<jni::JByteBuffer>(jni::alias_ref<jstring>)>("getAssetByteBuffer");
jni::local_ref<jni::JByteBuffer> localRef = method(_javaPart, jni::make_jstring(path));
jni::global_ref<jni::JByteBuffer> globalRef = jni::make_global(localRef);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memory leak!

return 13;
ByteBuffer getAssetByteBuffer(String assetName) throws IOException {
InputStream input = reactContext.getAssets().open(assetName);
byte[] bytes = new byte[input.available()];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allocates buffer twice!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I found a better solution for it, please have a look

@@ -24,6 +35,13 @@ EngineWrapper::EngineWrapper(std::shared_ptr<Choreographer> choreographer) {
_engine = References<Engine>::adoptRef(Engine::create(), [](Engine* engine) { Engine::destroy(&engine); });
_materialProvider = gltfio::createUbershaderProvider(_engine.get(), UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
_assetLoader = gltfio::AssetLoader::create(filament::gltfio::AssetConfiguration{.engine = _engine.get(), .materials = _materialProvider});
_resourceLoader = new filament::gltfio::ResourceLoader({.engine = _engine.get(), .normalizeSkinningWeights = true});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memory leak!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

References<T>::

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted _materialProvider, _assetLoader and _resourceLoader to be shared_ptrs using the references library now!

void EngineWrapper::createDefaultLight() {
// Create default directional light (In ModelViewer this is the default, so we use it here as well)
void EngineWrapper::loadAsset(std::shared_ptr<FilamentBuffer> modelBuffer) {
filament::gltfio::FilamentAsset* asset = _assetLoader->createAsset(modelBuffer->getData(), modelBuffer->getSize());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does cleanup work here? it's a pointer, does it need to be delete'd?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use the References I feel like we'd need a AdoptAssetLoader reference 🤔

Texture* cubemap = ktxreader::Ktx1Reader::createTexture(
_engine.get(), *iblBundle, false,
[](void* userdata) {
auto* bundle = (image::Ktx1Bundle*)userdata;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use dynamic_cast and check for null (sucessful cast)

buffer.put(bytes);
// Create a channel from the input stream
ReadableByteChannel channel = Channels.newChannel(input);
int estimatedSize = input.available(); // This is not always accurate for the actual size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what? 😄 you cannot estimate an array size - this needs to be the exact number.

hannojg and others added 2 commits March 5, 2024 13:24
>[!WARNING]
> Based on the following PR which should be merged first
> - #13

**Goal:**

To provide an API from JS that can be used to setup the scene and
control the transform of the elements.

(Most important) **Changes:**

- **Camera:**
- Renamed `lookAt` -> `lookAtCameraManipulator` Can be used to make
camera look at camera manipulator
- New `lookAt` function, which can be used to manually control the
position, target and up vector of the camera
- New `setLensProjection` & `setProjection` function to Control the lens
configuration from JS
- **⚠️ Note:** @mrousavy The user would also need to call this when the
surface size changes (as we need to pass the aspect ratio to this
function). Lets discuss in a quick meeting how to solve this best

- **Engine:**
- Renamed `createDefaultLight` -> `setIndirectLight`, only sets the
indirect light from an FilamentBuffer now (decouples the function from
setting a default directional light, which can be now configured by the
user)
- New `createLightEntity` Function to create a light with the
configuration you want
- Exposed `transformToUnitCube`. Pass an asset and it will transform the
asset to fit into a unit cube
- New `setEntityPosition`, `setEntityRotation` and `setEntityScale` to
set or update an entities transform
- `loadAsset` now returns a `FilamentAsset`. The asset can be used for
various operations in the scene.

---------

Co-authored-by: Marc Rousavy <me@mrousavy.com>
@mrousavy mrousavy merged commit 58984d7 into main Mar 5, 2024
mrousavy added a commit that referenced this pull request Mar 5, 2024
>[!WARNING]
> Based on the following PR which should be merged first
> - #13

**Goal:**

To provide an API from JS that can be used to setup the scene and
control the transform of the elements.

(Most important) **Changes:**

- **Camera:**
- Renamed `lookAt` -> `lookAtCameraManipulator` Can be used to make
camera look at camera manipulator
- New `lookAt` function, which can be used to manually control the
position, target and up vector of the camera
- New `setLensProjection` & `setProjection` function to Control the lens
configuration from JS
- **⚠️ Note:** @mrousavy The user would also need to call this when the
surface size changes (as we need to pass the aspect ratio to this
function). Lets discuss in a quick meeting how to solve this best

- **Engine:**
- Renamed `createDefaultLight` -> `setIndirectLight`, only sets the
indirect light from an FilamentBuffer now (decouples the function from
setting a default directional light, which can be now configured by the
user)
- New `createLightEntity` Function to create a light with the
configuration you want
- Exposed `transformToUnitCube`. Pass an asset and it will transform the
asset to fit into a unit cube
- New `setEntityPosition`, `setEntityRotation` and `setEntityScale` to
set or update an entities transform
- `loadAsset` now returns a `FilamentAsset`. The asset can be used for
various operations in the scene.

---------

Co-authored-by: Marc Rousavy <me@mrousavy.com>
mrousavy added a commit that referenced this pull request Mar 5, 2024
>[!WARNING]
> Based on the following PR which should be merged first
> - #13

**Goal:**

To provide an API from JS that can be used to setup the scene and
control the transform of the elements.

(Most important) **Changes:**

- **Camera:**
- Renamed `lookAt` -> `lookAtCameraManipulator` Can be used to make
camera look at camera manipulator
- New `lookAt` function, which can be used to manually control the
position, target and up vector of the camera
- New `setLensProjection` & `setProjection` function to Control the lens
configuration from JS
- **⚠️ Note:** @mrousavy The user would also need to call this when the
surface size changes (as we need to pass the aspect ratio to this
function). Lets discuss in a quick meeting how to solve this best

- **Engine:**
- Renamed `createDefaultLight` -> `setIndirectLight`, only sets the
indirect light from an FilamentBuffer now (decouples the function from
setting a default directional light, which can be now configured by the
user)
- New `createLightEntity` Function to create a light with the
configuration you want
- Exposed `transformToUnitCube`. Pass an asset and it will transform the
asset to fit into a unit cube
- New `setEntityPosition`, `setEntityRotation` and `setEntityScale` to
set or update an entities transform
- `loadAsset` now returns a `FilamentAsset`. The asset can be used for
various operations in the scene.

---------

---------

Co-authored-by: Hanno J. Gödecke <hanno@margelo.io>
Co-authored-by: Hanno J. Gödecke <die.drei99@yahoo.de>
hannojg added a commit that referenced this pull request Jun 19, 2024
>[!WARNING]
> Based on the following PR which should be merged first
> - #13

**Goal:**

To provide an API from JS that can be used to setup the scene and
control the transform of the elements.

(Most important) **Changes:**

- **Camera:**
- Renamed `lookAt` -> `lookAtCameraManipulator` Can be used to make
camera look at camera manipulator
- New `lookAt` function, which can be used to manually control the
position, target and up vector of the camera
- New `setLensProjection` & `setProjection` function to Control the lens
configuration from JS
- **⚠️ Note:** @mrousavy The user would also need to call this when the
surface size changes (as we need to pass the aspect ratio to this
function). Lets discuss in a quick meeting how to solve this best

- **Engine:**
- Renamed `createDefaultLight` -> `setIndirectLight`, only sets the
indirect light from an FilamentBuffer now (decouples the function from
setting a default directional light, which can be now configured by the
user)
- New `createLightEntity` Function to create a light with the
configuration you want
- Exposed `transformToUnitCube`. Pass an asset and it will transform the
asset to fit into a unit cube
- New `setEntityPosition`, `setEntityRotation` and `setEntityScale` to
set or update an entities transform
- `loadAsset` now returns a `FilamentAsset`. The asset can be used for
various operations in the scene.

---------

Co-authored-by: Marc Rousavy <me@mrousavy.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants