| import gradio as gr |
| import numpy as np |
| from typing import Optional |
| import json |
| from pathlib import Path |
|
|
| THREE_JS_TEMPLATE = """ |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Webspace Network 3D</title> |
| <style> |
| body {{ margin: 0; overflow: hidden; }} |
| canvas {{ display: block; }} |
| </style> |
| </head> |
| <body> |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js"></script> |
| |
| <script> |
| // Scene setup |
| const scene = new THREE.Scene(); |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); |
| const renderer = new THREE.WebGLRenderer({{ antialias: true }}); |
| renderer.setSize(window.innerWidth, window.innerHeight); |
| document.body.appendChild(renderer.domElement); |
| |
| // Universe data |
| const universeData = {universe_json}; |
| |
| // Rest of your Three.js code... |
| </script> |
| </body> |
| </html> |
| """ |
|
|
| def get_threejs_app(): |
| """Generate the Three.js HTML with current universe data""" |
| |
| template = THREE_JS_TEMPLATE.replace('{', '{{').replace('}', '}}') |
| |
| return template.replace('{universe_json}', json.dumps(universe)) |
| class UniverseGenerator: |
| def __init__(self, seed=42): |
| self.rng = np.random.RandomState(seed) |
| self.star_types = { |
| 'O': {'color': [0.7, 0.8, 1.0], 'temp': 30000}, |
| 'B': {'color': [0.8, 0.9, 1.0], 'temp': 20000}, |
| 'G': {'color': [1.0, 0.93, 0.7], 'temp': 5700} |
| } |
| self.planet_types = [ |
| {'name': 'Lava', 'color': [0.8, 0.3, 0.1]}, |
| {'name': 'Ocean', 'color': [0.1, 0.3, 0.8]}, |
| {'name': 'Desert', 'color': [0.9, 0.8, 0.5]} |
| ] |
| |
| def generate_system(self, index): |
| star_class = self.rng.choice(list(self.star_types.keys())) |
| system = { |
| 'name': f"{star_class}-{index}", |
| 'star_color': self.star_types[star_class]['color'], |
| 'planets': [] |
| } |
| |
| num_planets = self.rng.randint(3, 7) |
| for i in range(num_planets): |
| planet_type = self.rng.choice(self.planet_types) |
| system['planets'].append({ |
| 'name': f"Planet-{i}", |
| 'type': planet_type['name'], |
| 'color': planet_type['color'], |
| 'size': self.rng.uniform(0.5, 1.5), |
| 'resources': self.rng.randint(1, 5), |
| 'habitability': self.rng.uniform(0, 1) |
| }) |
| |
| return system |
| |
| def generate_universe(self, num_systems=5): |
| return { |
| 'systems': [self.generate_system(i) for i in range(num_systems)], |
| 'seed': 42 |
| } |
|
|
| |
| generator = UniverseGenerator() |
| universe = generator.generate_universe() |
|
|
| def get_threejs_app(): |
| """Generate the Three.js HTML with current universe data""" |
| return THREE_JS_TEMPLATE.format(universe_json=json.dumps(universe)) |
|
|
| def travel_to_system(system_index: int): |
| """Handle system transition""" |
| system_index = max(0, min(system_index, len(universe['systems'])-1)) |
| return { |
| 'system': universe['systems'][system_index], |
| 'html': get_threejs_app() |
| } |
|
|
| with gr.Blocks(title="Webspace Network 3D") as demo: |
| gr.Markdown("# ๐ Webspace Network 3D") |
| gr.Markdown("Explore procedurally generated star systems in your browser") |
| |
| with gr.Row(): |
| with gr.Column(scale=2): |
| |
| html = gr.HTML(get_threejs_app(), elem_id="threejs-container") |
| |
| |
| system_slider = gr.Slider(0, len(universe['systems'])-1, step=1, label="Star System") |
| travel_btn = gr.Button("Engage Hyperdrive") |
| |
| with gr.Column(scale=1): |
| |
| planet_info = gr.JSON(label="Selected Planet") |
| system_info = gr.JSON(label="Current System", value=universe['systems'][0]) |
| |
| |
| debug = gr.Textbox(label="Debug Console") |
| |
| |
| demo.load( |
| None, |
| None, |
| None, |
| _js=""" |
| () => { |
| window.addEventListener('message', (event) => { |
| if (event.data.type === 'planetSelected') { |
| return event.data.data; |
| } |
| }); |
| return null; |
| } |
| """, |
| outputs=planet_info |
| ) |
| |
| |
| travel_btn.click( |
| travel_to_system, |
| inputs=system_slider, |
| outputs=[system_info, html], |
| _js=""" |
| (index) => { |
| const iframe = document.querySelector('#threejs-container iframe'); |
| iframe.contentWindow.postMessage({type: 'travelToSystem', systemIndex: index}, '*'); |
| return index; |
| } |
| """ |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |