graphics and settings

This commit is contained in:
tresabhi committed 2026-06-16 19:44:58 -05:00
1 parent 7e2fba35d0
commit b572ac5ea8
15 files changed
+367 -8

No files matched your search

@@ -0,0 +1,37 @@
import { CaretLeftIcon, CaretRightIcon } from "@radix-ui/react-icons";
import { type ReactNode } from "react";
interface Props {
value: number;
onChange: (value: number) => void;
options: ReactNode[];
}
export function Carousel({ value, onChange, options }: Props) {
const isMin = value === 0;
const isMax = value === options.length - 1;
return (
<div>
<div
data-disabled={isMin}
onClick={() => {
if (!isMin) onChange(value - 1);
}}
>
<CaretLeftIcon />
</div>
<div>{options[value]}</div>
<div
data-disabled={isMax}
onClick={() => {
if (!isMax) onChange(value + 1);
}}
>
<CaretRightIcon />
</div>
</div>
);
}
@@ -1,14 +1,15 @@
import type { ComponentProps } from "react";
import { classNames } from "../../ui/classNames";
import { Text, type TextProps } from "../Text";
import styles from "./index.module.css";
export interface CodeProps extends ComponentProps<"code"> {
export interface CodeProps extends TextProps {
lowContrast?: boolean;
variant?: "ghost" | "solid";
}
export function Code({ className, variant = "ghost", ...props }: CodeProps) {
return (
<code
<Text
data-variant={variant}
className={classNames(styles.code, className)}
{...props}
@@ -0,0 +1,29 @@
.stats {
padding: var(--space-3);
gap: var(--space-3);
z-index: 1;
display: flex;
flex-direction: column;
position: absolute;
top: 0;
left: 0;
.graphs {
display: flex;
gap: var(--space-2);
.graph {
position: static !important;
}
}
.settings {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
}
@@ -0,0 +1,40 @@
import { Stats } from "@react-three/drei";
import { useRef } from "react";
import { settingsOrder } from "../../config/settings";
import { useSettingDeferred } from "../../hooks/useSetting";
import { Settings } from "../../stores/settings";
import { Code } from "../Code";
import styles from "./index.module.css";
const stats = [0, 1, 2];
export function RendererStats() {
const renderStatistics = useSettingDeferred("render_statistics");
if (!renderStatistics) return null;
return <Inner />;
}
function Inner() {
const parent = useRef<HTMLDivElement>(null!);
const settings = Settings.use();
return (
<div className={styles.stats}>
<div ref={parent} className={styles.graphs}>
{stats.map((stat) => (
<Stats parent={parent} showPanel={stat} className={styles.graph} />
))}
</div>
<div className={styles.settings}>
{settingsOrder[0].settings.map((setting) => (
<Code lowContrast size="minor">
{setting} = {settings[setting]}
</Code>
))}
</div>
</div>
);
}
@@ -1,6 +1,8 @@
import { useGLTF } from "@react-three/drei";
import { useEffect } from "react";
import { Mesh, MeshStandardMaterial } from "three";
import { SettingQuality3 } from "../config/settings";
import { useSetting } from "../hooks/useSetting";
interface Props {
url: string;
@@ -8,6 +10,9 @@ interface Props {
}
export function TankModelPart({ url, map }: Props) {
const tankQuality = useSetting<SettingQuality3>("tank_quality");
const lightingQuality = useSetting<SettingQuality3>("lighting_quality");
const gltf = useGLTF(url);
const [root] = gltf.scene.children;
@@ -17,16 +22,32 @@ export function TankModelPart({ url, map }: Props) {
// TODO: remove this hack and fix the gltf
material.vertexColors = false;
material.needsUpdate = true;
if (tankQuality <= SettingQuality3.Medium) {
material.normalMap = null;
}
if (tankQuality <= SettingQuality3.Low) {
material.metalness = 0;
material.roughness = 1;
material.metalnessMap = null;
material.roughnessMap = null;
}
if (tankQuality <= SettingQuality3.Medium) {
material.aoMap = null;
}
}
}
for (const node of Object.values(gltf.nodes)) {
if (node instanceof Mesh) {
node.castShadow = true;
node.receiveShadow = true;
node.castShadow = lightingQuality >= SettingQuality3.Medium;
node.receiveShadow = lightingQuality >= SettingQuality3.High;
}
}
}, [url]);
}, [url, tankQuality]);
useEffect(() => {
for (const child of root.children) {
@@ -10,7 +10,7 @@
height: 100%;
.canvas {
background-color: black;
background-color: black;
}
}
}
@@ -1,6 +1,7 @@
import { type StageParameters } from "@protos/blitz_static_tank_upgrade_single_stage";
import { Canvas } from "@react-three/fiber";
import { fov } from "../../config/camera";
import { RendererStats } from "../RendererStats";
import { TankModelChassis } from "../TankModelChassis";
import { TankModelGun } from "../TankModelGun";
import { TankModelHull } from "../TankModelHull";
@@ -17,7 +18,9 @@ interface TankopediaSandboxProps {
export function TankopediaSandbox({ parameters }: TankopediaSandboxProps) {
return (
<div className={styles.wrapper}>
<div className={styles.sandbox}>
<div className={styles.sandbox} id="canvas-attach">
<RendererStats />
<Canvas
camera={{ fov }}
shadows