instancedMesh instead of drei instances: much higher performance
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { ObjectType, RuntimeGameObjectInstance, RuntimeObjectInstance } from "../types";
|
||||
import { useEffect, useImperativeHandle, useRef, type Ref } from "react";
|
||||
import { Euler, Quaternion, type Group } from "three";
|
||||
import { Instance, Instances } from "@react-three/drei";
|
||||
import type { VoxelGroup } from "../types/runtime/voxelGroup";
|
||||
import { useEffect, useImperativeHandle, useLayoutEffect, useRef, type Ref, memo } from "react";
|
||||
import { Euler, Matrix4, Quaternion, type Group, type InstancedMesh } from "three";
|
||||
import type { ThreeEvent } from "@react-three/fiber";
|
||||
import { ConvexHullCollider, RapierRigidBody } from "@react-three/rapier";
|
||||
import { SyncRigidBody } from "./SyncRigidBody";
|
||||
@@ -9,6 +9,30 @@ import { reaction, runInAction } from "mobx";
|
||||
import { v3toRapier } from "../utils";
|
||||
import { state } from "../state";
|
||||
|
||||
const _m4 = new Matrix4();
|
||||
|
||||
const VoxelGroupMesh = memo(function VoxelGroupMesh({ vg }: { vg: VoxelGroup }) {
|
||||
const ref = useRef<InstancedMesh>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const mesh = ref.current;
|
||||
if (!mesh)
|
||||
return;
|
||||
vg.positions.forEach(([x, y, z], i) => {
|
||||
mesh.setMatrixAt(i, _m4.makeTranslation(x, y, z));
|
||||
});
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
mesh.computeBoundingSphere();
|
||||
}, [vg]);
|
||||
|
||||
return (
|
||||
<instancedMesh ref={ref} args={[undefined, undefined, vg.positions.length]}>
|
||||
<boxGeometry args={[1, 1, 1]} />
|
||||
<meshStandardMaterial color={vg.color} opacity={vg.opacity} transparent={vg.opacity < 1} />
|
||||
</instancedMesh>
|
||||
);
|
||||
});
|
||||
|
||||
export type ObjectViewInternalHandle = {
|
||||
group: Group | null;
|
||||
rb: RapierRigidBody | null;
|
||||
@@ -118,11 +142,7 @@ export const ObjectViewInternal = function ({ object, objectType, ref, ...props
|
||||
>
|
||||
{
|
||||
object.cache.voxelGroups.map((vg) =>
|
||||
<Instances key={`${vg.id}-${object.cache.updatedAt}`} limit={vg.positions.length}>
|
||||
<boxGeometry args={[1, 1, 1]} />
|
||||
<meshStandardMaterial color={vg.color} opacity={vg.opacity} transparent={vg.opacity < 1} />
|
||||
{vg.positions.map((pos, i) => <Instance key={i} position={pos} />)}
|
||||
</Instances>
|
||||
<VoxelGroupMesh key={`${vg.id}-${object.cache.updatedAt}`} vg={vg} />
|
||||
)
|
||||
}
|
||||
{object.cache.colliderMesh && <ConvexHullCollider args={[object.cache.colliderMesh[0]]} />}
|
||||
|
||||
Reference in New Issue
Block a user