简介

图形引擎服务(Scene Kit)是华为面向开发者提供的高性能、低功耗、轻量级的3D图形渲染引擎服务,为开发者提供高级描述性API,便于编辑、操作和渲染3D资源。
图形引擎服务为开发者提供了场景化接口SDK与原子化接口SDK,您可根据使用场景的不同选择合适的SDK进行集成:

您将建立什么

跟随本篇Codelab您将学会如何快速集成图形引擎服务,并使用已经创建好的示例代码体验图形引擎服务在不同的使用场景提供的3D渲染能力。
通过示例代码您可以体验到:

您将学到什么

跟随本篇Codelab您将学会:

硬件要求

软件要求

需要的知识点

集成图形引擎服务需要按照以下流程完成开发准备:

  1. 创建AppGallery Connect应用
  2. 生成签名证书指纹
  3. 配置签名证书指纹
  4. 添加当前应用的AppGallery Connect配置文件
  5. 配置HMS Core SDK的Maven仓地址
  6. 添加编译依赖
  7. 配置混淆脚本
详情请参照开发准备

添加当前应用的AppGallery Connect配置文件

如果在AppGallery Connect中开通了相关服务则需要将"agconnect-services.json"文件添加到您的App中。
步骤 1 - 登录AppGallery Connect网站,点击"我的项目"。
步骤 2 - 在项目列表中找到您的项目,在项目中点击需要集成HMS Core SDK的应用。
步骤 3 - 在"项目设置 > 常规"页面的"应用"区域,点击"agconnect-services.json"下载配置文件。

步骤 4 - 将"agconnect-services.json"文件拷贝到应用级根目录下。

—-结束

配置HMS Core SDK的Maven仓地址

Android Studio的代码库配置在Gradle 插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle 插件版本,选择对应的配置过程。

7.0以下版本

7.0版本

7.1及以上版本

添加编译依赖

步骤 1 - 打开应用级的"build.gradle"文件。

步骤 2 - 在"dependencies" 中添加如下编译依赖。

—-结束

图形引擎服务对不同SDK提供了多个示例代码以供参考:

原子化接口SDK

RenderView示例代码

RenderView示例代码:hms-scene-fine-grained-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。

运行效果如下左图所示,点击"RENDERVIERW DEMO"按钮,渲染效果如下右图所示:

RenderView Demo渲染效果图中使用的渲染素材为Spinosaurus_animation,作者:seirogan,未进行修改,License:CC Attribution,详情请见CC Attribution
设置3D模型与环境贴图

