import streamlit as st import os, base64, shutil, random from pathlib import Path # 🚀 1. Load Aframe and Scripts: Let's get the party started with Aframe and friends! 🎉 @st.cache_data def load_aframe_and_extras(): return """ """ # 🔐 2. Encode File: Sneakily encode files into base64! 🕵️ @st.cache_data def encode_file(path): with open(path,'rb') as f: return base64.b64encode(f.read()).decode() # 🏰 3. Create Aframe Entity: Build magical 3D models! 🪄 def create_aframe_entity(stem, ext, pos): ry = random.uniform(0,360) if ext == 'obj': return (f'') if ext in ('glb','gltf'): return (f'') return '' # 🗺️ 4. Generate Tilemap: Craft the world one tile at a time! 🌍 @st.cache_data def generate_tilemap(files, dirpath, gw=8, gh=8): img_exts = ['webp','png','jpeg','jpg'] model_exts = ['obj','glb','gltf'] vid_exts = ['mp4'] imgs = [f for f in files if f.split('.')[-1] in img_exts] models = [f for f in files if f.split('.')[-1] in model_exts] vids = [f for f in files if f.split('.')[-1] in vid_exts] # 📦 4.1 Load Assets: Pack up all the goodies! 🎁 assets = "" for f in files: stem = Path(f).stem; ext=f.split('.')[-1] data=encode_file(os.path.join(dirpath,f)) if ext in model_exts: assets += (f'') elif ext in img_exts: assets += f'' elif ext in vid_exts: assets += (f'') assets += "" # 🏞️ 4.2 Build the Scene: Lay out the tiles and models! 🏡 entities = "" model_counts = {f: 0 for f in models} # Track spawned model counts 📊 if vids: v = vids[0]; s = Path(v).stem # 📹 Adjust video dimensions to cover the tilemap while preserving aspect ratio 🎥 # Assume a common video aspect ratio (16:9) and scale to fit 8x8 tilemap videoWidth = 8 # Match tilemap width videoHeight = 8 # Match tilemap height (square to fit tilemap) entities += (f'') else: sx = -gw/2; sz = -gh/2 for i in range(gw): for j in range(gh): x,y,z = sx+i,0,sz+j if imgs: img = random.choice(imgs); s = Path(img).stem entities += (f'') sx = -gw/2; sz = -gh/2 for i in range(gw): for j in range(gh): x,y,z = sx+i,0,sz+j if models: m = random.choice(models); ext = m.split('.')[-1]; s = Path(m).stem entities += create_aframe_entity(s, ext, f"{x} 0 {z}") model_counts[m] += 1 # Increment count for this model 📈 return assets, entities, model_counts # 🎨 5. Main Function: Paint the canvas of your 3D world! 🖌️ def main(): st.set_page_config(layout="wide") with st.sidebar: # 🧭 5.1 Camera Views UI: Pick your perfect angle! 📐 st.markdown("### 🧭 Camera Views") st.markdown("**Select Quadrant** 📷") cols = st.columns(3) cols[0].button("↖️ Top-Left", on_click=lambda: st.session_state.update({'camera_view': 'angle1'})) cols[1].button("⬆️ Top", on_click=lambda: st.session_state.update({'camera_view': 'front'})) cols[2].button("↗️ Top-Right", on_click=lambda: st.session_state.update({'camera_view': 'angle2'})) cols = st.columns(3) cols[0].button("⬅️ Left", on_click=lambda: st.session_state.update({'camera_view': 'left'})) cols[1].button("🔳 Center", on_click=lambda: st.session_state.update({'camera_view': 'center'})) cols[2].button("➡️ Right", on_click=lambda: st.session_state.update({'camera_view': 'right'})) cols = st.columns(3) cols[0].button("↙️ Bottom-Left", on_click=lambda: st.session_state.update({'camera_view': 'angle3'})) cols[1].button("⬇️ Bottom", on_click=lambda: st.session_state.update({'camera_view': 'back'})) cols[2].button("↘️ Bottom-Right", on_click=lambda: st.session_state.update({'camera_view': 'angle4'})) # 📂 5.2 File Uploader: Drop your media treasures here! 💎 st.markdown("### ➕ Add Media Files") ups = st.file_uploader( "🖼️ png/jpeg, 🏰 obj/glb/gltf, 📹 mp4:", accept_multiple_files=True ) st.markdown("### 📋 Uploaded Model Files") directory = st.text_input("", ".", key="dir", placeholder="Enter directory path (e.g., '.')") if os.path.isdir(directory): files = [f for f in os.listdir(directory) if f.split('.')[-1] in ['obj', 'glb', 'gltf']] if files: for i, f in enumerate(files, 1): # Add emoji based on file type and show spawn count 🖌️ ext = f.split('.')[-1] emoji = "🏰" if ext == 'obj' else "🏯" # 🏰 for obj, 🏯 for glb/gltf count = st.session_state.get('model_counts', {}).get(f, 0) st.markdown(f"{i}. {emoji} {f} (Spawned: {count})") else: st.markdown("No model files found. 🕸️") # 🚨 5.3 Directory Check: Make sure the path exists! 🛤️ if not os.path.isdir(directory): st.sidebar.error("Invalid directory 🚫") return # 📥 5.4 Handle Uploads: Bring in the new files! 📦 types = ['obj','glb','gltf','webp','png','jpeg','jpg','mp4'] if ups: for up in ups: ext=Path(up.name).suffix.lower()[1:] if ext in types: with open(os.path.join(directory,up.name),'wb') as f: shutil.copyfileobj(up,f) emoji = "🖼️" if ext in ['webp', 'png', 'jpeg', 'jpg'] else "🏰" if ext in ['obj', 'glb', 'gltf'] else "📹" st.sidebar.success(f"Uploaded {emoji} {up.name}") else: st.sidebar.warning(f"Skipped {up.name} 🚧") files = [f for f in os.listdir(directory) if f.split('.')[-1] in types] spot_h = max(8,8)*1.5 # 🌐 5.5 Build the Scene: Create your 3D masterpiece! 🎬 scene = f""" """ # 🏗️ 5.6 Add Assets and Entities: Fill the world with wonders! 🌟 assets, ents, model_counts = generate_tilemap(files, directory, 8, 8) st.session_state['model_counts'] = model_counts # Store counts for display 📊 scene += assets + ents + "" # 🎥 5.7 Apply Camera Actions: Lights, camera, action! 🎬 view_cmd = st.session_state.get('camera_view', 'center') if view_cmd: scene += f"" st.session_state.pop('camera_view', None) fly_cmd = st.session_state.get('fly_action') if fly_cmd: scene += f"" st.session_state.pop('fly_action', None) loader = '' st.components.v1.html( load_aframe_and_extras() + loader + scene, height=1000 ) # 🏁 6. Run the Show: Let’s launch this 3D adventure! 🎭 if __name__ == "__main__": main()