реализация "io.github.sceneview:sceneview:2.3.3"
В моем проекте есть 3D-модель в виде файла .glb из Blender 4.5.6.
Этот файл содержит одного персонажа (риг и сетку) с тремя разными позами, каждая из которых анимирована и состоит из одного кадра.
Моя цель — отобразить желаемую позу в виде сцены.
По моим исследованиям, лучше всего манипулировать видом сцены с помощью Kotlin, поэтому моя активность Java вызывает функцию Kotlin для обработки отображения.
Вот Java код для моей деятельности:
Код: Выделить всё
package com.smk.monprojet;
import androidx.appcompat.app.AppCompatActivity; import
android.os.Bundle; import android.view.View; import
android.widget.ProgressBar;
import com.google.android.filament.EntityManager; import
com.google.android.filament.LightManager;
import io.github.sceneview.SceneView;
public class ModelViewerActivity extends AppCompatActivity {
private SceneView sceneView;
private ProgressBar progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_model_viewer);
sceneView = findViewById(R.id.sceneView);
progress = findViewById(R.id.progress);
// --- Éclairage directionnel (inchangé) ---
int lightEntity = EntityManager.get().create();
new LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(1.0f, 1.0f, 1.0f)
.intensity(100_000.0f)
.direction(0f, -1f, -1f)
.castShadows(true)
.build(sceneView.getEngine(), lightEntity);
sceneView.getScene().addEntity(lightEntity);
progress.setVisibility(View.VISIBLE);
try {
String animationNameToLoad = "pose_113";
String assetPathToLoad = "models/Modele3D.glb";
io.github.sceneview.node.ModelNode modelNode =
ModelLoaderHelper.displaySinglePose(
sceneView,
assetPathToLoad,
animationNameToLoad
);
} catch (Exception e) {
e.printStackTrace();
} finally {
progress.setVisibility(View.GONE);
}
}
@Override
protected void onDestroy() {
if (sceneView != null) {
sceneView.destroy(); // libère Filament/ressources GPU
}
super.onDestroy();
}
}
Основная функциональность находится в блоке Try: вызов функции Kotlin ModelLoaderHelper.displaySinglePose()
Вот мой файл Kotlin:
Код: Выделить всё
package com.smk.monprojet
import android.util.Log import
com.google.android.filament.gltfio.FilamentInstance import
dev.romainguy.kotlin.math.Float3 import
dev.romainguy.kotlin.math.length import
dev.romainguy.kotlin.math.lookAt import io.github.sceneview.SceneView
import io.github.sceneview.math.Position import
io.github.sceneview.math.toFloat3 import kotlin.math.tan
object ModelLoaderHelper {
@JvmStatic
fun displaySinglePose(
sceneView: SceneView,
assetPath: String,
animationName: String
): io.github.sceneview.node.ModelNode {
// 1️⃣ Charger l'instance GLB
val instance = sceneView.modelLoader.createModelInstance(assetPath)
// 2️⃣ Créer le ModelNode
val modelNode = io.github.sceneview.node.ModelNode(instance)
// 3️⃣ Ajouter à la scène
sceneView.addChildNode(modelNode)
// 4️⃣ Post pour attendre que le node soit attaché
sceneView.post {
val animator = instance.animator
if (animator != null) {
// Cherche l'index de l'animation par son nom
var animIndex = -1
for (i in 0 until animator.animationCount) {
if (animator.getAnimationName(i) == animationName) {
animIndex = i
break
}
}
if (animIndex != -1) {
// Applique la première frame
animator.applyAnimation(animIndex, 0f)
animator.updateBoneMatrices()
} else {
Log.e("SceneViewPose", "Animation '$animationName' introuvable")
}
} else {
Log.e("SceneViewPose", "Animator non disponible sur cette instance")
}
// 5️⃣ Caméra centrée et reculée
val box = modelNode.boundingBox
val center = box.center
val half = box.halfExtent
val centerX = center[0]
val centerY = center[1]
val centerZ = center[2]
val maxHalf = maxOf(half[0], half[1], half[2])
val distance = maxHalf * 2.5f
sceneView.cameraNode.position = dev.romainguy.kotlin.math.Float3(
centerX,
centerY + maxHalf,
centerZ + distance
)
sceneView.cameraNode.lookAt(
targetWorldPosition = dev.romainguy.kotlin.math.Float3(centerX, centerY, centerZ),
upDirection = dev.romainguy.kotlin.math.Float3(0f, 1f, 0f),
smooth = false,
smoothSpeed = 0f
)
}
return modelNode
}
}
- Поза не отображается, а модель всегда отображается в Т-позе. Однако файл GLB содержит все три позы. Я проверил это с помощью https://sandbox.babylonjs.com/ и https://gltf-viewer.donmccurdy.com/
- Камера отказывается позиционировать себя правильно. Он практически на уровне земли, едва перед персонажем (я вижу часть его ног крупным планом).
Подробнее здесь: https://stackoverflow.com/questions/798 ... sual-studi
Мобильная версия