From 204c0dc38bd0e6bee663b0d7d86cb78922ac649b Mon Sep 17 00:00:00 2001 From: z60068389 Date: Thu, 5 Jun 2025 18:21:58 +0800 Subject: [PATCH] Samples Warehouse Common Source Rectification Signed-off-by: zhulei --- .../src/main/ets/arkgraphic/animation.ets | 58 ++--- .../src/main/ets/arkgraphic/resource.ets | 233 ++++++++++-------- .../entry/src/main/ets/scene/camera.ets | 91 +++---- .../entry/src/main/ets/scene/init.ets | 8 +- .../entry/src/main/ets/scene/light.ets | 95 +++---- 5 files changed, 260 insertions(+), 225 deletions(-) diff --git a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/animation.ets b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/animation.ets index 35af0cbda6..f35cfaf688 100644 --- a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/animation.ets +++ b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/animation.ets @@ -17,17 +17,6 @@ import { Animation, Camera, Scene, SceneResourceFactory } from '@kit.ArkGraphics import { router } from '@kit.ArkUI'; import logger from '../utils/Logger'; -async function createAnimationPromise(): Promise { - let scene: Scene = await Scene.load($rawfile('gltf/BrainStem/glTF/BrainStem.glb')); - - // create animation - let anim: Animation = scene.animations[0]; - - logger.info('ready to create a new animation.'); - - return anim; -} - @Entry @Component struct sceneAnimation { @@ -54,20 +43,38 @@ struct sceneAnimation { init(): void { if (this.scene == null) { // Loading scene. + // Switched from .gltf to .glb; same content, different format Scene.load($rawfile('gltf/BrainStem/glTF/BrainStem.glb')) .then(async (result: Scene) => { this.scene = result; let rf: SceneResourceFactory = this.scene.getResourceFactory(); + + // Get animation resources + this.anim = this.scene.animations[0]; + if (this.anim) { + this.anim.enabled = true; + // Register callback function + this.anim.onStarted(() => { + console.info('onStarted'); + this.animationCallbackInvoked = 'animation on start'; + }); + + this.anim.onFinished(() => { + console.info('onFinished'); + this.animationCallbackInvoked = 'animation on finish'; + }); + + logger.info('ready to create a new animation.'); + } else { + logger.error('No animation found in scene.'); + } + // create a new camera. this.cam = await rf.createCamera({ 'name': 'Camera' }); // set the camera. this.cam.enabled = true; this.cam.position.z = 5; - this.scene.animations[0] = await createAnimationPromise(); - - this.scene.animations[0].enabled = true; - this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions; }).catch((err: string) => { logger.error(err); @@ -82,24 +89,9 @@ struct sceneAnimation { if (this.sceneOpt) { Component3D(this.sceneOpt) .renderWidth('60%') - .renderHeight('60%') - .onAppear(() => { - if (!this.scene || !this.scene.animations[0]) { - return; - } - - let anim: Animation = this.scene.animations[0]; - - anim.onStarted(() => { - this.animationCallbackInvoked = 'animation on start'; - }); - - anim.onFinished(() => { - this.animationCallbackInvoked = 'animation on finish'; - }); - }); + .renderHeight('60%'); } else { - Text('loading 1...'); + Text('Loading···'); } } .height('30%'); @@ -117,7 +109,7 @@ struct sceneAnimation { if (!this.scene || !this.scene.animations[0]) { return; } - this.anim = this.scene?.animations[0]; + this.anim = this.scene.animations[0]; this.anim.start(); }); diff --git a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/resource.ets b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/resource.ets index a7e73caae7..a7b6cd5e34 100644 --- a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/resource.ets +++ b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/arkgraphic/resource.ets @@ -30,6 +30,129 @@ import { import { router } from '@kit.ArkUI'; import logger from '../utils/Logger'; +let globalScene: Scene | null = null; + +function createMaterialPromise(): Promise { + return new Promise((resolve, reject) => { + // Ensure the scene is loaded before accessing sceneFactory + if (globalScene) { + let sceneFactory: SceneResourceFactory = globalScene.getResourceFactory(); + let sceneMaterialParameter: SceneResourceParameters = { name: 'material' }; + // Create Material + let material: Promise = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER); + material.then(resolve) + .catch((err: string) => { + logger.error('Blank material create failed: ' + err); + reject(err); + }); + } else { + reject('Scene is not loaded yet.'); + } + }); +} + +function createShaderPromise(): Promise { + return new Promise((resolve, reject) => { + // Ensure the scene is loaded before accessing sceneFactory + if (globalScene) { + let sceneFactory: SceneResourceFactory = globalScene.getResourceFactory(); + + // Create a SceneResourceParameters object and use it to create a shader + let sceneResourceParameter: SceneResourceParameters = { + name: 'shaderResource', + uri: $rawfile('shaders/custom_shader/custom_material_sample.shader') + }; + let shader: Promise = sceneFactory.createShader(sceneResourceParameter); + shader.then(async (shaderEntity: Shader) => { + let sceneMaterialParameter: SceneResourceParameters = { name: 'material' }; + // Create material + let material: Promise = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER); + material.then(async (materialEntity: ShaderMaterial) => { + // Bind material with shader + materialEntity.colorShader = shaderEntity; + resolve(shaderEntity); + }).catch((err: string) => { + logger.error('Custom ShaderMaterial create failed: ' + err + '.'); + reject(err); + }); + }).catch((err: string) => { + logger.error('Shader load failed: ' + err + '.'); + reject(err); + }); + } else { + reject('Scene is not loaded yet.'); + } + }); +} + +function createImagePromise(): Promise { + return new Promise((resolve, reject) => { + // Ensure the scene is loaded before accessing sceneFactory + if (globalScene) { + let sceneFactory: SceneResourceFactory = globalScene.getResourceFactory(); + let sceneImageParameter: SceneResourceParameters = { name: 'image', uri: $rawfile('image/Cube_BaseColor.png') }; + // Create image + let image: Promise = sceneFactory.createImage(sceneImageParameter); + image.then(async (imageEntity: Image) => { + let sceneMaterialParameter: SceneResourceParameters = { name: 'material' }; + // Create material + let material: Promise = sceneFactory.createMaterial(sceneMaterialParameter, MaterialType.SHADER); + material.then(async (materialEntity: ShaderMaterial) => { + // Use the created image resource to set texture property + if (materialEntity && materialEntity.colorShader) { + materialEntity.colorShader.inputs['BASE_COLOR_Image'] = imageEntity; + } + resolve(imageEntity); + }).catch((err: string) => { + logger.error('Shader material of image texture create failed: ' + err + '.'); + reject(err); + }); + }).catch((err: string) => { + logger.error('ImageTexture load failed: ' + err + '.'); + reject(err); + }); + } else { + reject('Scene is not loaded yet.'); + } + }); +} + +function createEnvironmentPromise() : Promise { + return new Promise((resolve, reject) => { + // Ensure the scene is loaded before accessing sceneFactory + if (globalScene) { + let sceneFactory: SceneResourceFactory = globalScene.getResourceFactory(); + + // Manually load environment maps (.ktx/.jpg/.png etc.) + let sceneImageParameter: SceneResourceParameters = { name: 'image', uri: $rawfile('image/Cube_BaseColor.png') }; + let image: Promise = sceneFactory.createImage(sceneImageParameter); + image.then(async (imageEntity: Image) => { + // Create Environment + let sceneEnvironmentParameter: SceneResourceParameters = { name: 'env' }; + let env: Promise = sceneFactory.createEnvironment(sceneEnvironmentParameter); + env.then(async (envEntity: Environment) => { + envEntity.backgroundType = EnvironmentBackgroundType.BACKGROUND_EQUIRECTANGULAR; + envEntity.environmentImage = imageEntity; + // Set environment related properties + envEntity.indirectDiffuseFactor.x = 1; + envEntity.indirectDiffuseFactor.y = 1; + envEntity.indirectDiffuseFactor.z = 1; + envEntity.indirectDiffuseFactor.w = 1; + resolve(envEntity); + }).catch((err: string) => { + logger.error('Environment mapping material create failed: ' + err + '.'); + reject(err); + }); + }).catch((err: string) => { + logger.error('Image load failed: ' + err); + reject(err); + }); + } else { + reject('Scene is not loaded yet.'); + } + }); +} + @Entry @Component struct materialPage { @@ -68,102 +191,16 @@ struct materialPage { this.shaderMat = null; this.imageMat = null; this.env = null; - } - - async createMaterialPromise(): Promise { - try { - logger.info('start to create a new Material.'); - if (!this.rf) { - return null; - } - let sceneMaterialParameter: SceneResourceParameters = { name: 'material' }; - - // Create a material without anything - let material: Material = await this.rf.createMaterial(sceneMaterialParameter, MaterialType.SHADER); - - return material; - } catch (error) { - logger.error('Failed to create material: ' + error); - return null; - } - } - - async createShaderPromise(): Promise { - try { - logger.info('start to create a new shader.'); - if (!this.rf) { - return null; - } - - // Create a variable of the SceneResourceParameters type and use it to create a shader. - let sceneResourceParameter: SceneResourceParameters = { - name: 'shaderResource', - uri: $rawfile('shaders/custom_shader/custom_material_sample.shader') - }; - - // Create a material. - let shader: Shader = await this.rf.createShader(sceneResourceParameter); - - return shader; - } catch (error) { - logger.error('Failed to create shader: ' + error); - return null; - } - } - - async createImagePromise(): Promise { - try { - logger.info('start to create a new image.'); - if (!this.rf) { - return null; - } - let sceneImageParameter: SceneResourceParameters = { name: 'image', uri: $rawfile('image/Cube_BaseColor.png') }; - // create image - let image: Image = await this.rf.createImage(sceneImageParameter); - - return image; - } catch (error) { - logger.error('Failed to create image: ' + error); - return null; - } - } - - async createEnvironmentPromise(): Promise { - try { - logger.info('start to create a new environment.'); - if (!this.rf) { - return null; - } - - // create a new environment. - let env: Environment = await this.rf.createEnvironment({ - name: 'env' - }); - - let image: Image = await this.rf.createImage({ - name: 'Image', - uri: $rawfile('image/Cube_BaseColor.png') - }); - - env.backgroundType = EnvironmentBackgroundType.BACKGROUND_EQUIRECTANGULAR; - env.environmentImage = image; - - env.indirectDiffuseFactor.x = 1; - env.indirectDiffuseFactor.y = 1; - env.indirectDiffuseFactor.z = 1; - env.indirectDiffuseFactor.w = 1; - - return env; - } catch (error) { - logger.error('Failed to create environment: ' + error); - return null; - } + globalScene = null; } init(): void { if (this.scene === null) { + // Switched from .gltf to .glb; same content, different format Scene.load($rawfile('gltf/CubeWithFloor/glTF/AnimatedCube.glb')) .then(async (result: Scene) => { + // Assign loaded scene to globalScene for unified resource creation + globalScene = result; this.scene = result; this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions; this.rf = this.scene.getResourceFactory(); @@ -190,7 +227,7 @@ struct materialPage { if (this.sceneOpt) { Component3D(this.sceneOpt); } else { - Text('loading ...'); + Text('Loading···'); } } .height('30%'); @@ -204,7 +241,7 @@ struct materialPage { logger.info('Start to replace with a blank material'); if (!this.blankMat) { - this.blankMat = await this.createMaterialPromise(); + this.blankMat = await createMaterialPromise(); } if (!this.scene || !this.rf) { @@ -226,10 +263,10 @@ struct materialPage { .width('60%') .height(40) .onClick(async (): Promise => { - logger.info('Start to replace with a blank material'); + logger.info('Start to replace with a shader material'); if (!this.shader) { - this.shader = await this.createShaderPromise(); + this.shader = await createShaderPromise(); } if (!this.scene || !this.rf) { @@ -277,12 +314,11 @@ struct materialPage { // bind between shader and imageMat this.imageMat.colorShader = this.shader; - let createdImage = await this.createImagePromise(); + let createdImage = await createImagePromise(); if (createdImage) { this.imageMat.colorShader.inputs['BASE_COLOR_Image'] = createdImage; } - this.geom = this.scene.getNodeByPath('rootNode_/Unnamed Node 1/AnimatedCube') as Geometry; this.geom.mesh.materialOverride = undefined; @@ -301,9 +337,10 @@ struct materialPage { return; } - this.env = await this.createEnvironmentPromise(); - if (this.env) + this.env = await createEnvironmentPromise(); + if (this.env) { this.scene.environment = this.env; + } }); Button('back') diff --git a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/camera.ets b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/camera.ets index 38842e5623..03cd0ffae1 100644 --- a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/camera.ets +++ b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/camera.ets @@ -17,6 +17,43 @@ import { Camera, Scene, SceneNodeParameters, SceneResourceFactory } from '@kit.A import { router } from '@kit.ArkUI'; import logger from '../utils/Logger'; +let globalScene: Scene | null = null; + +function createCameraPromise(): Promise { + return new Promise((resolve, reject) => { + // Switched from .gltf to .glb; same content, different format + let scene: Promise = Scene.load($rawfile('gltf/CubeWithFloor/glTF/AnimatedCube.glb')); + scene.then(async (result: Scene) => { + // Save loaded scene globally for reuse (e.g., in CameraPage) + globalScene = result; + let sceneFactory: SceneResourceFactory = result.getResourceFactory(); + let sceneCameraParameter: SceneNodeParameters = { name: 'camera' }; + // Create a Camera. + let camera: Promise = sceneFactory.createCamera(sceneCameraParameter); + camera.then(async (cameraEntity: Camera) => { + // Enable the camera node. + cameraEntity.enabled = true; + + // Set the camera position. + cameraEntity.position.z = 5; + + // Set the FoV. + cameraEntity.fov = 60 * Math.PI / 180; + + // Set other camera parameters. + // ... + resolve(cameraEntity); + }).catch((error: string) => { + logger.error('Camera create failed: ' + error + '.'); + reject(error); + }); + }).catch((error: string) => { + logger.error('Scene load failed: ' + error); + reject(error); + }); + }); +} + @Entry @Component struct CameraPage { @@ -27,7 +64,7 @@ struct CameraPage { @State positionY: number = 0; @State positionZ: number = 5; - async onPageShow(): Promise { + onPageShow(): void { this.init(); } @@ -38,49 +75,18 @@ struct CameraPage { this.scene = null; this.sceneOpt = null; this.camera = null; - } - - createCameraPromise(): Promise { - return new Promise((resolve, reject) => { - Scene.load($rawfile('gltf/CubeWithFloor/glTF/AnimatedCube.glb')) - .then(async (result: Scene) => { - try { - this.scene = result; - const sceneFactory: SceneResourceFactory = result.getResourceFactory(); - let sceneCameraParameter: SceneNodeParameters = { name: 'camera' }; - // Create a Camera. - let camera: Promise = sceneFactory.createCamera(sceneCameraParameter); - camera.then(async (cameraEntity: Camera) => { - // Enable the camera node. - cameraEntity.enabled = true; - - // Set the camera position. - cameraEntity.position.x = this.positionX; - cameraEntity.position.y = this.positionY; - cameraEntity.position.z = this.positionZ; - - // Set the FoV. - cameraEntity.fov = 60 * Math.PI / 180; - // Set other camera parameters. - // ... - }); - this.sceneOpt = { scene: result, modelType: ModelType.SURFACE } as SceneOptions; - - resolve(camera); - } catch (error) { - logger.error('Error in createCameraPromise: ' + error + '.'); - reject(error); - } - }) - .catch((error: string) => { - logger.error('Error loading scene: ' + error + '.'); - reject(error); - }); - }); + globalScene = null; } async init(): Promise { - this.camera = await this.createCameraPromise(); + this.camera = await createCameraPromise(); + if (globalScene && this.camera) { + this.scene = globalScene; + this.positionX = this.camera.position.x; + this.positionY = this.camera.position.y; + this.positionZ = this.camera.position.z; + this.sceneOpt = { scene: globalScene, modelType: ModelType.SURFACE } as SceneOptions; + } } build() { @@ -179,6 +185,3 @@ struct CameraPage { }.height('60%') } } - - - diff --git a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/init.ets b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/init.ets index a1a2426403..1f80003f47 100644 --- a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/init.ets +++ b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/init.ets @@ -19,7 +19,7 @@ import logger from '../utils/Logger'; @Entry @Component -struct Init { +struct Model { scene: Scene | null = null; @State sceneOpt: SceneOptions | null = null; cam: Camera | null = null; @@ -40,6 +40,7 @@ struct Init { init(): void { if (this.scene == null) { // Load the model and place the gltf file in the related path. Use the actual path during loading. + // Switched from .gltf to .glb; same content, different format Scene.load($rawfile('gltf/DamagedHelmet/glTF/DamagedHelmet.glb')) .then(async (result: Scene) => { this.scene = result; @@ -52,8 +53,9 @@ struct Init { this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions; logger.info('initialization completely.'); - }).catch((err: string) => { - logger.error('Error: ' + err + '.'); + }) + .catch((reason: string) => { + console.log(reason); }); } } diff --git a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/light.ets b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/light.ets index 9a0d938dd4..0a7482a836 100644 --- a/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/light.ets +++ b/code/DocsSample/graphic/ArkGraphics3D/entry/src/main/ets/scene/light.ets @@ -17,6 +17,37 @@ import { Camera, Light, LightType, Scene, SceneNodeParameters, SceneResourceFact import { router } from '@kit.ArkUI'; import logger from '../utils/Logger'; +let globalScene: Scene | null = null; + +function createLightPromise(): Promise { + return new Promise((resolve, reject) => { + // Switched from .gltf to .glb; same content, different format + let scene: Promise = Scene.load($rawfile('gltf/CubeWithFloor/glTF/AnimatedCube.glb')); + scene.then(async (result: Scene) => { + // Save loaded scene globally for reuse (e.g., in LightPage) + globalScene = result; + let sceneFactory: SceneResourceFactory = result.getResourceFactory(); + let lightParameter: SceneNodeParameters = { name: 'light' }; + // Create directional light. + let light: Promise = sceneFactory.createLight(lightParameter, LightType.DIRECTIONAL); + light.then(async (lightEntity: Light) => { + // Set the color of the directional light. + lightEntity.color = { r: 0.8, g: 0.1, b: 0.2, a: 1.0 }; + + // Set other light parameters. + // ... + resolve(lightEntity); + }).catch((err: string) => { + logger.error('Light create failed: ' + err + '.'); + reject(err); + }); + }).catch((error: string) => { + logger.error('Scene load failed: ' + error); + reject(error); + }); + }); +} + @Entry @Component struct LightPage { @@ -24,52 +55,11 @@ struct LightPage { @State sceneOpt: SceneOptions | null = null; cam: Camera | null = null; light: Light | null = null; + rf: SceneResourceFactory | null = null; @State red: number = 0; @State green: number = 0; @State blue: number = 0; - createLightPromise(): Promise { - return new Promise((resolve, reject) => { - Scene.load($rawfile('gltf/CubeWithFloor/glTF/AnimatedCube.glb')) - .then(async (result: Scene) => { - try { - this.scene = result; - this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE }; - - let sceneFactory: SceneResourceFactory = this.scene.getResourceFactory(); - - // Create a new camera. - this.cam = await sceneFactory.createCamera({ name: 'camera' }); - this.cam.enabled = true; - this.cam.position.z = 10; - - let sceneLightParameter: SceneNodeParameters = { name: 'light' }; - // Create directional light. - let light: Light = await sceneFactory.createLight(sceneLightParameter, LightType.DIRECTIONAL); - // Set the color of the directional light. - light.color = { - r: this.red, - g: this.green, - b: this.blue, - a: 1.0 - }; - - // Set other light parameters. - // ... - - resolve(light); - } catch (error) { - logger.error('Error in createLightPromise: ' + error + '.'); - reject(error); - } - }) - .catch((error: string) => { - logger.error('Error loading scene: ' + error + '.'); - reject(error); - }) - }) - } - onPageShow(): void { this.init(); } @@ -82,10 +72,24 @@ struct LightPage { this.sceneOpt = null; this.cam = null; this.light = null; + this.rf = null; + globalScene = null; } async init(): Promise { - this.light = await this.createLightPromise(); + this.light = await createLightPromise(); + if (globalScene && this.light) { + this.scene = globalScene; + this.sceneOpt = { scene: globalScene, modelType: ModelType.SURFACE } as SceneOptions; + this.rf = this.scene.getResourceFactory(); + this.cam = await this.rf.createCamera({ 'name': 'Camera1' }); + this.cam.enabled = true; + this.cam.position.z = 5; + // Initialize color value + this.red = this.light.color.r; + this.green = this.light.color.g; + this.blue = this.light.color.b; + } } build() { @@ -94,7 +98,7 @@ struct LightPage { if (this.sceneOpt) { Component3D(this.sceneOpt); } else { - Text('loading···'); + Text('Loading···'); } Column() { @@ -199,6 +203,3 @@ struct LightPage { .height('60%') } } - - - -- Gitee