silphius/app/react/components/pixi/sprite.jsx
2024-07-30 09:56:53 -05:00

103 lines
2.2 KiB
JavaScript

import {Sprite as PixiSprite} from '@pixi/react';
import {memo, useEffect, useState} from 'react';
import {useAsset} from '@/react/context/assets.js';
import {deferredLighting} from './lights.js';
function textureFromAsset(asset, animation, frame) {
if (!asset) {
return undefined;
}
let texture;
if (asset.data.animations) {
if (!animation) {
return undefined;
}
texture = asset.animations[animation][frame];
}
else {
texture = asset.textures[''];
}
return texture;
}
function Sprite(props) {
const {
alpha,
anchor,
animation,
direction,
frame,
scale,
rotates,
rotation,
source,
tint,
...rest
} = props;
const [mounted, setMounted] = useState();
const [normals, setNormals] = useState();
const [normalsMounted, setNormalsMounted] = useState();
const asset = useAsset(source);
const normalsAsset = useAsset(normals);
useEffect(() => {
if (!asset) {
return;
}
const {normals} = asset.data.meta;
if (normals) {
const {pathname} = new URL(
source.split('/').slice(0, -1).concat(normals).join('/'),
'http://example.org',
);
setNormals(pathname);
}
}, [asset, source]);
const texture = textureFromAsset(
asset,
animation,
frame,
);
const normalsTexture = textureFromAsset(
normalsAsset,
animation,
frame,
);
if (mounted) {
mounted.parentGroup = deferredLighting.diffuseGroup;
}
if (normalsMounted) {
normalsMounted.parentGroup = deferredLighting.normalGroup;
}
return (
<>
{texture && (
<PixiSprite
alpha={alpha}
anchor={anchor}
ref={setMounted}
{...(rotates ? {rotation: direction + rotation} : {})}
scale={scale}
texture={texture}
{...(0 !== tint ? {tint} : {})}
{...rest}
/>
)}
{normalsTexture && (
<PixiSprite
alpha={alpha}
anchor={anchor}
ref={setNormalsMounted}
{...(rotates ? {rotation: direction + rotation} : {})}
scale={scale}
texture={normalsTexture}
{...rest}
/>
)}
</>
);
}
export default memo(Sprite);