Skip to content
This repository was archived by the owner on Feb 1, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions docs/.vitepress/theme/components/FBXModelDemo.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
<script setup lang="ts">
import { FBXModel, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'

const gl = {
clearColor: '#82DBC5',
shadows: true,
alpha: false,
shadowMapType: BasicShadowMap,
outputColorSpace: SRGBColorSpace,
toneMapping: NoToneMapping,
}
</script>

<template>
<TresCanvas clear-color="#1F90FF">
<TresPerspectiveCamera :position="[11, 11, 11]" />
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[5.3, 2.45, 9.3]" :look-at="[0, 0, 0]" />
<OrbitControls />
<Suspense>
<FBXModel
path="https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx"
:scale="0.025"
/>
</Suspense>
<FBXModel
path="https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx"
cast-shadow
:scale="0.01"
:position="[0, -1.6, 0]"
:rotation-y="-Math.PI * 0.5"
/>
<TresMesh
:rotate-x="Math.PI * -0.5"
:position-y="-2"
receive-shadow
>
<TresPlaneGeometry :args="[40, 40]" />
<TresMeshStandardMaterial :color="0xF7F7F7" />
</TresMesh>
<TresAmbientLight :intensity="1" />
<TresDirectionalLight
:intensity="2"
:position="[3, 3, 3]"
:intensity="1"
cast-shadow
:position="[5, 10, 5]"
/>
<TresAmbientLight />
</TresCanvas>
</template>
57 changes: 45 additions & 12 deletions docs/.vitepress/theme/components/UseFBXDemo.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,59 @@
<script setup lang="ts">
import { OrbitControls, useFBX } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, Mesh, NoToneMapping, SRGBColorSpace } from 'three'
import { watchEffect } from 'vue'

const gl = {
clearColor: '#82DBC5',
shadows: true,
alpha: false,
shadowMapType: BasicShadowMap,
outputColorSpace: SRGBColorSpace,
toneMapping: NoToneMapping,
}

const path = 'https://raw.githubusercontent.com/'
+ 'Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx'
const model = await useFBX(path)

// Use the new reactive useFBX API
const { state: model } = useFBX(path)

// Apply transformations and shadows when model loads
watchEffect(() => {
if (model.value) {
model.value.scale.set(0.01, 0.01, 0.01)
model.value.position.set(0, -1.6, 0)
model.value.rotation.y = -Math.PI * 0.5

// Enable shadows for all meshes
model.value.traverse((child) => {
if (child instanceof Mesh) {
child.castShadow = true
}
})
}
})
</script>

<template>
<TresCanvas clear-color="#1F90FF">
<TresPerspectiveCamera :position="[11, 11, 11]" />
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[5.3, 2.45, 9.3]" :look-at="[0, 0, 0]" />
<OrbitControls />
<Suspense>
<primitive
:object="model"
:scale="0.025"
/>
</Suspense>
<primitive v-if="model" :object="model" />
<TresMesh
:rotate-x="Math.PI * -0.5"
:position-y="-2"
receive-shadow
>
<TresPlaneGeometry :args="[40, 40]" />
<TresMeshStandardMaterial :color="0xF7F7F7" />
</TresMesh>
<TresAmbientLight :intensity="1" />
<TresDirectionalLight
:intensity="2"
:position="[3, 3, 3]"
:intensity="1"
cast-shadow
:position="[5, 10, 5]"
/>
<TresAmbientLight :intensity="1" />
</TresCanvas>
</template>
35 changes: 30 additions & 5 deletions docs/guide/loaders/fbx-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,35 @@ The `FBXModel` component is a wrapper around [`useFBX`](./use-fbx.md) composable

<<< @/.vitepress/theme/components/FBXModelDemo.vue{3,10-15}

## Model reference

You can access the model reference by passing a `ref` to the `FBXModel` component and then using it to get the object.

```vue
<script setup lang="ts">
import type { TresObject } from '@tresjs/core'
import { FBXModel, OrbitControls } from '@tresjs/cientos'

const modelRef = shallowRef<TresObject>()

watch(modelRef, (model) => {
// Do something with the model
model.position.set(0, 0, 0)
})
</script>

<template>
<FBXModel
ref="modelRef"
path="https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx"
/>
</template>
```

## Props

| Prop | Description | Default |
| :----- | :---------------------- | ----------- |
| `path` | Path to the model file. | `undefined` |
| `castShadow` | Apply `cast-shadow` to all meshes inside your model. | `false` |
| `receiveShadow` | Apply `receive-shadow` to all meshes inside your model. | `false` |
| Prop | Description | Default |
| :------------- | :--------------------------------------------------------- | ----------- |
| `path` | Path to the model file. | `undefined` |
| `castShadow` | Apply `cast-shadow` to all meshes inside your model. | `false` |
| `receiveShadow`| Apply `receive-shadow` to all meshes inside your model. | `false` |
57 changes: 39 additions & 18 deletions docs/guide/loaders/use-fbx.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,24 @@
<UseFBXDemo />
</DocsDemo>

A composable that allows you to easily load glTF models into your **TresJS** scene.
A composable that allows you to easily load FBX models into your **TresJS** scene.

## Usage

