primitive
is not a subset of mesh. it can be a children of group
.
primitive
requires both geometry and material as props. Mesh
requires both geometry and material as props. it's pretty obvious both cannot be used as subset of each other.
- to implement your idea, you need to use only one
Mesh
or primitive
. I'd suggest using Mesh
which has abundant documentations. primitive
is not documented enough.
- the
OBJ
acquired through useLoader
may have complex group inside it. Models usually contain larger sets such as group
or scene
. Group and Scenes can't have textures. Mesh
can.
OBJ(result of useLoader) = scene => group => mesh => geometry, texture
traversing is required to acquire geometry from mesh.
// I've implemented this with Typescript,
// but it is not necessary to use 'as' for type conversion.
const obj = useLoader(OBJLoader, "/rock.obj");
const texture = useTexture("/guide.png");
const geometry = useMemo(() => {
let g;
obj.traverse((c) => {
if (c.type === "Mesh") {
const _c = c as Mesh;
g = _c.geometry;
}
});
return g;
}, [obj]);
// I've used meshPhysicalMaterial because the texture needs lights to be seen properly.
return (
<mesh geometry={geometry} scale={0.04}>
<meshPhysicalMaterial map={texture} />
</mesh>
);
I've implemented it in codesandbox. here's the working code:
https://codesandbox.io/s/crazy-dawn-i6vzb?file=/src/components/Rock.tsx:257-550