gltfio: allow dynamic attach / detach for bones (#5601)
Sceneform allowed users to attach and detach bones, so this seems like a useful feature. Fixes #3075
This commit is contained in:
@@ -5,6 +5,9 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## main branch
|
||||
|
||||
- gltfio: support skinning with bones that do not belong to any scene
|
||||
- gltfio: add attachSkin / detachSkin method to FilamentAsset
|
||||
|
||||
## v1.23.0
|
||||
|
||||
- Normals on morphed models have been fixed (core Filament change)
|
||||
|
||||
@@ -340,3 +340,19 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv*
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
asset->releaseSourceData();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nAttachSkin(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jint targetEntity) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity target = Entity::import(targetEntity);
|
||||
asset->attachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nDetachSkin(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jint targetEntity) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity target = Entity::import(targetEntity);
|
||||
asset->detachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
@@ -241,17 +241,37 @@ public class FilamentAsset {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the given skin to the given node, which must have an associated mesh with
|
||||
* BONE_INDICES and BONE_WEIGHTS attributes.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
public void attachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
|
||||
nAttachSkin(getNativeObject(), skinIndex, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the given skin to the given node, which must have an associated mesh with
|
||||
* BONE_INDICES and BONE_WEIGHTS attributes.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
public void detachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
|
||||
nDetachSkin(getNativeObject(), skinIndex, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joint count at skin index in this asset.
|
||||
*/
|
||||
public int getJointCountAt(int skinIndex) {
|
||||
public int getJointCountAt(@IntRange(from = 0) int skinIndex) {
|
||||
return nGetJointCountAt(getNativeObject(), skinIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets joints at skin index in this asset.
|
||||
*/
|
||||
public @NonNull @Entity int[] getJointsAt(int skinIndex) {
|
||||
public @NonNull @Entity int[] getJointsAt(@IntRange(from = 0) int skinIndex) {
|
||||
int[] result = new int[getJointCountAt(skinIndex)];
|
||||
nGetJointsAt(getNativeObject(), skinIndex, result);
|
||||
return result;
|
||||
@@ -345,6 +365,9 @@ public class FilamentAsset {
|
||||
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
|
||||
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
|
||||
|
||||
private static native void nAttachSkin(long nativeAsset, int skinIndex, int entity);
|
||||
private static native void nDetachSkin(long nativeAsset, int skinIndex, int entity);
|
||||
|
||||
private static native void nGetBoundingBox(long nativeAsset, float[] box);
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
|
||||
@@ -238,6 +238,21 @@ public:
|
||||
*/
|
||||
const Entity* getJointsAt(size_t skinIndex) const noexcept;
|
||||
|
||||
/**
|
||||
* Attaches the given skin to the given node, which must have an associated mesh with
|
||||
* BONE_INDICES and BONE_WEIGHTS attributes.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
void attachSkin(size_t skinIndex, Entity target) noexcept;
|
||||
|
||||
/**
|
||||
* Detaches the given skin from the given node.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
void detachSkin(size_t skinIndex, Entity target) noexcept;
|
||||
|
||||
/**
|
||||
* Gets the morph target name at the given index in the given entity.
|
||||
*/
|
||||
|
||||
@@ -212,6 +212,10 @@ struct FFilamentAsset : public FilamentAsset {
|
||||
|
||||
const utils::Entity* getJointsAt(size_t skinIndex) const noexcept;
|
||||
|
||||
void attachSkin(size_t skinIndex, Entity target) noexcept;
|
||||
|
||||
void detachSkin(size_t skinIndex, Entity target) noexcept;
|
||||
|
||||
const char* getMorphTargetNameAt(utils::Entity entity, size_t targetIndex) const noexcept;
|
||||
|
||||
size_t getMorphTargetCountAt(utils::Entity entity) const noexcept;
|
||||
|
||||
@@ -120,6 +120,20 @@ const utils::Entity* FFilamentAsset::getJointsAt(size_t skinIndex) const noexcep
|
||||
return mSkins[skinIndex].joints.data();
|
||||
}
|
||||
|
||||
void FFilamentAsset::attachSkin(size_t skinIndex, Entity target) noexcept {
|
||||
if (UTILS_UNLIKELY(mSkins.size() <= skinIndex || target.isNull())) {
|
||||
return;
|
||||
}
|
||||
mSkins[skinIndex].targets.insert(target);
|
||||
}
|
||||
|
||||
void FFilamentAsset::detachSkin(size_t skinIndex, Entity target) noexcept {
|
||||
if (UTILS_UNLIKELY(mSkins.size() <= skinIndex || target.isNull())) {
|
||||
return;
|
||||
}
|
||||
mSkins[skinIndex].targets.erase(target);
|
||||
}
|
||||
|
||||
const char* FFilamentAsset::getMorphTargetNameAt(utils::Entity entity,
|
||||
size_t targetIndex) const noexcept {
|
||||
if (!mResourcesLoaded) {
|
||||
@@ -381,6 +395,14 @@ const utils::Entity* FilamentAsset::getJointsAt(size_t skinIndex) const noexcept
|
||||
return upcast(this)->getJointsAt(skinIndex);
|
||||
}
|
||||
|
||||
void FilamentAsset::attachSkin(size_t skinIndex, Entity target) noexcept {
|
||||
upcast(this)->attachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
void FilamentAsset::detachSkin(size_t skinIndex, Entity target) noexcept {
|
||||
upcast(this)->detachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
const char* FilamentAsset::getMorphTargetNameAt(utils::Entity entity,
|
||||
size_t targetIndex) const noexcept {
|
||||
return upcast(this)->getMorphTargetNameAt(entity, targetIndex);
|
||||
|
||||
3
web/filament-js/filament.d.ts
vendored
3
web/filament-js/filament.d.ts
vendored
@@ -584,6 +584,9 @@ export class gltfio$FilamentAsset {
|
||||
public popRenderable(): Entity;
|
||||
public getMaterialInstances(): Vector<MaterialInstance>;
|
||||
public getResourceUris(): Vector<string>;
|
||||
public getSkinNames(): Vector<string>;
|
||||
public attachSkin(skinIndex: number, entity: Entity): void;
|
||||
public detachSkin(skinIndex: number, entity: Entity): void;
|
||||
public getBoundingBox(): Aabb;
|
||||
public getName(entity: Entity): string;
|
||||
public getExtras(entity: Entity): string;
|
||||
|
||||
@@ -1803,6 +1803,17 @@ class_<FilamentAsset>("gltfio$FilamentAsset")
|
||||
return retval;
|
||||
}), allow_raw_pointers())
|
||||
|
||||
.function("getSkinNames", EMBIND_LAMBDA(std::vector<std::string>, (FilamentAsset* self), {
|
||||
std::vector<std::string> names(self->getSkinCount());
|
||||
for (size_t i = 0; i < names.size(); ++i) {
|
||||
names[i] = self->getSkinNameAt(i);
|
||||
}
|
||||
return names;
|
||||
}), allow_raw_pointers())
|
||||
|
||||
.function("attachSkin", &FilamentAsset::attachSkin)
|
||||
.function("detachSkin", &FilamentAsset::detachSkin)
|
||||
|
||||
.function("getBoundingBox", &FilamentAsset::getBoundingBox)
|
||||
.function("getName", EMBIND_LAMBDA(std::string, (FilamentAsset* self, utils::Entity entity), {
|
||||
return std::string(self->getName(entity));
|
||||
|
||||
Reference in New Issue
Block a user