1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import scene3d from '@ohos.graphics.scene' 17import router from '@ohos.router'; 18import Logger from '../util/Logger'; 19@Entry 20@Component 21struct nodeBase { 22 scene: scene3d.Scene | null = null; 23 @State sceneOpt: SceneOptions | null = null; 24 cam: scene3d.Camera | null = null; 25 private scaled: boolean = false; 26 private step: number = 0; 27 @State xAxis: number = 0; 28 @State layerMaskInfo: string = ''; 29 private value: number = 0; 30 private layerMaskIndex: number = 0x1; 31 node: scene3d.Node | null | undefined = null; 32 33 traversalChild(node: scene3d.Node | null): void { 34 if (!node) { 35 return; 36 } 37 38 let container: scene3d.Container<scene3d.Node> = node.children; 39 let count: number = container.count(); 40 41 for (let i = 0; i < count; i++) { 42 this.traversalChild(container.get(i)); 43 } 44 } 45 46 onPageShow(): void { 47 this.init(); 48 } 49 50 onPageHide(): void { 51 if (this.scene) { 52 this.scene.destroy(); 53 } 54 55 this.cam = null; 56 this.scene = null; 57 } 58 59 init(): void { 60 if (this.scene === null) { 61 scene3d.Scene.load($rawfile("gltf/DamagedHelmet/glTF/DamagedHelmet.glb")).then(async (result: scene3d.Scene) => { 62 this.scene = result; 63 this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions; 64 let rf: scene3d.SceneResourceFactory = this.scene.getResourceFactory(); 65 this.cam = await rf.createCamera({ "name": "Camera1" }); 66 this.cam.enabled = true; 67 this.cam.position.z = 5; // move camera to position 5 on z 68 69 this.scene.environment.backgroundType = scene3d.EnvironmentBackgroundType.BACKGROUND_NONE; 70 this.cam.clearColor = { r: 0, g: 0, b: 0, a: 0.0 }; 71 this.node = this.scene.getNodeByPath('rootNode_/Scene/node_damagedHelmet_-6514'); 72 if (this.node) { 73 this.xAxis = this.node.position.x; 74 this.value = this.xAxis; 75 } 76 }).catch((reason: string) => { 77 Logger.error("init error", reason); 78 }); 79 } 80 } 81 82 build() { 83 Row() { 84 Column() { 85 Column() { 86 if (this.sceneOpt) { 87 Component3D(this.sceneOpt) 88 .renderWidth('60%') 89 .renderHeight('60%') 90 } 91 else { 92 Text("loading 1..."); 93 } 94 } 95 .height('30%') 96 97 Button('scale helmet ') 98 .onClick(() => { 99 if (!this.scene) { 100 return; 101 } 102 let node: scene3d.Node | null | undefined = this.scene.root?.children.get(0)?.getNodeByPath('node_damagedHelmet_-6514'); 103 if (!node) { 104 return; 105 } 106 107 if (this.scaled) { 108 node.scale = { x: 1.0, y: 1.0, z: 1.0 } 109 this.scaled = false; 110 } else { 111 node.scale = { x: 0.5, y: 0.5, z: 0.5 } 112 this.scaled = true; 113 } 114 }).id('scale_helmet'); 115 116 Column() { 117 Text("x axis: " + this.xAxis?.toFixed(1)).fontSize(12) 118 Slider({ 119 value: this.value, 120 min: this.value - 10, 121 max: this.value + 10, 122 step: 0.1, 123 style: SliderStyle.OutSet 124 }) 125 .showTips(false) 126 .onChange((value: number, mode: SliderChangeMode) => { 127 this.xAxis = value; 128 if (mode === SliderChangeMode.End) { 129 if (!this.node) { 130 return; 131 } 132 this.node.position.x = this.xAxis; 133 } 134 }) 135 .width("100%") 136 } 137 .alignItems(HorizontalAlign.Start) 138 .width('100%') 139 140 Button('rotate helmet ') 141 .onClick(() => { 142 if (!this.scene) { 143 return; 144 } 145 let node: scene3d.Node | null | undefined = this.scene.getNodeByPath('rootNode_/Scene/node_damagedHelmet_-6514'); 146 if (!node) { 147 return; 148 } 149 let c = Math.cos(-this.step * 0.7 * 0.1); 150 let s = Math.sin(-this.step * 0.7 * 0.1); 151 node.rotation = { x: s, y: 0.0, z: 0.0, w: c }; 152 this.step++; 153 }).id('rotate_helmet'); 154 155 Button('rotate parent ') 156 .onClick(() => { 157 if (!this.scene) { 158 return; 159 } 160 let child: scene3d.Node | null | undefined = this.scene.root?.getNodeByPath('Scene/node_damagedHelmet_-6514'); 161 if (!child) { 162 return; 163 } 164 let node: scene3d.Node | null = child.parent; 165 if (!node) { 166 return; 167 } 168 let c = Math.cos(-this.step * 0.7 * 0.1); 169 let s = Math.sin(-this.step * 0.7 * 0.1); 170 node.rotation = { x: 0.0, y: s, z: 0.0, w: c }; 171 this.step++; 172 }).id('rotate_parent'); 173 174 Button('root visible') 175 .onClick(() => { 176 if (this.scene?.root) { 177 this.scene.root.visible = !this.scene.root?.visible 178 } 179 }).id('root_visible') 180 181 Button('layer mask').onClick(() => { 182 if (!this.scene) { 183 return; 184 } 185 let node: scene3d.Node | null | undefined = this.scene.getNodeByPath('rootNode_/Scene/node_damagedHelmet_-6514'); 186 if (!node) { 187 return; 188 } 189 let enabled: Boolean = node.layerMask.getEnabled(this.layerMaskIndex); 190 node.layerMask.setEnabled(1,!enabled); 191 this.layerMaskInfo = node.name + ':\n' + 'layer mask index : ' + this.layerMaskIndex + '\n' + 192 'enabled: ' + enabled; 193 }).id('layer_mask') 194 195 Text("layer mask info: \n" + this.layerMaskInfo) 196 197 Button('back') 198 .onClick(() => { 199 if (this.scene) { 200 this.scene.destroy(); 201 } 202 router.back() 203 } 204 ).id('node_back') 205 } 206 .width('100%') 207 } 208 .height('100%') 209 } 210}