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
1 change: 0 additions & 1 deletion _external/aurora-homebrew-gui
Submodule aurora-homebrew-gui deleted from 1a1c0c
1 change: 0 additions & 1 deletion _external/dnd5e-srd
Submodule dnd5e-srd deleted from bc5222
1 change: 0 additions & 1 deletion _external/donjon-to-homebrewery
Submodule donjon-to-homebrewery deleted from f5ccb7
1 change: 0 additions & 1 deletion _external/dungeoneer
Submodule dungeoneer deleted from 39a5b3
1 change: 0 additions & 1 deletion _external/rpg-cards
Submodule rpg-cards deleted from 71e055
1 change: 0 additions & 1 deletion _external/rpgui
Submodule rpgui deleted from 048859
1 change: 0 additions & 1 deletion _external/slaytheweb
Submodule slaytheweb deleted from adf565
1 change: 0 additions & 1 deletion _realms/cardmaker_realm/cardmaker
Submodule cardmaker deleted from 6c714b
1 change: 0 additions & 1 deletion _realms/gitgud_realm/Git-Gud
Submodule Git-Gud deleted from cc425b
1 change: 0 additions & 1 deletion _realms/pdfme_realm
Submodule pdfme_realm deleted from 0cb635
1 change: 0 additions & 1 deletion _temp_latexam_study
Submodule _temp_latexam_study deleted from a88c21
1 change: 0 additions & 1 deletion _temp_science_textbook_template
Submodule _temp_science_textbook_template deleted from fe51bb
Submodule decisiontree_repo deleted from a0adfd
Submodule hannacliengine_repo deleted from e67fb2
Submodule lime_backend_repo deleted from f7323e
Submodule lime_html_repo deleted from 6d1879
Submodule lime_qml_repo deleted from e3e4b3
Submodule lime_repo deleted from 99652a
Submodule lime_termbox_repo deleted from 2137de
Submodule ArthurDantas-CV deleted from 068f70
Submodule TwentySecondsCurriculumVitae-LaTex deleted from 89743b
Submodule dnd-5e-latex-template deleted from 7f68b9
Submodule eth-zurich-article-template deleted from ca8eda
Submodule f31-templates deleted from ee937f
Submodule latex-templates-insa-toulouse deleted from 08f57c
Submodule dnd5e-latex-template deleted from 7f68b9
Submodule science-textbook-template deleted from fe51bb
1 change: 0 additions & 1 deletion lib/dnd
Submodule dnd deleted from 7f68b9
1 change: 1 addition & 0 deletions src/waft/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
def cards_status():
typer.echo("cards CLI unavailable: install optional dependency `playingcards` to enable.")

