【Sceneform-EQR】通过filament(gltfio)加载gltf模型动画(Filament使用Animator)

Sceneform-EQR

简介

Sceneform-EQR是EQ基于sceneform(filament)扩展的一个用于安卓端的三维渲染器。

相关链接

Git仓库
码云
EQ-R相关文档

实现通过filament加载gltf模型动画

运行示例

注意

原录屏经过压缩,并转成gif。实际效果远优于gif图所展示。

在sceneform-eqr中使用

我在sceneform-eqr中对模型动画做了一层封装,简化了模型动画的使用。

示例

示例工程:Sceneform-EQR

关键类:GltfSampleScene.java

创建模型

之前的文档【Sceneform-EQR】使用EQ-R加载模型 ,已经详细介绍如何在场景(AR场景、普通三维场景)中加载一个模型,这里不再赘述。

主要是创建了一个Node对象,而下面的示例需要用到这个Node。

创建动画

在sceneform-eqr中,当执行Node#setRenderable(model)后,我们即可创建动画

其中,创建动画的代码示例如下:

java 复制代码
public void createAnimation(Node node){
    if (node.getRenderableInstance() == null) {
        return;
    }
    int animationCount = node.getRenderableInstance().getAnimationCount();
    if (animationCount > 0){
        //创建动画参数(这里主要设置周期)
        ARAnimationParameter parameter = new ARAnimationParameter();
        parameter.setDuration(6000L);//设置播放周期
        parameter.setRepeatMode(ARAnimationRepeatMode.INFINITE);//设置循环方式
        //创建默认动画
        ARAnimationModel animationModel = new ARAnimationModel(node);
        animationModel.createAnimation(parameter);
        //默认播放第一个索引的动画
        animationModel.setCurrentIndex(0);
        //播放动画
        animationModel.play();
    }
}

至此,若使用Sceneform-EQR,读取模型动画及加载的教程已结束。

后文将结合filament,详细介绍流程。


分界线


Filament调用解析

创建FilamentAsset

我们先看一段使用filament加载gltf模型的代码片段。

java 复制代码
loader = new AssetLoader(engine,newUbershaderProvider(filamentEngine),EntityManager.get());

FilamentAsset filamentAssets = loader.createAsset(gltfByteBuffer);

其中,gltfByteBuffer是通过InputStream读取gltf文件得到的Buffer对象。我们通过loader的createAsset方法,得到了filamentAssets对象。

获取FilamentAnimator

现在,我们从filamentAssets中获取FilamentAnimator,并用存入List。

复制代码
ArrayList<ModelAnimation> animations = new ArrayList<>();

//...省略其他代码

filamentAnimator = filamentAssets.getInstance().getAnimator();
animations = new ArrayList<>();
for (int i = 0; i < filamentAnimator.getAnimationCount(); i++) {
    animations.add(new    ModelAnimation(this,filamentAnimator.getAnimationName(i),     i,filamentAnimator.getAnimationDuration(i),getRenderable().getAnimationFrameRate()));
}

这里使用到的ModelAnimation,参考Sceneform-EQR中ModelAnimation.java

也可不使用ModelAnimation.java,与后续updateSkinning时对应上就行。

更新骨骼动画

在每一帧("doFrame")绘制前,执行updateSkinning。

复制代码
            // 更新蒙皮skinning
            if (updateAnimations(false)) {
                updateSkinning();
            }

updateAnimations(false)中,则是从之前的List中取出ModelAnimation,将其应用。代码片段如下:

这里的关键是ModelAnimation.java中采用了不同的单位计算TimePosition,因此是个不错的参考。

复制代码
    public boolean updateAnimations(boolean force) {
        boolean hasUpdate = false;
        for (int i = 0; i < getAnimationCount(); i++) {
            ModelAnimation animation = getAnimation(i);
            if (force || animation.isDirty()) {
                if (getFilamentAnimator() != null) {
                    getFilamentAnimator().applyAnimation(i, animation.getTimePosition());
                }
                animation.setDirty(false);
                hasUpdate = true;
            }
        }
        return hasUpdate;
    }

undateSkinning方法则是更新FilamentAnimator的骨骼动画

复制代码
    private void updateSkinning() {
        if (getFilamentAnimator() != null) {
            getFilamentAnimator().updateBoneMatrices();
        }
    }

综上所述

若要在filament中使用3D模型自身的动画,需要通过FilamentAssets获取Animator对象,然后在每一帧绘制前,调用applyAnimation以修改当前进度值,然后再updateBoneMatrices即可。

当然,使用Sceneform-EQR,是最简单的。当前Sceneform-EQR已适配最新的filament依赖(v1.53.4),并已开源,欢迎有缘人加入。若有其他使用问题,请在git讨论。

相关推荐
似霰1 小时前
安卓adb shell串口基础指令
android·adb
FIT2CLOUD飞致云2 小时前
问答页面支持拖拽和复制粘贴文件,MaxKB企业级AI助手v1.10.6 LTS版本发布
人工智能·开源
爱喝奶茶的企鹅2 小时前
Ethan独立开发产品日报 | 2025-04-24
人工智能·程序员·开源
少年、潜行3 小时前
【开源】STM32HAL库移植Arduino OneWire库驱动DS18B20和MAX31850
stm32·嵌入式硬件·开源·ds18b20·max31850
fatiaozhang95273 小时前
中兴云电脑W102D_晶晨S905X2_2+16G_mt7661无线_安卓9.0_线刷固件包
android·adb·电视盒子·魔百盒刷机·魔百盒固件
CYRUS_STUDIO4 小时前
Android APP 热修复原理
android·app·hotfix
鸿蒙布道师5 小时前
鸿蒙NEXT开发通知工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师5 小时前
鸿蒙NEXT开发网络相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
大耳猫5 小时前
【解决】Android Gradle Sync 报错 Could not read workspace metadata
android·gradle·android studio
ta叫我小白5 小时前
实现 Android 图片信息获取和 EXIF 坐标解析
android·exif·经纬度