66 lines
2.7 KiB
TypeScript
66 lines
2.7 KiB
TypeScript
import { observer } from "mobx-react-lite";
|
|
import type { ObjectType, RuntimeObjectInstance } from "../types";
|
|
import { forwardRef, useMemo } from "react";
|
|
import type { Group } from "three";
|
|
import { Instance, Instances } from "@react-three/drei";
|
|
import type { ThreeEvent } from "@react-three/fiber";
|
|
import { state } from "../state";
|
|
import { TrimeshCollider } from "@react-three/rapier";
|
|
import { SyncRigidBody } from "./SyncRigidBody";
|
|
import { runInAction } from "mobx";
|
|
import { buildObjectTrimesh } from "../utils/graphics/mesh";
|
|
|
|
type ObjectViewInternalProps = {
|
|
object: Omit<RuntimeObjectInstance, 'typeId'>;
|
|
objectType: ObjectType;
|
|
onClick?: (e: ThreeEvent<MouseEvent>) => void;
|
|
}
|
|
|
|
export const ObjectViewInternal = observer(forwardRef<Group | null, ObjectViewInternalProps>(
|
|
function ({ object, objectType, onClick }, ref) {
|
|
const trimeshArgs = useMemo(
|
|
() => buildObjectTrimesh(objectType, state.world.data.voxelTypes),
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
[objectType.id]
|
|
);
|
|
|
|
return (
|
|
<SyncRigidBody
|
|
colliders={false}
|
|
gravityScale={object.physics ? 1 : 0.1}
|
|
onSync={(data) => {
|
|
runInAction(() => {
|
|
const obj = state.game?.scene.objects[object.id];
|
|
if (obj) {
|
|
obj.position = data.position;
|
|
obj.rotation = data.rotation;
|
|
obj.linearVelocity = data.linearVelocity;
|
|
obj.radialVelocity = data.radialVelocity;
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
<group
|
|
ref={ref}
|
|
name={`${object.id} (${objectType.id} instance)`}
|
|
position={object.position}
|
|
rotation={object.rotation}
|
|
scale={object.scale}
|
|
onClick={onClick}
|
|
>
|
|
{
|
|
object.cache.voxelGroups.map((vg) =>
|
|
<Instances key={vg.id} 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>
|
|
)
|
|
}
|
|
{trimeshArgs && <TrimeshCollider args={trimeshArgs} />}
|
|
</group>
|
|
</SyncRigidBody>
|
|
);
|
|
}
|
|
));
|