from .cli.awakening_cli import app as awakening_app
from .cli.case_render import case_render_cmd
from .cli.chief_cli import app as chief_app
from .cli.epistemic_display import (
Expand Down
1 change: 0 additions & 1 deletion standalone/404-prompt-configurator
Submodule 404-prompt-configurator deleted from bf59f9
1 change: 0 additions & 1 deletion templates/latex-cookbook
Submodule latex-cookbook deleted from ef414c
2,883 changes: 1,456 additions & 1,427 deletions uv.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions visualizer/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces

declare global {
namespace App {
// interface Error {}
Expand Down
93 changes: 17 additions & 76 deletions visualizer/src/lib/biome/caustics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,81 +15,19 @@ import {
WebGLRenderTarget
} from 'three';
import type { CausticsSettings } from './types';
import {
causticsEnvVert as envVertex,
causticsEnvFrag as envFragment,
causticsPassVert as passVertex,
causticsMarchFrag as causticsFragment
} from './shaders';

/**
* WAFT `/biome` primary optics path (Phase 4): **env-depth + bounded screen-space march**
* implemented in this module (Renou-style grounding plane), not Evan Wallaces
* implemented in this module (Renou-style grounding plane), not Evan Wallace's
* derivative caustics mesh. For MLS-MPM + SSFR see `/biome/fluid-research`.
*/

const envVertex = /* glsl */ `
varying vec3 vWorldPos;
void main() {
vec4 world = modelMatrix * vec4(position, 1.0);
vWorldPos = world.xyz;
gl_Position = projectionMatrix * viewMatrix * world;
}
`;

const envFragment = /* glsl */ `
varying vec3 vWorldPos;
void main() {
float depth = gl_FragCoord.z;
gl_FragColor = vec4(vWorldPos, depth);
}
`;

const passVertex = /* glsl */ `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position.xy, 0.0, 1.0);
}
`;

const causticsFragment = /* glsl */ `
precision highp float;
varying vec2 vUv;
uniform sampler2D envMapTex;
uniform sampler2D waterNormalTex;
uniform vec3 sunDirection;
uniform float eta;
uniform float maxSteps;
uniform float intensity;
uniform vec2 texel;
uniform float time;

float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
}

void main() {
vec3 n = normalize(texture2D(waterNormalTex, vUv + vec2(time * 0.01, time * 0.015)).xyz * 2.0 - 1.0);
vec3 refracted = normalize(refract(-normalize(sunDirection), n, 1.0 / eta));
vec2 rayUv = vUv;
float prevDepth = 0.0;
float found = 0.0;
float converged = 0.0;
for (float i = 0.0; i < 256.0; i++) {
if (i > maxSteps) break;
rayUv += refracted.xy * texel;
if (rayUv.x < 0.0 || rayUv.y < 0.0 || rayUv.x > 1.0 || rayUv.y > 1.0) break;
vec4 env = texture2D(envMapTex, rayUv);
float envDepth = env.a;
float rayDepth = prevDepth + max(refracted.z * 0.01, 0.0005);
if (rayDepth >= envDepth) {
found = 1.0;
converged = 1.0 - clamp(length(rayUv - vUv) * 2.0, 0.0, 1.0);
break;
}
prevDepth = rayDepth;
}
float noise = hash(vUv * 712.0 + time * 0.2) * 0.12;
float c = (converged + noise) * intensity * found;
gl_FragColor = vec4(vec3(c), 1.0);
}
`;

export class CausticsPipeline {
private envTarget: WebGLRenderTarget;
private causticsTarget: WebGLRenderTarget;
Expand All @@ -100,6 +38,8 @@ export class CausticsPipeline {
private passMesh: Mesh;
private lightCamera: OrthographicCamera;
private timer = new Timer();
private _scratchVec3 = new Vector3();
private _savedVisibility: boolean[] = [];

constructor(settings: CausticsSettings) {
const size = settings.resolution;
Expand Down Expand Up @@ -170,13 +110,14 @@ export class CausticsPipeline {
this.causticsMaterial.uniforms.time.value = this.timer.getElapsed();
this.causticsMaterial.uniforms.waterNormalTex.value = waterNormalMap;
this.causticsMaterial.uniforms.sunDirection.value.copy(sunDirection).normalize();
this.lightCamera.position.copy(sunDirection.clone().normalize().multiplyScalar(-280));
this._scratchVec3.copy(sunDirection).normalize().multiplyScalar(-280);
this.lightCamera.position.copy(this._scratchVec3);
this.lightCamera.lookAt(0, -20, 0);

const visibility = new Map<Mesh, boolean>();
for (const obj of underwater) {
visibility.set(obj, obj.visible);
obj.visible = true;
this._savedVisibility.length = underwater.length;
for (let i = 0; i < underwater.length; i++) {
this._savedVisibility[i] = underwater[i].visible;
underwater[i].visible = true;
}

const previous = scene.overrideMaterial;
Expand All @@ -191,8 +132,8 @@ export class CausticsPipeline {
renderer.render(this.passScene, this.passCamera);
renderer.setRenderTarget(null);

for (const [obj, isVisible] of Array.from(visibility.entries())) {
obj.visible = isVisible;
for (let i = 0; i < underwater.length; i++) {
underwater[i].visible = this._savedVisibility[i];
}
}

Expand Down
99 changes: 99 additions & 0 deletions visualizer/src/lib/biome/engine-shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {
Color,
DataTexture,
Raycaster,
RepeatWrapping,
SRGBColorSpace,
Vector2,
type Camera,
type Object3D,
type Texture
} from 'three';
import type { SeabedPreset } from './types';

// ── Shared constants ────────────────────────────────────────────────

export const BIOME_FOV = 55;
export const BIOME_NEAR = 0.1;
export const BIOME_FAR = 2400;
export const BIOME_CLEAR_COLOR = '#061626';
export const BIOME_BG_COLOR = '#0a1626';
export const BIOME_FOG_COLOR = '#12263f';
export const BIOME_FOG_NEAR = 40;
export const BIOME_FOG_FAR = 420;
export const BIOME_SKY_SCALE = 450000;
export const BIOME_ORBIT_DAMPING = 0.06;
export const BIOME_MAX_POLAR = Math.PI / 2 - 0.08;

// ── Seabed presets ──────────────────────────────────────────────────

export const SEABED_PRESETS: Record<SeabedPreset, { base: string; shallow: string }> = {
default: { base: '#375249', shallow: '#4f6f63' },
muddy: { base: '#3d2f22', shallow: '#5c4a38' },
sand: { base: '#7a6548', shallow: '#c9b896' },
coral: { base: '#4a3a55', shallow: '#6b5a7d' }
};

// ── Fallback normal texture ─────────────────────────────────────────

export function buildFallbackNormalTexture(): Texture {
const width = 128;
const height = 128;
const data = new Uint8Array(width * height * 4);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
const wave =
Math.sin((x / width) * Math.PI * 10) * 0.5 + Math.cos((y / height) * Math.PI * 12) * 0.5;
data[i] = 127 + Math.floor(wave * 18);
data[i + 1] = 127 + Math.floor(wave * 18);
data[i + 2] = 255;
data[i + 3] = 255;
}
}
const texture = new DataTexture(data, width, height);
texture.needsUpdate = true;
texture.wrapS = RepeatWrapping;
texture.wrapT = RepeatWrapping;
texture.colorSpace = SRGBColorSpace;
return texture;
}

// ── Pointer ripple helper ───────────────────────────────────────────

const _ripplePointer = new Vector2();
const _rippleRaycaster = new Raycaster();

/**
* Shared ripple logic for pointer interaction with water surface.
* Returns the boost delta to add to the engine's rippleBoost (0 if no hit).
*/
export function computeRippleBoost(
e: PointerEvent,
canvas: HTMLCanvasElement,
camera: Camera,
waterObj: Object3D | null
): number {
if ((e.buttons & 1) === 0 && e.type !== 'pointerdown') return 0;
if (!waterObj) return 0;
const rect = canvas.getBoundingClientRect();
_ripplePointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
_ripplePointer.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
_rippleRaycaster.setFromCamera(_ripplePointer, camera);
const hits = _rippleRaycaster.intersectObject(waterObj, false);
return hits.length ? 1.8 : 0;
}

// ── Debug logging ───────────────────────────────────────────────────

export function isBiomeDebugEnabled(): boolean {
if (typeof window === 'undefined') return false;
const search = window.location.search ?? '';
if (search.includes('debugBiome=1')) return true;
return new URLSearchParams(search).get('debugBiome') === '1';
}

export function debugBiome(...args: unknown[]): void {
if (!isBiomeDebugEnabled()) return;
console.warn(...args);
}
Loading
Loading