From e80ea5eae26c88dc60af3f9892eeba9adf651cd3 Mon Sep 17 00:00:00 2001 From: Thomas Gorisse Date: Thu, 1 Sep 2022 20:22:44 +0200 Subject: [PATCH] Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and Scene.hasEntity() (#6007) * Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and scene.hasEntity() * Update RELEASE_NOTES.md * Fixes * Change getChildren to take a nullable array * Remove no params TransformManager.getChildren() * Update RELEASE_NOTES.md Co-authored-by: Ben Doherty Co-authored-by: Ben Doherty --- RELEASE_NOTES.md | 1 + .../filament-android/src/main/cpp/Scene.cpp | 8 +++++ .../src/main/cpp/TransformManager.cpp | 20 +++++++++++ .../com/google/android/filament/Scene.java | 10 ++++++ .../android/filament/TransformManager.java | 33 +++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 429beeb3b2..abbf022197 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,7 @@ A new header is inserted each time a *tag* is created. ## main branch +- Java: add methods for TransformManager.getChildCount(), TransformManager.getChildren() and Scene.hasEntity() - engine: Fix stencil buffer writes with OpenGL backend. ## v1.27.0 diff --git a/android/filament-android/src/main/cpp/Scene.cpp b/android/filament-android/src/main/cpp/Scene.cpp index 5f98a4cf4f..25e6be09ba 100644 --- a/android/filament-android/src/main/cpp/Scene.cpp +++ b/android/filament-android/src/main/cpp/Scene.cpp @@ -83,3 +83,11 @@ Java_com_google_android_filament_Scene_nGetLightCount(JNIEnv *env, jclass type, Scene* scene = (Scene*) nativeScene; return (jint) scene->getLightCount(); } + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Scene_nHasEntity(JNIEnv *env, jclass type, jlong nativeScene, + jint entityId) { + Scene* scene = (Scene*) nativeScene; + Entity entity = Entity::import(entityId); + return (jboolean) scene->hasEntity(entity); +} diff --git a/android/filament-android/src/main/cpp/TransformManager.cpp b/android/filament-android/src/main/cpp/TransformManager.cpp index 484c711e00..8ddcae0dbd 100644 --- a/android/filament-android/src/main/cpp/TransformManager.cpp +++ b/android/filament-android/src/main/cpp/TransformManager.cpp @@ -110,6 +110,26 @@ Java_com_google_android_filament_TransformManager_nGetParent(JNIEnv*, jclass, return tm->getParent((TransformManager::Instance) i).getId(); } +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_TransformManager_nGetChildCount(JNIEnv*, jclass, + jlong nativeTransformManager, jint i) { + TransformManager* tm = (TransformManager*) nativeTransformManager; + return tm->getChildCount((TransformManager::Instance) i); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_TransformManager_nGetChildren(JNIEnv* env, + jclass, jlong nativeTransformManager, jint i, + jintArray outEntities_, jint count) { + TransformManager* tm = (TransformManager*) nativeTransformManager; + jint* entities = env->GetIntArrayElements(outEntities_, nullptr); + // This is very very gross, we just pretend Entity is just like an jint + // (which it is), but still. + tm->getChildren((TransformManager::Instance) i, + reinterpret_cast(entities), (size_t) count); + env->ReleaseIntArrayElements(outEntities_, entities, JNI_ABORT); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env, jclass, jlong nativeTransformManager, jint i, diff --git a/android/filament-android/src/main/java/com/google/android/filament/Scene.java b/android/filament-android/src/main/java/com/google/android/filament/Scene.java index e7036de651..283b7024e7 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Scene.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Scene.java @@ -163,6 +163,15 @@ public class Scene { return nGetLightCount(getNativeObject()); } + /** + * Returns true if the given entity is in the Scene. + * + * @return Whether the given entity is in the Scene. + */ + public boolean hasEntity(@Entity int entity) { + return nHasEntity(getNativeObject(), entity); + } + public long getNativeObject() { if (mNativeObject == 0) { throw new IllegalStateException("Calling method on destroyed Scene"); @@ -182,4 +191,5 @@ public class Scene { private static native void nRemoveEntities(long nativeScene, int[] entities); private static native int nGetRenderableCount(long nativeScene); private static native int nGetLightCount(long nativeScene); + private static native boolean nHasEntity(long nativeScene, int entity); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java b/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java index 7f319b56a3..c3cefba985 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java +++ b/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java @@ -16,6 +16,7 @@ package com.google.android.filament; +import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Size; @@ -199,6 +200,36 @@ import androidx.annotation.Size; return nGetParent(mNativeObject, i); } + /** + * Returns the number of children of an {@link EntityInstance}. + * + * @param i the {@link EntityInstance} of the transform component to query. + * @return The number of children of the queried component. + */ + public int getChildCount(@EntityInstance int i) { + return nGetChildCount(mNativeObject, i); + } + + /** + * Gets a list of children for a transform component. + * + * @param i the {@link EntityInstance} of the transform component to get the children + * from. + * @param outEntities array to receive the result sized to the maximum number of children to + * retrieve. If null is given, a new suitable array sized to + * {@link #getChildCount(int)} is allocated. + * @return Array of retrieved children {@link Entity}. + */ + public @Entity @NonNull int[] getChildren(@EntityInstance int i, @Nullable int[] outEntities) { + if (outEntities == null) { + outEntities = new int[getChildCount(i)]; + } + if (outEntities.length > 0) { + nGetChildren(mNativeObject, i, outEntities, outEntities.length); + } + return outEntities; + } + /** * Sets a local transform of a transform component. *

This operation can be slow if the hierarchy of transform is too deep, and this @@ -360,6 +391,8 @@ import androidx.annotation.Size; private static native void nDestroy(long nativeTransformManager, int entity); private static native void nSetParent(long nativeTransformManager, int i, int newParent); private static native int nGetParent(long nativeTransformManager, int i); + private static native int nGetChildCount(long nativeTransformManager, int i); + private static native void nGetChildren(long nativeEntityManager, int i, int[] outEntities, int count); private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform); private static native void nSetTransformFp64(long nativeTransformManager, int i, double[] localTransform); private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);