Removing Generics from Meshes causes a lot of headaches
See original GitHub issueDescribe the bug
For some context, i’m using react-three-fiber
. My use case is when i’m loading a GLTF
model, to TS it’s a black box, So I know it’s a mesh & can typecast the return of the gltf
to be Mesh
. However, when I want to edit the properties of the mesh materials, I now have to typecast the material because Mesh
is no longer a generic. This is quite a headache. I’m not saying i’m right, it’d be good to get some clarity on why this commit was done?
Old Code
type GLTFResult = GLTF &
ObjectMap & {
nodes: {
[name: string]: Mesh<BufferGeometry, MeshStandardMaterial>
}
}
const { nodes } = useGLTF(
`${ENV_MODEL_PATH}/rain/RainPond_Droplets_Polyredux.gltf`
) as GLTFResult
const instanceMeshes = React.useMemo(
() =>
meshes
.filter((mesh) => mesh.material)
.map((mesh, i) => {
mesh.material.metalness = 0 // all good here, no typecast needed
mesh.material.transparent = true
mesh.material.onBeforeCompile = compileMaterialForInstance
mesh.geometry.setAttribute(
'instOpacity',
new InstancedBufferAttribute(
new Float32Array(new Array(INSTANCE_COUNT).fill(0)),
1
)
)
return (
<instancedMesh
ref={(ref: THREE.InstancedMesh) =>
setKeyValue(instanceRefs.current, i, ref)
}
key={mesh.name}
args={[mesh.geometry, mesh.material, INSTANCE_COUNT]}
/>
)
}),
[meshes]
)
New Code
type GLTFResult = GLTF &
ObjectMap & {
nodes: {
[name: string]: Mesh
}
}
const { nodes } = useGLTF(
`${ENV_MODEL_PATH}/rain/RainPond_Droplets_Polyredux.gltf`
) as GLTFResult
const instanceMeshes = React.useMemo(
() =>
meshes
.filter((mesh) => mesh.material)
.map((mesh, i) => {
mesh.material.metalness = 0 // this now throws an error because metalness does not exist on type Material[]
mesh.material.transparent = true
mesh.material.onBeforeCompile = compileMaterialForInstance
mesh.geometry.setAttribute(
'instOpacity',
new InstancedBufferAttribute(
new Float32Array(new Array(INSTANCE_COUNT).fill(0)),
1
)
)
return (
<instancedMesh
ref={(ref: THREE.InstancedMesh) =>
setKeyValue(instanceRefs.current, i, ref)
}
key={mesh.name}
args={[mesh.geometry, mesh.material, INSTANCE_COUNT]}
/>
)
}),
[meshes]
)
Expected behavior
Ideally i’d like to pass the Generics back in, because even if it was able to figure out if it was Material
or Material[]
I know the material is MeshStandardMaterial
so metalness
will still throw a typescript error.
disclaimer I’m happy to work on a solution if we want to fix this.
Platform:
- Three.js version: r125
Issue Analytics
- State:
- Created 3 years ago
- Comments:19 (19 by maintainers)
Top GitHub Comments
And that’s how you force JavaScript people learn TypeScript. Makes contributing harder.
I’m not liking this at all.
Fair enough.