华为应用市场在2022HDC大会期间发布了3D水流主题。基于华为HMSCoreSceneKit服务能力,展现立体灵活的水流岛,可以跟随用户的指尖实现实时的流体波动效果。解压缩。让不可预知的物质在影视、游戏等各种应用场景中实现我们的奇思妙想。从早期的重特技制作到今天,出现了更轻、更易用的问题解决范式。只需10分钟即可创建逼真的3D流体效果。什么是SceneKit流体模拟?SceneKit是一种图形引擎服务,提供轻量级的3D图形渲染引擎,可为游戏、AR&VR等移动应用提供简单易用的渲染界面,助力打造精美炫酷的视觉体验。SceneKit的3D流体技术目前支持移动端对水、油、岩浆等不同类型的物理和真实流体模拟。服务包括雾化接口、场景接口、离线简单模型插件、实时光线追踪插件等。性能优越:基于3D图形渲染框架和算法,提供高性能和低功耗3D立体场景构建能力。轻巧易用:提供基于场景的移动应用接口,简化3D图形应用的开发,方便2D图形应用扩展构建3D立体场景。逼真的效果:基于物理的渲染能力提供高质量的3D场景效果和身临其境的图形体验。实践环节:使用3D流体实现逼真的水流效果。开发环境安装AndroidStudio3.6.1及以上版本。JDK1.8(推荐)。您的应用应满足以下条件:minSdkVersion19及以上。targetSdkVersion30(推荐)。compileSdkVersion30(推荐)。Gradle5.4.1及以上版本(推荐)。如果同时使用多个HMSCore服务,需要使用每个Kit对应的最大值。测试应用程序的设备:Android4.4及更高版本。详细的开发配置准备步骤请参考图形引擎服务开发者联盟官网。Gradleplugin7.0以下、7.0、7.1及以上版本AndroidStudio开发准备代码库配置不同。请根据您当前的Gradle插件版本选择相应的配置流程。在“buildscript>repositories”配置HMSCoreSDK的Maven仓库地址。如果App中添加了“agconnect-services.json”文件,需要在“buildscript>dependencies”中添加agcp插件配置。打开项目级“settings.gradle”文件,配置HMSCoreSDK的Maven仓库地址。buildscript{repositories{google()jcenter()//配置HMSCoreSDK的Maven仓库地址。maven{url'https://developer.huawei.com/repo/'}}dependencies{...//添加agcp插件的配置。建议您使用最新版本的agcp插件。classpath'com.huawei.agconnect:agcp:1.6.0.300'}}dependencyResolutionManagement{...repositories{google()jcenter()//配置HMSCoreSDK的Maven仓库地址。maven{url'https://developer.huawei.com/repo/'}}}添加权限开发步骤创建两个Activity:MainActivity和SampleActivity。其中MainActivity负责完成SceneKit的初始化,SampleActivity用于容纳渲染视图,呈现最终效果。在MainActivity中添加初始化标识和初始化方法。在初始化方法中设置SceneKit全局属性,使用同步初始化接口initializeSync初始化SceneKit。privatestaticfinalintREQ_CODE_UPDATE_SCENE_KIT=10001;privatebooleaninitialized=false;privatevoidinitializeSceneKit(){//如果已经初始化过,不要重复初始化。如果(已初始化){返回;}//创建SceneKit属性,配置AppId和图形后端API。SceneKit.Propertyproperty=SceneKit.Property.builder().setAppId("${app_id}").setGraphicsBackend(SceneKit.Property.GraphicsBackend.GLES).build();try{//使用同步接口初始化。SceneKit.getInstance().setProperty(属性).initializeSync(getApplicationContext());初始化=真;Toast.makeText(this,"SceneKit初始化",Toast.LENGTH_SHORT).show();}catch(UpdateNeededExceptione){//捕获需要升级的异常,拉起升级Activity。startActivityForResult(e.getIntent(),REQ_CODE_UPDATE_SCENE_KIT);}catch(Exceptione){//处理初始化异常。Toast.makeText(this,"无法初始化SceneKit:"+e.getMessage(),Toast.LENGTH_SHORT).show();}}重写MainActivity的onActivityResult方法处理升级结果//当resultCode为-1时表示升级成功,其他resultCode表示升级失败。privatestaticfinalintRES_CODE_UPDATE_SUCCESS=-1;@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,@NullableIntentdata){super.onActivityResult(requestCode,resultCode,data);//如果升级成功,尝试重新初始化。if(requestCode==REQ_CODE_UPDATE_SCENE_KIT&&resultCode==RES_CODE_UPDATE_SUCCESS){尝试{SceneKit.getInstance().initializeSync(getApplicationContext());初始化=真;Toast.makeText(this,"SceneKit初始化",Toast.LENGTH_SHORT));}catch(Exceptione){//重试初始化时不再捕获升级异常。Toast.makeText(this,"无法初始化SceneKit:"+e.getMessage(),Toast.LENGTH_SHORT).show();}}}在MainActivity的Layout文件中添加一个跳转到SampleActivity的按钮。在MainActivity中添加按钮回调。publicvoidonBtnRenderViewDemoClicked(Viewview){//如果没有初始化,先初始化。if(!initialized){initializeSceneKit();返回;}//跳转到SampleActivity。startActivity(newIntent(this,SampleActivity.class));}新建一个渲染视图子类XRenderView,需要在该子类中添加相机和灯光组件。详情请参见布局场景。.publicclassXRenderViewextendsRenderView{publicXRenderView(Contextcontext){//...prepareScene();}//...}创建SampleActivity显示效果页publicclassDemoActivityextendsActivityimplementsSensorEventListener{privateXRenderViewrenderView;@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);renderView=newXRenderView(这个);设置内容视图(渲染视图);//...}}流体布局添加createFluidSecene方法3D流体组件不支持动态加载,只有在流体场景初始化时才会生效privateNodefluidNode;privatevoidcreateFluidScene(Contextcontext){//创建一个3D流体节点。fluidNode=renderView.getScene().createNode("fluidNode");//添加3D流体组件。FluidComponentfluidComponent=fluidNode.addComponent(FluidComponent.descriptor());}创建流体边界形状,设置流体体积privatevoidcreateFluidScene(Contextcontext){//...//创建球形流体边界形状。SdfSphereShapesphere=fluidComponent.createSdfSphereShape();//设置球体的半径。sphere.setRadius(12.0f);//设置流体体积。fluidComponent.setFluidVolume(0.4f);}注册传感器事件,获取加速度传感器信息);//获取加速度计。传感器=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);}@OverrideprotectedvoidonResume(){super.onResume();//注册传感器事件。sensorManager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_NORMAL);//...}@OverrideprotectedvoidonPause(){super.onPause();//注册传感器事件。sensorManager.unregisterListener(这个);//...}覆盖传感器的onSensorChanged方法,根据加速度传感器获取的值更新流体系统的重力加速度。@OverridepublicvoidonAccuracyChanged(Sensorsensor,intaccuracy){}@OverridepublicvoidonSensorChanged(SensorEventevent){if(event.sensor==null){返回;}//加速度传感器。如果(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){intx=(int)event.values[0];inty=(int)event.values[1];intz=(int)事件。价值观[2];int重力X=0;int重力Y=0;int重力Z=0;//屏幕旋转信息。rotation=this.getWindowManager().getDefaultDisplay().getRotation();//根据屏幕的旋转角度更新加速度信息。开关(旋转){caseSurface.ROTATION_0:gravityX=-x;重力Y=-y;重力Z=-z;休息;caseSurface.ROTATION_90:gravityX=y;重力Y=-x;重力Z=-z;休息;案例Surface.ROTATION_180:gravityX=x;重力Y=y;重力Z=-z;休息;案例Surface.ROTATION_270:gravityX=-y;重力Y=x;重力Z=-z;休息;默认值:中断;}FluidComponentfluidComponent=fluidNode.getComponent(FluidComponent.descriptor());if(fluidComponent!=null){//设置流体系统的重力加速度。fluidComponent.setGravity(newVector3(gravityX,gravityY,gravityZ));}}}@OverridepublicvoidonAccuracyChanged(Sensorsensor,intaccuracy){}创建一个新的触摸屏交互手势事件子类GestureEvent。公共类GestureEvent实现View.OnTouchListener{privateFluidComponentfluidComponent;私有int表面宽度;私有int表面高度;私人布尔场景就绪;publicGestureEvent(FluidComponentfluidComponent,intsurfaceWidth,intsurfaceHeight){this.fluidComponent=fluidComponent;this.surfaceWidth=surfaceWidth;this.surfaceHeight=surfaceHeight;sceneReady=fluidComponent!=null&&surfaceWidth!=0&&surfaceHeight!=0;}@OverridepublicbooleanonTouch(Viewview,MotionEventevent){if(!sceneReady){returnfalse;}switch(event.getAction()){caseMotionEvent.ACTION_DOWN:caseMotionEvent.ACTION_MOVE://流动体触屏交互接口,滑动流动体,模拟流动体震动的效果。fluidComponent.setGesture(event.getX()/surfaceWidth,event.getY()/surfaceHeight);休息;案例MotionEvent.ACTION_UP:fluidComponent.setGesture(-1.0f,-1.0f);休息;默认值:中断;}返回真;}}注册触屏交互手势事件,支持触屏滑动流体,模拟流动飞溅效果。重写DemoActivity中的onTouchEvent方法。privateGestureEventgesture;privatevoidcreateFluidScene(Contextcontext){//...//获取屏幕信息。DisplayMetricsdisplayMetrics=context.getResources().getDisplayMetrics();//注册手势事件。gesture=newGestureEvent(fluidComponent,displayMetrics.widthPixels,displayMetrics.heightPixels);}@OverridepublicbooleanonTouchEvent(MotionEventmotionEvent){if(gesture!=null){gesture.onTouch(renderView,motionEvent);}}returnmoActive}在onCreate方法中调用createFluidScene方法完成流体场景创建。@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){//...createFluidScene();}完成以上步骤后,运行应用程序,启动DemoActivity,就可以看到流体在看不见的球形边界内流动。有关详细信息,请参阅雾化界面3D流体示例代码。更多详情>>访问华为开发者联盟官网获取开发指导文档华为移动服务开源仓库地址:GitHub、Gitee关注我们,第一时间了解HMSCore最新技术资讯~