Android: Google 灯丝 GLTF/GLB 模型未显示

Android: Google Filament GLTF/GLB model not displayed

我的问题是我正在尝试让 SurfaceView 显示 3D 模型,这只是整个应用程序布局的一小部分。该布局包括用于显示其他数据的多个视图;但是,一旦我创建 ModelViewerSurfaceView 就会消失。当我使用 Filament 版本 1.9.9 时,会显示布局,但像素化严重,似乎使其他布局元素消失。使用 v1.7.0,其他元素不会消失,但不会显示任何内容。

我在 Gradle 文件中使用以下版本:

implementation 'com.google.android.filament:filament-android:1.7.0'
implementation 'com.google.android.filament:filament-utils-android:1.7.0'
implementation 'com.google.android.filament:gltfio-android:1.7.0'

我有一个模型正在复制到 assets 文件夹,正如我在他们的 Kotlin 示例中看到的那样: https://github.com/google/filament/tree/main/android/samples/sample-gltf-viewer

这是我 Java 尝试加载从 Blender 导出的自定义 GLTF 2.0 模型:

import android.content.Context;
import androidx.constraintlayout.widget.ConstraintLayout;

import android.view.Choreographer;
import android.view.SurfaceView;

import com.google.android.filament.Engine;
import com.google.android.filament.utils.*;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class Model implements Choreographer.FrameCallback {

    static {
        Utils.INSTANCE.init();
    }

    private final String TAG = Model.class.getSimpleName();
    private Context context;
    private SurfaceView surfaceView;
    private ModelViewer modelViewer;
    private Engine engine;
    private Choreographer choreographer;
    private final String modelFilename = "models/modelTest.glb";

    @Override
    public void doFrame(long currentTime) {
        choreographer.postFrameCallback(this);
        modelViewer.render(currentTime);
    }

    public Model(Context context, ConstraintLayout layout) {

        this.context = context;
        choreographer = Choreographer.getInstance();

        surfaceView = new SurfaceView(context);
        layout.addView(surfaceView);
        engine = Engine.create();
        modelViewer = new ModelViewer(surfaceView, engine, null);
        loadModel(modelFilename);
        choreographer.postFrameCallback(this);
    }

    private void loadModel(String filepath) {
        try {
            InputStream buffer = context.getAssets().open(filepath);
            byte[] bytes = new byte[buffer.available()];
            buffer.read(bytes);
            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
            modelViewer.loadModelGlb(byteBuffer);
            modelViewer.transformToUnitCube(new Float3(0,0,0));
        }
        catch(IOException e) {

        }
    }

}

编辑 1:

这是使用 1.9.4 以上的任何版本时显示的内容。编舞循环使静态部分看起来像电视上的静态噪声。红色部分似乎是模型的一小部分。

我不久前通过制作 ModelViewer class 的副本并使用新的构造函数制作自定义 ModelViewer3D class 来解决这个问题,这很好解决方案,因为它使您可以比通常使用给定的 ModelViewer.

更好地控制选项

uiHelper isOpaque 字段需要设置为 false 以解决上述问题,并且对于表面视图的透明背景,渲染器需要重置清除选项(我做了一个单独的函数,如下所示)。

     constructor(surfaceView: SurfaceView, engine: Engine = Engine.create(), manipulator: Manipulator? = null, isOpaque: Boolean) : this(engine) {
        cameraManipulator = manipulator ?: Manipulator.Builder()
                .targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
                .viewport(surfaceView.width, surfaceView.height)
                .build(Manipulator.Mode.ORBIT)

        this.surfaceView = surfaceView
        gestureDetector = GestureDetector(surfaceView, cameraManipulator)
        displayHelper = DisplayHelper(surfaceView.context)
        uiHelper.isOpaque = isOpaque
        uiHelper.renderCallback = SurfaceCallback()
        uiHelper.attachTo(surfaceView)
        addDetachListener(surfaceView)
    }

    fun makeBackgroundTransparent() {
        val options = renderer.clearOptions
        options.clear = true
        renderer.clearOptions = options
    }

我也最终使用了这个版本的库,因为它当时是最新的:

    implementation 'com.google.android.filament:filament-android:1.9.9'
    implementation 'com.google.android.filament:filament-utils-android:1.9.9'
    implementation 'com.google.android.filament:gltfio-android:1.9.9'