southbank, albert_parklands, story_bridge, kangaroo_point + queen_st_mall rebuilt textured. Level builder now does: FLUX facade/road/grass/water/rock/ steel materials with box-projected UVs (roofs split to plain grey), parks, multipolygon river water (solid, cars skim it), tree nodes as low-poly cones, natural=cliff walls, and a procedural steel cantilever truss along a named bridge way (Story Bridge / Bradfield Highway, 338m). osm_xml_to_json.py assembles water relations; osm_level_args.py gains trace: mode for race paths that follow one iconic road. 11 textures via Cloudflare Workers AI flux-1-schnell (tools/flux_texture.sh, creds from .env never printed). Data (c) OpenStreetMap contributors, ODbL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
36 lines
1.6 KiB
Bash
Executable File
36 lines
1.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# Generate a texture via Cloudflare Workers AI FLUX (flux-1-schnell).
|
|
# Usage: flux_texture.sh "<prompt>" <out.jpg>
|
|
# Credentials: sourced from known .env files; accepts CLOUDFLARE_API_TOKEN/CF_API_TOKEN
|
|
# + CLOUDFLARE_ACCOUNT_ID/CF_ACCOUNT_ID. Values never printed.
|
|
set -euo pipefail
|
|
for f in ~/Documents/backnforth/.env ~/Documents/wardrobegod/.env; do
|
|
[ -f "$f" ] && set -a && source "$f" 2>/dev/null && set +a
|
|
done
|
|
TOKEN="${CLOUDFLARE_API_TOKEN:-${CF_API_TOKEN:-${CLOUDFLARE_TOKEN:-}}}"
|
|
ACCT="${CLOUDFLARE_ACCOUNT_ID:-${CF_ACCOUNT_ID:-${CLOUDFLARE_ACCOUNT:-}}}"
|
|
if [ -z "$TOKEN" ] || [ -z "$ACCT" ]; then
|
|
echo "MISSING_CREDS token_present=$([ -n "$TOKEN" ] && echo yes || echo no) acct_present=$([ -n "$ACCT" ] && echo yes || echo no)"
|
|
exit 1
|
|
fi
|
|
PROMPT="$1"
|
|
OUT="$2"
|
|
RESP=$(mktemp)
|
|
HTTP=$(curl -s -w '%{http_code}' -o "$RESP" --max-time 120 \
|
|
"https://api.cloudflare.com/client/v4/accounts/$ACCT/ai/run/@cf/black-forest-labs/flux-1-schnell" \
|
|
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
|
-d "$(python3 -c 'import json,sys; print(json.dumps({"prompt": sys.argv[1], "steps": 6}))' "$PROMPT")")
|
|
if [ "$HTTP" != "200" ]; then
|
|
echo "HTTP $HTTP: $(python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); print(d.get("errors"))' "$RESP" 2>/dev/null | head -c 200)"
|
|
rm -f "$RESP"
|
|
exit 1
|
|
fi
|
|
python3 - "$RESP" "$OUT" <<'EOF'
|
|
import base64, json, sys
|
|
d = json.load(open(sys.argv[1]))
|
|
open(sys.argv[2] + ".png", "wb").write(base64.b64decode(d["result"]["image"]))
|
|
EOF
|
|
sips -Z 512 -s format jpeg -s formatOptions 80 "$OUT.png" --out "$OUT" > /dev/null 2>&1
|
|
rm -f "$RESP" "$OUT.png"
|
|
echo "OK $OUT ($(du -h "$OUT" | cut -f1))"
|