import React, { useMemo } from "react";
import Cylinder from "3dModels/Shapes/3D/Cylinder";
import Cone from "3dModels/Shapes/3D/Cone";
import { Vector3, Euler } from "three";
interface Props {
diameter: number;
sidewallHeight: number;
hopperHeight?: number;
fillPercent: number;
}
export default function GrainFillFlat(props: Props) {
const {
diameter,
sidewallHeight,
hopperHeight = 0,
fillPercent
} = props;
const radius = diameter / 2;
// Slightly smaller to avoid z-fighting with shell
const grainRadius = radius * 0.98;
// --- volumes ---
const cylinderVolume = Math.PI * radius * radius * sidewallHeight;
const hopperVolume = hopperHeight > 0
? (1 / 3) * Math.PI * radius * radius * hopperHeight
: 0;
const totalVolume = cylinderVolume + hopperVolume;
const filledVolume = totalVolume * fillPercent;
// --- result values ---
let hopperFillHeight = 0;
let cylinderFillHeight = 0;
if (hopperHeight > 0 && filledVolume <= hopperVolume) {
// ONLY hopper filling
const ratio = filledVolume / hopperVolume;
hopperFillHeight = hopperHeight * Math.pow(ratio, 1 / 3);
cylinderFillHeight = 0;
} else {
// hopper full (or no hopper)
hopperFillHeight = hopperHeight;
const remainingVolume = filledVolume - hopperVolume;
cylinderFillHeight = Math.max(
0,
remainingVolume / (Math.PI * radius * radius)
);
}
// --- positions ---
const hopperPosition = useMemo(
() => new Vector3(
0,
-(sidewallHeight / 2 + hopperHeight) + hopperFillHeight / 2, //adding the hopper height so it starts at the cone and not the flat side
0
),
[sidewallHeight, hopperFillHeight]
);
//flip the cone so it matches the hoppers rotation with the cone pointed down
const hopperRotation = useMemo(
() => new Euler(Math.PI, 0, 0),
[]
);
const cylinderPosition = useMemo(
() => new Vector3(
0,
-sidewallHeight / 2 + cylinderFillHeight / 2,
0
),
[sidewallHeight, cylinderFillHeight]
);
// --- material ---
const grainColour = "#fff302";
return (
<>
{/* Hopper fill */}
{hopperHeight > 0 && hopperFillHeight > 0 && (
)}
{/* Cylinder fill */}
{cylinderFillHeight > 0 && (
)}
>
);
}