Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export default function App() {
const [tiltAngle, setTiltAngle] = useState(0);
const [particleScale, setParticleScale] = useState(1);
const [gravityScale, setGravityScale] = useState(1);
const [flaskWidth, setFlaskWidth] = useState(10);
const [flaskHeight, setFlaskHeight] = useState(3);

return (
<div className="relative h-screen w-full overflow-hidden bg-gray-900">
Expand All @@ -23,6 +25,8 @@ export default function App() {
tiltAngle={tiltAngle}
particleScale={particleScale}
gravityScale={gravityScale}
flaskWidth={flaskWidth}
flaskHeight={flaskHeight}
/>
</div>

Expand Down Expand Up @@ -70,6 +74,38 @@ export default function App() {
/>
</div>


<div>
<div className="mb-2 flex items-center justify-between text-[10px] uppercase tracking-wider text-white/60">
<span>Flask Width</span>
<span>{flaskWidth.toFixed(1)}</span>
</div>
<input
type="range"
min="4"
max="18"
step="0.1"
value={flaskWidth}
onChange={(e) => setFlaskWidth(parseFloat(e.target.value))}
className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-white"
/>
</div>

<div>
<div className="mb-2 flex items-center justify-between text-[10px] uppercase tracking-wider text-white/60">
<span>Flask Height</span>
<span>{flaskHeight.toFixed(1)}</span>
</div>
<input
type="range"
min="1.6"
max="10"
step="0.1"
value={flaskHeight}
onChange={(e) => setFlaskHeight(parseFloat(e.target.value))}
className="w-full h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-white"
/>
</div>
<div>
<div className="mb-2 flex items-center justify-between text-[10px] uppercase tracking-wider text-white/60">
<span>Tilt</span>
Expand Down
27 changes: 19 additions & 8 deletions src/components/RealisticProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ interface RealisticProgressBarProps {
meshQuality?: 'high' | 'balanced' | 'low';
particleScale?: number;
gravityScale?: number;
flaskWidth?: number;
flaskHeight?: number;
}


Expand Down Expand Up @@ -54,6 +56,8 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({
meshQuality = 'low',
particleScale = 1,
gravityScale = 1,
flaskWidth = 10,
flaskHeight = 3,
}) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const progressRef = useRef(progress);
Expand All @@ -66,6 +70,12 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({
const kinematicPrevRef = useRef<KinematicSample | null>(null);
const reverseImpulseRef = useRef({ strength: 0.0, age: 1e6, deltaV: new Vec2(0, 0) });

const flaskHalfSize = {
x: Math.max(1.5, flaskWidth / 2),
y: Math.max(0.8, flaskHeight / 2),
};
const flaskRadius = Math.min(flaskHalfSize.x, flaskHalfSize.y) * 0.5;

useEffect(() => {
progressRef.current = progress;
SPH.injectWater(progress);
Expand Down Expand Up @@ -125,13 +135,13 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({

const createParticlesRoundedBox = () => {
let pos = [];
let boxSize = {x: 5.0, y: 1.5};
let boxRadius = 0.8;
let boxSize = flaskHalfSize;
let boxRadius = flaskRadius;

let minX = -7.5;
let maxX = 7.5;
let minY = -1.0;
let maxY = 5.0;
let minX = -flaskHalfSize.x - 2.0;
let maxX = flaskHalfSize.x + 2.0;
let minY = 3.0 - flaskHalfSize.y - 2.0;
let maxY = 3.0 + flaskHalfSize.y + 2.0;

const sdRoundedBox = (px: number, py: number, bx: number, by: number, r: number) => {
let qx = Math.abs(px) - bx + r;
Expand Down Expand Up @@ -159,6 +169,7 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({

const initAsync = async () => {
SPH.setGravityScale(gravityScaleRef.current);
SPH.setFlaskShape({ boxHalfSize: flaskHalfSize, radius: flaskRadius });
const bgUrl = 'https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?q=80&w=2000&auto=format&fit=crop';
const [bgTex] = await Promise.all([
GLU.loadTexture(gl, bgUrl),
Expand Down Expand Up @@ -249,7 +260,7 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({
reverseImpulseAge: reverseImpulseRef.current.age,
reverseDeltaV: reverseImpulseRef.current.deltaV,
});
Renderer.setAnimationParams(timeRef.current, waveAmplitudeRef.current, pose.position, pose.angle);
Renderer.setAnimationParams(timeRef.current, waveAmplitudeRef.current, pose.position, pose.angle, { boxHalfSize: new Vec2(flaskHalfSize.x, flaskHalfSize.y), radius: flaskRadius });

for (let i = 0; i < 8; i++) SPH.step();

Expand All @@ -269,7 +280,7 @@ export const RealisticProgressBar: React.FC<RealisticProgressBarProps> = ({
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseleave', handleMouseLeave);
};
}, [meshQuality, particleScale]);
}, [meshQuality, particleScale, flaskWidth, flaskHeight]);

return (
<canvas
Expand Down
6 changes: 4 additions & 2 deletions src/sph/ms.frag
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ uniform vec2 u_container_pos;
uniform float u_container_angle;
uniform vec2 u_sim_min;
uniform vec2 u_sim_size;
uniform vec2 u_flask_half_size;
uniform float u_flask_radius;

out vec4 outColor;

Expand Down Expand Up @@ -58,8 +60,8 @@ void main() {
}

// Параметры формы (делаем чуть шире и "коробочнее" как в вёрстке)
vec2 boxSize = vec2(5.0, 1.5);
float boxRadius = 0.8;
vec2 boxSize = u_flask_half_size;
float boxRadius = u_flask_radius;

float angle = u_container_angle;
mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
Expand Down
6 changes: 4 additions & 2 deletions src/sph/pressure.frag
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ uniform float u_container_ang_acc;
uniform float u_reverse_impulse_strength;
uniform float u_reverse_impulse_age;
uniform vec2 u_reverse_delta_v;
uniform vec2 u_flask_half_size;
uniform float u_flask_radius;

out vec4 o;

Expand Down Expand Up @@ -81,8 +83,8 @@ void main(void) {
}
}

vec2 boxSize = vec2(5.0, 1.5);
float boxRadius = 0.8;
vec2 boxSize = u_flask_half_size;
float boxRadius = u_flask_radius;

// Apply container pose from CPU kinematics
float angle = u_container_angle;
Expand Down
Loading