Skip to content

Commit

Permalink
feat(core): made custom renderer determine whether materials and geom…
Browse files Browse the repository at this point in the history
…etries should be disposed
  • Loading branch information
Tinoooo committed Apr 6, 2023
1 parent 31bdd96 commit 36c8cf5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
12 changes: 7 additions & 5 deletions playground/src/components/TheConditional.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { BasicShadowMap, NoToneMapping, sRGBEncoding } from 'three'
import { BasicShadowMap, MeshToonMaterial, NoToneMapping, sRGBEncoding } from 'three'
import { reactive } from 'vue'
import { OrbitControls, useTweakPane } from '@tresjs/cientos'
import { TresCanvas } from '/@/'
Expand All @@ -22,24 +22,26 @@ const { pane } = useTweakPane()
pane.addInput(paneElements, 'boxVisible')
pane.addInput(paneElements, 'groupVisible')
const material = new MeshToonMaterial({ color: '#ff0000' })
</script>

<template>
<TresCanvas v-bind="state">
<TresPerspectiveCamera :position="[11, 11, 11]" :fov="45" :near="0.1" :far="1000" :look-at="[-8, 3, -3]" />

<TresDirectionalLight :position="[0, 8, 4]" :intensity="0.2" cast-shadow />
<TresMesh v-if="paneElements.boxVisible" :position="[0, 0, 0]">
<TresMesh v-if="paneElements.boxVisible" :position="[0, 0, 0]" :material="material">
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshToonMaterial color="#efefef" />
<!-- <TresMeshToonMaterial color="#efefef" /> -->
</TresMesh>

<TresGroup v-if="paneElements.groupVisible" :position="[0, -4, -5]">
<!-- <TresGroup v-if="paneElements.groupVisible" :position="[0, -4, -5]">
<TresMesh :position="[0, 0, 0]">
<TresBoxGeometry :args="[1, 1, 1]" />
<TresMeshToonMaterial color="#efef11" />
</TresMesh>
</TresGroup>
</TresGroup> -->
<OrbitControls></OrbitControls>
<TresAmbientLight :intensity="0.5" />
</TresCanvas>
Expand Down
2 changes: 1 addition & 1 deletion src/composables/useRenderer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ You could set windowSize=true to force the canvas to be the size of the window.`
{ immediate: true, deep: true },
)

setInterval(() => console.log(renderer.value?.info.memory), 3000) // TODO remove
setInterval(() => console.log(renderer.value?.info.memory, renderer.value?.info.programs?.length), 3000) // TODO remove

return {
renderer,
Expand Down
21 changes: 18 additions & 3 deletions src/core/nodeOps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BufferAttribute, Mesh } from 'three'
import { BufferAttribute, Mesh, Object3D } from 'three'
import { useCamera, useRaycaster, useRenderLoop, useLogger } from '/@/composables'
import { RendererOptions } from 'vue'
import { catalogue } from './catalogue'
Expand All @@ -23,6 +23,11 @@ function noop(fn: string): any {

let scene: TresObject | null = null

const OBJECT_3D_USER_DATA_KEYS = {
GEOMETRY_VIA_PROP: 'tres__geometryViaProp',
MATERIAL_VIA_PROP: 'tres__materialViaProp',
}

export const nodeOps: RendererOptions<TresObject, TresObject> = {
createElement(tag, _isSVG, _anchor, props) {
if (tag === 'template') return null
Expand Down Expand Up @@ -54,6 +59,13 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
else if (instance.isBufferGeometry) instance.attach = 'geometry'
}

// determine whether the material was passed via prop to
// prevent it's disposal when node is removed later in it's lifecycle
const { GEOMETRY_VIA_PROP, MATERIAL_VIA_PROP } = OBJECT_3D_USER_DATA_KEYS

if (props?.material?.isMaterial) (instance as Object3D).userData[MATERIAL_VIA_PROP] = true
if (props?.geometry?.isBufferGeometry) (instance as Object3D).userData[GEOMETRY_VIA_PROP] = true

return instance
},
insert(child, parent, anchor) {
Expand Down Expand Up @@ -122,8 +134,10 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
node.removeFromParent?.()

// TODO how to handle groups?
node.material?.dispose() // TODO probably disposes material also when passed via prop
node.geometry?.dispose()
const { GEOMETRY_VIA_PROP, MATERIAL_VIA_PROP } = OBJECT_3D_USER_DATA_KEYS

if (!node.userData[MATERIAL_VIA_PROP]) node.material?.dispose()
if (!node.userData[GEOMETRY_VIA_PROP]) node.geometry?.dispose()

//TODO traverse children and dispose them too

Expand Down Expand Up @@ -156,6 +170,7 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {

if (!target?.set) root = chain.reduce((acc, key) => acc[kebabToCamel(key)], root)
}

let value = nextValue
if (value === '') value = true
// Set prop, prefer atomic methods if applicable
Expand Down

0 comments on commit 36c8cf5

Please sign in to comment.