4.use-graph.md 3.2 KB


title: useGraph

description: useGraph generates a reactive map of named nodes, materials, and meshes from a Three.js object hierarchy.

The useGraph composable provides a convenient way to extract and reactively access all named nodes, materials, and meshes from a Three.js object or scene. This is especially useful when working with loaded models or complex object hierarchies, allowing you to reference and manipulate specific parts of your 3D scene by name.

Usage

import { useGraph } from '@tresjs/core'
import { BoxGeometry, Group, Mesh, MeshStandardMaterial } from 'three'

// Create a group and add a mesh with a named material
const group = new Group()
const box = new Mesh(
  new BoxGeometry(1, 1, 1),
  new MeshStandardMaterial({ name: 'FancyMaterial', color: 'red' })
)
box.name = 'Box'
group.add(box)

// Use useGraph to extract nodes and materials
const { nodes, materials } = useGraph(group)

// Change the position of the box by name
nodes.Box.position.set(1, 0, 0)
// Change the color of the material by name
materials.FancyMaterial.color.set('blue')

::tip useGraph is especially useful for working with loaded GLTF/FBX models, where you want to access specific meshes or materials by their names as defined in the 3D modeling tool. ::

Example

When loading a GLTF model, you can use useGraph to easily access and manipulate specific parts of the model:

<script setup lang="ts">
import { useGraph, useLoader } from '@tresjs/core'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

const { state: model } = useLoader(GLTFLoader, 'path/to/model.glb')
const scene = computed(() => model.value?.scene)

const { nodes, materials } = useGraph(scene)

materials.FancyMaterial.color.set('purple')
</script>

<template>
  <primitive v-if="nodes.Rig" :object="nodes.Rig" />
</template>

::note Best Practice: Always assign unique names to important nodes and materials in your 3D models for easier access in code. ::

API

The useGraph composable returns a computed ref containing a TresObjectMap with the following structure:

:::field-group ::::field{name="nodes" type="Record"} All named nodes in the object hierarchy, indexed by their name property. :::: ::::field{name="materials" type="Record"} All unique materials, indexed by their name property. Only the first material with a given name is included. :::: ::::field{name="meshes" type="Record"} All unique meshes, indexed by their name property. Only the first mesh with a given name is included. :::: ::::field{name="scene" type="Scene | undefined"} The root scene object, if available. :::: :::

Type Signature

function useGraph(object: MaybeRef<TresObject>): ComputedRef<TresObjectMap>

interface TresObjectMap {
  nodes: { [name: string]: TresObject }
  materials: { [name: string]: TresMaterial }
  meshes: { [name: string]: Mesh }
  scene?: Scene
}

Edge Cases & Notes

  • Only the first material or mesh with a given name is included in the map. Duplicate names are ignored after the first occurrence.
  • Unnamed objects are not included in the nodes map.
  • If the input object is null or undefined, all maps will be empty.