r3f-managed-glb
Version:
Wrapper around the gbl/gltf loader that allows handling and customizing only selected nodes in JSX instead of generating the full JSX file.
154 lines (118 loc) • 4.07 kB
Markdown

Wrapper around the gbl/gltf loader that allows handling and customizing only selected nodes in JSX
instead of generating the full JSX file.
```bash
npm i --save r3f-managed-glb
yarn add r3f-managed-glb
```
```javascript
import { ManagedGLB, meshesInNodeByCount, preloadGLB } from 'r3f-managed-glb';
// ....
return <ManagedGLB castShadows recieveShadows path={glb} custom={custom} {...props} />;
```
```typescript
interface ManagedGLBProps {
path: string; // path to glb file
custom?: Custom; // structure to customize nodes
onInit?: ({ scene, animations, actions }) => void; // callback on init, provides scene, animations, actions from glb scene
castShadow?: boolean; // set {castShadow} for all meshes (default=true)
receiveShadow?: boolean; // set {receiveShadow} for all meshes (default=true)
debug?: boolean; // console.log the Threejs scene object (default=false)
[]: any; // other props for the root node
}
```
The render function will called with 2 arguments:
- Node - Node component (Mesh or Group)
- node - threejs node object
You able to override any props of the actual {Node}, set or get variables directly from {node}
object or just replace the node with anything you like. Just provide the {custom} prop contains the
struct with description of those nodes
```typescript
type Custom = {
[]: (Node: FC, node: THREE.Object3D) => ReactNode | null;
};
```
```javascript
import React from 'react';
import { ManagedGLB, meshesInNodeByCount, preloadGLB } from 'r3f-managed-glb';
import * as THREE from 'three';
const glb = 'assets/model.glb';
export const MyModel = (props) => {
const custom = {
// override material :
['node_001']: (Node, node) => (
<Node>
<meshStandardMaterial transparent opacity={0.1} />
</Node>
),
// or extend material ( you able to add {...node.material} to extend props of existing material)
['node_001']: (Node, node) => (
<Node>
<meshStandardMaterial {...node.material} transparent opacity={0.1} />
</Node>
),
// change scale (position, rotation, etc.):
['node_002']: (Node) => <Node scale={0.1} />,
// remove node:
['node_003']: () => null,
// hide node:
['node_004']: (Node) => <Node visible={false} />,
// several nodes selection
['node_4|node_5|node_6']: (Node) => <Node />,
// you can generate selector with function meshesInNodeByCount('node', 5) //(parentNodeName, children count),
// it returns "node_1|node_2|node_3|node_4|node_5". It useful for meshes splited by glb format
[]: (Node) => (
<Node>
<meshStandardMaterial transparent opacity={0.1} side={THREE.DoubleSide} />
</Node>
),
// dublicate node:
['node_005']: (Node, node) => {
const pos = [...node.position];
pos[1] += 2;
return (
<>
<Node />
<Node position={pos} />
</>
);
}
// modify the Threejs node object directly (may not good idea):
['node_006']: (Node, node) => {
node.position = [10,10,10]
return <Node />
}
};
return <ManagedGLB castShadows recieveShadows path={glb} custom={custom} {...props} />;
};
preloadGLB(glb); // optional, just useGLTF.preload() function
```
```javascript
import { ManagedGLB } from './ManagedGLB';
import React, { useRef } from 'react';
const glb = 'assets/animated_model.glb';
export const Anim = ({ parts, ...props }) => {
const actionsRef = useRef();
const custom = {
['node_001']: (Node) => <Node onClick={() => actionsRef.current['my_action'].play()} />
};
return (
<ManagedGLB
onInit={({ actions }) => (actionsRef.current = actions)}
src={glb}
custom={custom}
{...props}
/>
);
};
```
1. `git clone git@github.com:dsdevgit/r3f-managed-glb.git`
2. `cd r3f-managed-glb`
3. `yarn`
4. `yarn build`