::: code-group
```vue{2,6} [TheModel.vue]
<script setup lang="ts">
import { useFBX } from '@tresjs/cientos'

const path = 'https://raw.githubusercontent.com/'
+ 'Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx'
const { state, nodes, materials } = useFBX(path)
</script>

<template>
<primitive v-if="state" :object="state" :scale="0.025" />
</template>
```
```vue [app.vue]
<script setup lang="ts">
import { OrbitControls } from '@tresjs/cientos'
Expand All @@ -20,9 +33,7 @@ import TheModel from './TheModel.vue'
<TresCanvas clear-color="#1F90FF">
<TresPerspectiveCamera :position="[11, 11, 11]" />
<OrbitControls />
<Suspense>
<TheModel />
</Suspense>
<TheModel />
<TresDirectionalLight
:intensity="2"
:position="[3, 3, 3]"
Expand All @@ -31,20 +42,30 @@ import TheModel from './TheModel.vue'
</TresCanvas>
</template>
```
```vue{2,6} [TheModel.vue]
<script setup lang="ts">
import { useFBX } from '@tresjs/cientos'
:::

const path = 'https://raw.githubusercontent.com/'
+ 'Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx'
const { scene } = await useFBX(path)
</script>
## Return Values

<template>
<primitive
:object="scene"
:scale="0.025"
/>
</template>
| Name | Type | Description |
| :----------- | --------- | ---------------------------------------------- |
| **state** | `Group` | The loaded FBX model state |
| **nodes** | `object` | Computed object containing all nodes in the scene |
| **materials**| `object` | Computed object containing all materials in the scene |
| **isLoading**| `boolean` | Whether the model is currently loading |
| **execute** | `() => Promise<void>` | Function to reload the model |

## Accessing Nodes and Materials

The composable provides computed properties to easily access nodes and materials in your scene:

```ts
const { nodes, materials } = useFBX('/model.fbx')

// Access a specific node
const mesh = nodes.value.MeshName

// Access a specific material
const material = materials.value.MaterialName
```
:::

This makes it easier to manipulate specific parts of your model or apply materials programmatically.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"peerDependencies": {
"@tresjs/core": ">=4.2.1",
"three": ">=0.133",
"vue": ">=3.3"
"vue": ">=3.5.17"
},
"dependencies": {
"@vueuse/core": "^12.3.0",
Expand All @@ -74,10 +74,10 @@
"@tresjs/core": "5.0.0-next.6",
"@tresjs/eslint-config": "^1.4.0",
"@types/node": "^24.0.3",
"@types/three": "^0.177.0",
"@types/three": "^0.178.0",
"@typescript-eslint/eslint-plugin": "^8.19.0",
"@typescript-eslint/parser": "^8.19.0",
"@vitejs/plugin-vue": "^5.2.4",
"@vitejs/plugin-vue": "^6.0.0",
"eslint": "^9.27.0",
"eslint-plugin-vue": "^10.1.0",
"gsap": "^3.13.0",
Expand All @@ -86,14 +86,15 @@
"release-it": "^19.0.2",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-visualizer": "^5.13.1",
"three": "^0.176.0",
"three": "^0.178.0",
"typescript": "^5.8.3",
"unocss": "^66.1.2",
"vite": "^6.3.5",
"vite": "^7.0.2",
"vite-plugin-banner": "^0.8.1",
"vite-plugin-dts": "4.5.4",
"vite-plugin-glsl": "^1.4.1",
"vite-svg-loader": "^5.1.0",
"vitepress": "1.6.3"
"vitepress": "1.6.3",
"vue-tsc": "^3.0.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ const gl = {
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :position="[5.3, 2.45, 9.3]" :look-at="[0, 0, 0]" />
<OrbitControls />
<Suspense>
<FBXModel
scale="0.01"
:position="[0, -1.6, 0]"
:rotation-y="-Math.PI * 0.5"
cast-shadow
path="https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx"
/>
</Suspense>
<FBXModel
path="https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx"
cast-shadow
:scale="0.01"
:position="[0, -1.6, 0]"
:rotation-y="-Math.PI * 0.5"
/>
<TresMesh
:rotate-x="Math.PI * -0.5"
:position-y="-2"
Expand Down
65 changes: 65 additions & 0 deletions playground/vue/src/pages/loaders/use-fbx/TheModel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script setup lang="ts">
/* eslint-disable no-console */
import { useFBX } from '@tresjs/cientos'
import { Mesh } from 'three'

// Inject the shared state for loading progress
const state = inject<{
hasFinishLoading: boolean
progress: number
}>('fbx-loader-state')!

// Use the new reactive useFBX composable
const { state: model, isLoading, nodes, materials } = useFBX(
'https://raw.githubusercontent.com/Tresjs/assets/main/models/fbx/low-poly-truck/Jeep_done.fbx',
)

// Log nodes when they become available
watch(nodes, (newNodes) => {
console.log('FBX nodes', newNodes)
})

// Log materials when they become available
watch(materials, (newMaterials) => {
console.log('FBX materials', newMaterials)
})

// Handle model loading and apply transformations
watch(model, (newModel) => {
if (newModel) {
console.log('FBX model loaded', newModel)

// Apply transformations and shadow settings
newModel.scale.set(0.01, 0.01, 0.01)
newModel.position.set(0, -2.6, 0) // Adjusted for TresGroup position offset
newModel.rotation.y = -Math.PI * 0.5

// Enable shadows for all meshes
newModel.traverse((child) => {
if (child instanceof Mesh) {
child.castShadow = true
}
})

// Simulate loading completion after model is ready
setTimeout(() => {
state.hasFinishLoading = true
}, 500)
}
}, { immediate: true })

// Track loading state
watch(isLoading, (loading) => {
console.log('FBX loading state:', loading)
if (!loading && model.value) {
state.progress = 100
}
else {
state.progress = 0
}
}, { immediate: true })
</script>

<template>
<primitive v-if="model && !isLoading" :object="model" />
</template>
Loading