1# SceneNode 2<!--Kit: ArkGraphics 3D--> 3<!--Subsystem: Graphics--> 4<!--Owner: @zzhao0--> 5<!--SE: @zdustc--> 6<!--TSE: @zhangyue283--> 7 8The module provides the types and operation methods of scene nodes in 3D graphics. 9 10> **NOTE** 11> 12> The initial APIs of this module are supported since API version 12. Newly added APIs will be marked with a superscript to indicate their earliest API version. 13 14## Modules to Import 15 16```ts 17import { LayerMask, NodeType, Container, Node, Geometry, LightType, Light, SpotLight, DirectionalLight, 18 Camera } from '@kit.ArkGraphics3D'; 19``` 20 21## LayerMask 22Layer mask of the node. 23 24### getEnabled 25getEnabled(index: number): boolean 26 27Checks whether the mask is enabled for a layer of a given index. 28 29**System capability**: SystemCapability.ArkUi.Graphics3D 30 31**Parameters** 32| Name| Type| Mandatory| Description| 33| ---- | ---- | ---- | ---- | 34| index | number | Yes| Index of the layer. The value is an integer greater than or equal to 0.| 35 36**Return value** 37| Type| Description| 38| ---- | ---- | 39| boolean | Check result for whether the layer mask is enabled. **true** if enabled, **false** otherwise.| 40 41**Example** 42```ts 43import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 44 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 45 46function layerMask() : void { 47 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 48 scene.then(async (result: Scene) => { 49 if (result) { 50 let node : Node | null = result.getNodeByPath("rootNode_"); 51 if (node) { 52 // Obtain the enabled status of the mask. 53 let enabled: Boolean = node.layerMask.getEnabled(1); 54 } 55 } 56 }); 57} 58``` 59 60### setEnabled 61 62setEnabled(index: number, enabled: boolean): void 63 64Enables the mask of a layer of a given index. 65 66**System capability**: SystemCapability.ArkUi.Graphics3D 67 68**Parameters** 69| Name| Type| Mandatory| Description| 70| ---- | ---- | ---- | ---- | 71| index | number | Yes| Index of the layer. The value is an integer greater than or equal to 0.| 72| enabled | boolean | Yes| Whether to enable the layer mask. **true** to enable, **false** otherwise.| 73 74**Example** 75```ts 76import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 77 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 78 79function layerMask() : void { 80 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 81 scene.then(async (result: Scene) => { 82 if (result) { 83 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 84 if (node) { 85 // Set the enabled status of the mask. 86 node.layerMask.setEnabled(1, true); 87 } 88 } 89 }); 90} 91``` 92 93## NodeType 94Enumerates the node types. 95 96**System capability**: SystemCapability.ArkUi.Graphics3D 97| Name| Value| Description| 98| ---- | ---- | ---- | 99| NODE | 1 | Empty node.| 100| GEOMETRY | 2 | Geometry node.| 101| CAMERA | 3 | Camera node.| 102| LIGHT | 4 | Light node.| 103 104## Container\<T> 105Container for defining scene nodes. It provides a way to group scene nodes into a hierarchy. 106 107### append 108append(item: T): void 109 110Appends a node to the container. 111 112**System capability**: SystemCapability.ArkUi.Graphics3D 113 114**Parameters** 115| Name| Type| Mandatory| Description| 116| ---- | ---- | ---- | ---- | 117| item | T | Yes| Object of the T type.| 118 119**Example** 120```ts 121import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 122 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 123 124function append() : void { 125 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 126 scene.then(async (result: Scene) => { 127 if (result) { 128 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 129 // Call append to add a node. 130 result.root?.children.get(0)?.children.append(node); 131 } 132 }); 133} 134``` 135 136### insertAfter 137insertAfter(item: T, sibling: T | null): void 138 139Inserts a node after a sibling node. 140 141**System capability**: SystemCapability.ArkUi.Graphics3D 142 143**Parameters** 144| Name| Type| Mandatory| Description| 145| ---- | ---- | ---- | ---- | 146| item | T | Yes| Node to insert.| 147| sibling | T \| null | Yes| Sibling node.| 148 149**Example** 150```ts 151import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 152 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 153 154function insertAfter() : void { 155 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 156 scene.then(async (result: Scene) => { 157 if (result) { 158 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 159 // Call insertAfter to add a node. 160 result.root?.children.get(0)?.children.insertAfter(node, null); 161 } 162 }); 163} 164``` 165 166### remove 167remove(item: T): void 168 169Removes a node. 170 171**System capability**: SystemCapability.ArkUi.Graphics3D 172 173**Parameters** 174| Name| Type| Mandatory| Description| 175| ---- | ---- | ---- | ---- | 176| item | T | Yes| Node to remove.| 177 178**Example** 179```ts 180import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 181 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 182 183function remove() : void { 184 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 185 scene.then(async (result: Scene) => { 186 if (result) { 187 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 188 // Call remove to remove a node. 189 result.root?.children.remove(node); 190 } 191 }); 192} 193``` 194 195### get 196get(index: number): T | null 197 198Obtains a node of a given index. If no node is obtained, null is returned. 199 200**System capability**: SystemCapability.ArkUi.Graphics3D 201 202**Parameters** 203| Name| Type| Mandatory| Description| 204| ---- | ---- | ---- | ---- | 205| index | number | Yes| Index of the node. The value is an integer greater than or equal to 0.| 206 207**Return value** 208| Type| Description| 209| ---- | ---- | 210| T \| null | Object obtained. If no object is obtained, null is returned.| 211 212**Example** 213```ts 214import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 215 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 216 217function get() : void { 218 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 219 scene.then(async (result: Scene) => { 220 if (result) { 221 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 222 // Get node 0 from children. 223 result.root?.children.get(0)?.children.insertAfter(node, null); 224 } 225 }); 226} 227``` 228 229### clear 230clear(): void 231 232Clears all nodes in the container. 233 234**System capability**: SystemCapability.ArkUi.Graphics3D 235 236**Example** 237```ts 238import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 239 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 240 241function clear() : void { 242 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 243 scene.then(async (result: Scene) => { 244 if (result) { 245 let node : Node | null = result.getNodeByPath("rootNode/Scene/"); 246 // Clear the nodes in children. 247 result.root?.children.clear(); 248 } 249 }); 250} 251``` 252 253### count 254count(): number 255 256Obtains the number of nodes in the container. 257 258**System capability**: SystemCapability.ArkUi.Graphics3D 259 260**Return value** 261| Type| Description| 262| ---- | ---- | 263| number | Number of nodes in the container. The value is a non-negative integer.| 264 265**Example** 266```ts 267import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 268 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 269 270function count() : void { 271 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 272 scene.then(async (result: Scene) => { 273 if (result) { 274 let node : Node | null = result.getNodeByPath("rootNode_"); 275 if (node) { 276 let container: Container<Node> = node.children; 277 // Obtain the number of nodes in children. 278 let count: number = container.count(); 279 } 280 } 281 }); 282} 283``` 284 285## Node 286The 3D scene consists of nodes in a tree hierarchy, where each node implements a **Node** interface. This class inherits from [SceneResource](js-apis-inner-scene-resources.md#sceneresource-1). 287 288### Properties 289 290**System capability**: SystemCapability.ArkUi.Graphics3D 291 292| Name| Type| Read Only| Optional| Description| 293| ---- | ---- | ---- | ---- | ---- | 294| position | [Position3](js-apis-inner-scene-types.md#position3) | No| No| Position of the node.| 295| rotation | [Quaternion](js-apis-inner-scene-types.md#quaternion) | No| No| Rotation angle of the node.| 296| scale | [Scale3](js-apis-inner-scene-types.md#scale3) | No| No| Scale factor of the node.| 297| visible | boolean | No| No| Whether the node is visible. **true** if visible, **false** otherwise.| 298| nodeType | [NodeType](#nodetype) | Yes| No| Type of the node.| 299| layerMask | [LayerMask](#layermask) | Yes| No| Layer mask of the node.| 300| path | string | Yes| No| Path of the node.| 301| parent | [Node](#node) \| null | Yes| No| Parent node of the node. If the parent node does not exist, the value is null.| 302| children | [Container](js-apis-inner-scene-nodes.md#containert)\<[Node](#node)> | Yes| No| Children of the node. If the node does not have a child, the value is null.| 303 304### getNodeByPath 305getNodeByPath(path: string): Node | null 306 307Obtains a node by path. If no node is obtained, null is returned. 308 309**System capability**: SystemCapability.ArkUi.Graphics3D 310 311**Parameters** 312| Name| Type| Mandatory| Description| 313| ---- | ---- | ---- | ---- | 314| path | string | Yes| Path in the scene node hierarchy. Each layer is separated by a slash (/).| 315 316**Return value** 317| Type| Description| 318| ---- | ---- | 319| [Node](#node) \| null | Node object.| 320 321**Example** 322```ts 323import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 324 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node } from '@kit.ArkGraphics3D'; 325 326function getNode() : void { 327 let scene: Promise<Scene> = Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.gltf")); 328 scene.then(async (result: Scene) => { 329 if (result && result.root) { 330 // Search for a node. 331 let geo : Node | null = result.root.getNodeByPath("scene/node"); 332 } 333 }); 334} 335``` 336 337## Geometry 338Geometric node type that holds renderable mesh data and supports optional deformation features. It inherits from [Node](#node). 339 340### Properties 341 342**System capability**: SystemCapability.ArkUi.Graphics3D 343 344| Name| Type| Read Only| Optional| Description| 345| ---- | ---- | ---- | ---- | ---- | 346| mesh | [Mesh](js-apis-inner-scene-resources.md#mesh) | Yes| No| Mesh property.| 347| morpher<sup>20+</sup> | [Morpher](js-apis-inner-scene-resources.md#morpher20) | Yes| Yes| Optional morpher that adds vertex-based deformation or animation effects to the geometry. If this parameter is not specified, the geometry does not support deformation.| 348 349## LightType 350Enumerates the light types. 351 352**System capability**: SystemCapability.ArkUi.Graphics3D 353 354| Name| Value| Description| 355| ---- | ---- | ---- | 356| DIRECTIONAL | 1 | Directional light.| 357| SPOT | 2 | Spot light.| 358 359## Light 360Light node, which inherits from [Node](#node). 361 362### Properties 363 364**System capability**: SystemCapability.ArkUi.Graphics3D 365 366| Name| Type| Read Only| Optional| Description| 367| ---- | ---- | ---- | ---- | ---- | 368| lightType | [LightType](#lighttype) | Yes| No| Light type.| 369| color | [Color](js-apis-inner-scene-types.md#color) | No| No| Color.| 370| intensity | number | No| No| Light intensity. The value is a real number greater than 0.| 371| shadowEnabled | boolean | No| No| Whether the shadow effect is enabled. **true** if enabled, **false** otherwise.| 372| enabled | boolean | No| No| Whether the light is used. **true** if used, **false** otherwise.| 373 374## SpotLight 375Spot light, which inherits from [Light](#light). 376 377**System capability**: SystemCapability.ArkUi.Graphics3D 378 379## DirectionalLight 380Directional light, which inherits from [Light](#light). 381 382**System capability**: SystemCapability.ArkUi.Graphics3D 383 384 385## Camera 386Camera node, which inherits from [Node](#node). 387 388### Properties 389 390**System capability**: SystemCapability.ArkUi.Graphics3D 391 392| Name| Type| Read Only| Optional| Description| 393| ---- | ---- | ---- | ---- | ---- | 394| fov | number | No| No| Field of view. The value ranges from 0 to π radians.| 395| nearPlane | number | No| No| Near plane. The value is greater than 0.| 396| farPlane | number | No| No| Remote plane. The value must be greater than that of **nearPlane**.| 397| enabled | boolean | No| No| Whether the camera is enabled. **true** if enabled, **false** otherwise.| 398| postProcess | [PostProcessSettings](js-apis-inner-scene-post-process-settings.md#postprocesssettings) \| null | No| No| Post-processing settings.| 399| clearColor | [Color](js-apis-inner-scene-types.md#color) \| null | No| No| Color after the render target is cleared.| 400 401### raycast<sup>20+</sup> 402raycast(viewPosition: Vec2, params: RaycastParameters): Promise<RaycastResult[]> 403 404Casts a ray from a specific position on the screen to detect and retrieve information about all hit 3D objects. This API uses a promise to return the result. 405 406**System capability**: SystemCapability.ArkUi.Graphics3D 407 408**Parameters** 409| Name| Type| Mandatory| Description| 410| ---- | ---- | ---- | ---- | 411| viewPosition | [Vec2](js-apis-inner-scene-types.md#vec2) | Yes| Standardized Device Coordinates (NDC). The value range is [-1, 1]. The bottom-left corner of the screen is (-1, -1), and the top-right corner is (1, 1).| 412| params | [RaycastParameters](js-apis-inner-scene.md#raycastparameters20) | Yes| Configuration parameters for raycasting, such as detection range and filtered nodes.| 413 414**Return value** 415| Type| Description| 416| ---- | ---- | 417| Promise<[RaycastResult](js-apis-inner-scene.md#raycastresult20)[]> | An array of hit objects sorted by distance (from nearest to farthest). If no objects are hit, an empty array is returned.| 418 419**Example** 420```ts 421import { Image, Shader, MaterialType, Material, ShaderMaterial, Animation, Environment, Container, SceneNodeParameters, 422 LightType, Light, Camera, SceneResourceParameters, SceneResourceFactory, Scene, Node, Vec2, Vec3, 423 Quaternion } from '@kit.ArkGraphics3D'; 424import { RaycastParameters } from '@ohos.graphics.scene'; 425 426function Raycast(): void { 427 Scene.load($rawfile("gltf/CubeWithFloor/glTF/AnimatedCube.glb")) 428 .then(async (result: Scene) => { 429 if (!result.root) { 430 return; 431 } 432 let node: Node | null | undefined = result.root.getNodeByPath("rootNode_/Unnamed Node 1/AnimatedCube"); 433 let sceneFactory: SceneResourceFactory = result.getResourceFactory(); 434 let sceneCameraParameter: SceneNodeParameters = { name: "camera1" }; 435 // Create a camera. 436 let camera: Camera = await sceneFactory.createCamera(sceneCameraParameter); 437 camera.enabled = true; 438 // Set the camera view. 439 lookAt(camera, { x: 0, y: 0, z: -3 }, { x: 0, y: 0, z: 0 }, { x: 0, y: 1, z: 0 }); 440 441 let viewPos: Vec2 = { x: 0.5, y: 0.5 }; 442 let raycastParams: RaycastParameters = {}; 443 if (node) { 444 raycastParams.rootNode = node; 445 } 446 return camera.raycast(viewPos, raycastParams); 447 }); 448} 449 450function Sub(l: Vec3, r: Vec3): Vec3 { 451 return { x: l.x - r.x, y: l.y - r.y, z: l.z - r.z }; 452} 453function Dot(l: Vec3, r: Vec3): number { 454 return l.x * r.x + l.y * r.y + r.z * l.z; 455} 456function Normalize(l: Vec3): Vec3 { 457 let d = Math.sqrt(Dot(l, l)); 458 return { x: l.x / d, y: l.y / d, z: l.z / d }; 459} 460function Cross(l: Vec3, r: Vec3): Vec3 { 461 return { x: (l.y * r.z - l.z * r.y), y: (l.z * r.x - l.x * r.z), z: (l.x * r.y - l.y * r.x) }; 462} 463function Mul(l: Quaternion, d: number): Quaternion { 464 return { 465 x: l.x * d, 466 y: l.y * d, 467 z: l.z * d, 468 w: l.w * d 469 }; 470} 471function lookAt(node: Node, eye: Vec3, center: Vec3, up: Vec3) { 472 473 let t: number; 474 475 let q: Quaternion = { 476 x: 0.0, 477 y: 0.0, 478 z: 0.0, 479 w: 0.0 480 }; 481 let f = Normalize(Sub(center, eye)); 482 let m0 = Normalize(Cross(f, up)); 483 let m1 = Cross(m0, f); 484 let m2: Vec3 = { x: -f.x, y: -f.y, z: -f.z }; 485 if (m2.z < 0) { 486 if (m0.x > m1.y) { 487 t = 1.0 + m0.x - m1.y - m2.z; 488 q = { 489 x: t, 490 y: m0.y + m1.x, 491 z: m2.x + m0.z, 492 w: m1.z - m2.y 493 }; 494 } else { 495 t = 1.0 - m0.x + m1.y - m2.z; 496 q = { 497 x: m0.y + m1.x, 498 y: t, 499 z: m1.z + m2.y, 500 w: m2.x - m0.z 501 }; 502 } 503 } else { 504 if (m0.x < -m1.y) { 505 t = 1.0 - m0.x - m1.y + m2.z; 506 q = { 507 x: m2.x + m0.z, 508 y: m1.z + m2.y, 509 z: t, 510 w: m0.y - m1.x 511 }; 512 } else { 513 t = 1.0 + m0.x + m1.y + m2.z; 514 q = { 515 x: m1.z - m2.y, 516 y: m2.x - m0.z, 517 z: m0.y - m1.x, 518 w: t 519 } 520 } 521 } 522 node.position = eye; 523 node.rotation = Mul(q, 0.5 / Math.sqrt(t)); 524} 525``` 526