3DWorldBuilder / app.py
awacke1's picture
Update app.py
bb2022a verified
raw
history blame
3.14 kB
import streamlit as st # 🌐 Streamlit magic
import streamlit.components.v1 as components # 🖼️ Embed custom HTML/JS
import os # 📂 File operations
import json # 🔄 JSON encoding/decoding
import pandas as pd # 📊 DataFrame handling
import uuid # 🆔 Unique IDs
import math # ➗ Math utils
import time # ⏳ Time utilities
from gamestate import GameState # 💼 Shared game‐state singleton
# 🚀 Page setup
st.set_page_config(page_title="Infinite World Builder", layout="wide")
# 📏 Constants for world dimensions & CSV schema
SAVE_DIR = "saved_worlds"
PLOT_WIDTH = 50.0 # ↔️ Plot width in world units
PLOT_DEPTH = 50.0 # ↕️ Plot depth in world units
CSV_COLUMNS = [
'obj_id', 'type',
'pos_x', 'pos_y', 'pos_z',
'rot_x', 'rot_y', 'rot_z', 'rot_order'
]
# 🗂️ Ensure directory for plots exists
os.makedirs(SAVE_DIR, exist_ok=True)
# … your existing load_plot_metadata, load_plot_objects, save_plot_data, GameState, etc. …
# 🧠 Session state defaults
st.session_state.setdefault('selected_object','None')
st.session_state.setdefault('new_plot_name','')
st.session_state.setdefault('js_save_data_result',None)
# 🔄 Load everything
plots_metadata = load_plot_metadata()
all_initial_objects = []
for p in plots_metadata:
all_initial_objects += load_plot_objects(p['filename'], p['x_offset'], p['z_offset'])
# 🖥️ Sidebar UI
with st.sidebar:
st.title("🏗️ World Controls")
st.header("📍 Navigate Plots")
cols = st.columns(2)
i = 0
for p in sorted(plots_metadata, key=lambda x:(x['grid_x'],x['grid_z'])):
label = f"➡️ {p['name']} ({p['grid_x']},{p['grid_z']})"
if cols[i].button(label, key=f"nav_{p['id']}"):
try:
from streamlit_js_eval import streamlit_js_eval
js = f"teleportPlayer({p['x_offset']+PLOT_WIDTH/2},{p['z_offset']+PLOT_DEPTH/2});"
streamlit_js_eval(js_code=js, key=f"tp_{p['id']}")
except Exception as e:
st.error(f"TP fail: {e}")
i = (i+1)%2
st.markdown("---")
st.header("🌲 Place Objects")
# ←─── HERE: add your four builder‐tool options ────→
opts = [
"None",
"Simple House",
"Tree",
"Rock",
"Fence Post",
"Cyberpunk City Builder Kit",
"POLYGON - Fantasy Kingdom Pack",
"HEROIC FANTASY CREATURES FULL PACK VOL 1",
"POLYGON - Apocalypse Pack"
]
idx = opts.index(st.session_state.selected_object) if st.session_state.selected_object in opts else 0
sel = st.selectbox("Select:", opts, index=idx, key="selected_object_widget")
if sel != st.session_state.selected_object:
st.session_state.selected_object = sel
st.markdown("---")
st.header("💾 Save Work")
if st.button("💾 Save Current Work", key="save_button"):
from streamlit_js_eval import streamlit_js_eval
streamlit_js_eval(js_code="getSaveDataAndPosition();", key="js_save_processor")
st.rerun()
# … the rest of your existing handler for save, and main view injection …