Files
yggdrasil-go/frontend/src/skinrender/skin-render.tsx
Gardel f6ac467265
Some checks failed
Release / build (push) Failing after 3m38s
feat: password reset support
2025-03-30 22:22:24 +08:00

96 lines
3.6 KiB
TypeScript

/*
* Copyright (C) 2023-2025. Gardel <sunxinao@hotmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Box} from '@mui/material';
import * as THREE from 'three';
import {Canvas, RootState, useFrame, useLoader} from '@react-three/fiber';
import React from 'react';
import createPlayerModel from './utils';
import {OrbitControls} from '@react-three/drei';
import {EffectComposer, SSAO} from '@react-three/postprocessing';
import {BlendFunction} from 'postprocessing';
function PlayerModel(props: { skinUrl: string, capeUrl?: string, slim?: boolean }) {
const {skinUrl, capeUrl, slim} = props;
console.log(props);
const skinTexture: THREE.Texture = useLoader(THREE.TextureLoader, skinUrl);
skinTexture.magFilter = THREE.NearestFilter;
skinTexture.minFilter = THREE.NearestFilter;
skinTexture.anisotropy = 0;
skinTexture.needsUpdate = true;
let version = 0;
if (skinTexture.image.height > 32) {
version = 1;
}
let capeTexture: THREE.Texture | undefined = undefined;
if (capeUrl) {
capeTexture = useLoader(THREE.TextureLoader, capeUrl);
if (capeTexture) {
capeTexture.magFilter = THREE.NearestFilter;
capeTexture.minFilter = THREE.NearestFilter;
capeTexture.anisotropy = 0;
capeTexture.needsUpdate = true;
}
}
let playerModel = createPlayerModel(skinTexture, capeTexture, version, slim);
useFrame((state, delta) => {
playerModel.rotation.y += delta * 0.7;
});
return (
<primitive object={playerModel} position={[0, -10, 0]}/>
);
}
function SkinRender(props: { skinUrl: string, capeUrl?: string, slim?: boolean }) {
const onCanvasCreate = (state: RootState) => {
state.gl.shadowMap.enabled = true;
state.gl.shadowMap.type = THREE.PCFSoftShadowMap;
};
return (
<Box component="div" height="600px">
<section className="header">
<h3></h3>
</section>
<Canvas
camera={{position: [0, 15, 35], near: 5}}
gl={{antialias: true, alpha: true, preserveDrawingBuffer: true}}
onCreated={onCanvasCreate}>
<ambientLight color={0xa0a0a0}/>
<PlayerModel {...props}/>
<OrbitControls makeDefault/>
<EffectComposer>
<SSAO
blendFunction={BlendFunction.OVERLAY}
samples={30}
rings={4}
distanceThreshold={1.0}
distanceFalloff={0.0}
rangeThreshold={0.5}
rangeFalloff={0.1}
luminanceInfluence={0.9}
radius={20}
resolutionScale={0.5}
bias={0.5}
/>
</EffectComposer>
</Canvas>
</Box>
);
}
export default SkinRender;