Android: Google 灯丝 GLTF/GLB 模型未显示
Android: Google Filament GLTF/GLB model not displayed
我的问题是我正在尝试让 SurfaceView
显示 3D 模型,这只是整个应用程序布局的一小部分。该布局包括用于显示其他数据的多个视图;但是,一旦我创建 ModelViewer
,SurfaceView
就会消失。当我使用 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'
我的问题是我正在尝试让 SurfaceView
显示 3D 模型,这只是整个应用程序布局的一小部分。该布局包括用于显示其他数据的多个视图;但是,一旦我创建 ModelViewer
,SurfaceView
就会消失。当我使用 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'