• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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