private void loadModel() { Model.builder() // 可更换为其他3D模型资源。 .setUri(Uri.parse("Spinosaurus_animation/scene.gltf")) .load(this, new ModelLoadEventListener(new WeakReference<>(this))); } private void loadTextures() { Texture.builder() // 可更换为其他天空盒素材。 .setUri(Uri.parse("Forest/output_skybox.dds")) .load(this, new SkyBoxTextureLoadEventListener(new WeakReference<>(this))); Texture.builder() // 可更换为其他高光贴图,高光贴图需与天空盒素材匹配。 .setUri(Uri.parse("Forest/output_specular.dds")) .load(this, new SpecularEnvTextureLoadEventListener(new WeakReference<>(this))); Texture.builder() // 可更换为其他漫反射贴图,漫反射贴图需与天空盒素材匹配。 .setUri(Uri.parse("Forest/output_diffuse.dds")) .load(this, new DiffuseEnvTextureLoadEventListener(new WeakReference<>(this))); }

ARView与FaceView示例代码

ARView与FaceView示例代码:hms-scene-ar-face-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。

运行效果如下左图所示;点击"START ARVIERW DEMO"按钮,识别平面后点击放置3D模型,渲染效果如下中图所示;点击"START FACEVIERW DEMO"按钮,识别人脸后渲染效果如下右图所示:

ARView Demo渲染效果图中使用的渲染素材为Robo_OBJ_pose4,作者:Artem Shupa-Dubrova,未进行修改,License:CC Attribution-NoDerivs,详情请见CC Attribution-NoDerivs
ARView设置3D模型

private void loadAsset() { if (testModel != null) { return; } Model.builder() // 可更换为其他3D模型 .setUri(Uri.parse("Robot/scene.gltf")) .load(getApplicationContext(), new Resource.OnLoadEventListener<Model>() { @Override public void onLoaded(Model model) { Toast.makeText(ARViewActivity.this, "load success.", Toast.LENGTH_SHORT).show(); testModel = model; } @Override public void onException(Exception exception) { Toast.makeText(ARViewActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); } }); }

FaceView设置3D模型

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_face_detection); faceView = findViewById(R.id.container1); setupIBL(); // 可设置为其他3D素材。 AssetFeature beaverAsset = new AssetFeature("Fox/fox.glb", FaceLandmark.TIP_OF_NOSE); beaverAsset // 设置模型的初始位置、大小与角度。 .setOffsetPosition(new Vector3(0.0f, -0.1f, 0.0f)) .setInitialScale(new Vector3(0.01f, 0.01f, 0.01f)) .setOffsetRotation(new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0)); loadAsset(beaverAsset); }

物理引擎组件

物理引擎组件示例代码:hms-scene-physics-engine-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。

运行效果如下左图所示;点击"PHYSICS ENGINE DEMO 1"按钮,示例中模拟了弹性系数不同的4个小球同时下落的场景,渲染效果如下中图所示;点击"PHYSICS ENGINE DEMO 2"按钮,示例中模拟了不同类型的约束效果,渲染效果如下右图所示:

示例1:设置地面与小球的物理参数

@Override public void onLoaded(Model model) { PhysicsEngineSampleOneActivity sampleActivity = weakRef.get(); if (sampleActivity == null || sampleActivity.isDestroyed()) { Model.destroy(model); return; } // 设置地面的物理参数。 if (isGround) { sampleActivity.groundModel = model; Node groundNode = sampleActivity.renderView.getScene().createNodeFromModel(model); groundNode.addComponent(Collider.descriptor()) .createBoxShape() .setExtent(new Vector3(1000f, 1f, 1000f)); groundNode.getComponent(Transform.descriptor()) .setPosition(new Vector3(0f, -3f, 0f)).setScale(new Vector3(20f, 1f, 20f)); groundNode.addComponent(RigidBody.descriptor()) .setRestitution(1f) .setGroup((short) 1) .setKinematic(false) .setFriction(10f) .setMask((short) 1) .setMass(0); return; } sampleActivity.sphereModel = model; // 设置小球的物理参数。 for (int index = 0; index &lt; 4; index++) { Node node = sampleActivity.renderView.getScene().createNodeFromModel(model); Transform transform = node.getComponent(Transform.descriptor()); transform.setScale(new Vector3(0.6f, 0.6f, 0.6f)); transform.setPosition(new Vector3(-3.0f + 2 * index, 10.0f, 10.0f)); node.addComponent(Collider.descriptor()) .createSphereShape().setRadius(0.6f); node.addComponent(RigidBody.descriptor()) .setMask((short) 1) .setGroup((short) 1) .setFriction(10.0f) .setKinematic(false) .setMass(1.0f) .setRestitution( 0.3f * index); } }

示例2:设置点约束与铰链约束

// 设置点约束。 private void addPoint2PointConstraint() { Node staticNode = loadModel(ballModel, new Vector3(0.1f, 0.1f, 0.1f), new Vector3(0, 15, 10)); staticNode.addComponent(RigidBody.descriptor()) .setMass(0) .setKinematic(false) .setGroup((short) 0) .setMask((short) 0); staticNode.addComponent(Collider.descriptor()) .createSphereShape() .setRadius(0.1f); Node targetNode = loadModel(ballModel, new Vector3(1f, 1f, 1f), new Vector3(2, 15, 10)); targetNode.addComponent(RigidBody.descriptor()) .setMass(1) .setLinearDamping(0) .setAngularDamping(0); targetNode.addComponent(Collider.descriptor()) .createSphereShape() .setRadius(0.77f); Point2PointConstraint constraint = targetNode.addComponent(Point2PointConstraint.descriptor()); constraint.setPivotA(new Vector3(0, 0, 0)); constraint.setPivotB(new Vector3(0, 3, 0)); constraint.setNodeA(staticNode); constraint.setNodeB(targetNode); } // 设置铰链约束。 private void addHingeConstraint() { Node staticNode = loadModel(boxModel, new Vector3(0.2f, 8, 0.25f), new Vector3(0.12f, 5, 10)); staticNode.addComponent(Collider.descriptor()).createBoxShape().setExtent(new Vector3(0.1f, 4, 0.125f)); staticNode.addComponent(RigidBody.descriptor()) .setMass(0) .setGroup((short) 0) .setMask((short) 0); Node targetNode = loadModel(boxModel, new Vector3(4, 8, 0.25f), new Vector3(-2, 5, 10)); targetNode.addComponent(Collider.descriptor()).createBoxShape().setExtent(new Vector3(1.98f, 4, 0.125f)); targetNode.addComponent(RigidBody.descriptor()) .setMass(1) .setAngularDamping(0) .setLinearDamping(0) .applyImpulse(new Vector3(15, 0, 15), new Vector3(1, 0, 0)); HingeConstraint hinge = targetNode.addComponent(HingeConstraint.descriptor()); hinge.setNodeA(targetNode); hinge.setNodeB(staticNode); hinge.setLowerLimit(0.f) .setUpperLimit((float) Math.PI) .setPivotA(new Vector3(2, 0, 0)) .setPivotB(Vector3.ZERO) .setAxisA(Vector3.UP) .setAxisB(Vector3.UP); }

3D流体组件

3D流体组件示例代码:hms-scene-3d-fluid-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上

运行效果如下左图所示;点击"START DEMO"按钮,摇晃手机使水体进行晃动,渲染效果如下右图所示:

场景化接口SDK

场景化接口SDK示例代码:hms-scene-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。

运行效果如下左图所示;分别点击"SCENE VIEW DEMO"按钮、"AR VIEW DEMO"按钮、"FACE VIEW DEMO"按钮,渲染效果如下图:

2D流体模拟SDK

2D流体模拟SDK示例代码:hms-scene-2d-fluid-demo。打开Android Studio工程同步完成后,点击"Run'app'"图标 ,运行打包生成APK,并安装在测试手机上。

运行效果如下左图所示;点击"Start Demo"按钮,摇晃手机使水体进行晃动,渲染效果如下右图所示:

干得好,您已经成功完成了Codelab所有步骤并学到了:

您可以阅读下面链接,了解更多相关的信息。

原子化接口SDK示例代码

hms-scene-fine-grained-demo

hms-scene-ar-face-demo

hms-scene-physics-engine-demo

hms-scene-3d-fluid-demo

场景化接口SDK示例代码

hms-scene-demo

2D流体模拟SDK示例代码

hms-scene-2d-fluid-demo

Code copied