ewebspace commited on
Commit
b001b00
·
verified ·
1 Parent(s): db85807

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +258 -0
app.py ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ from typing import Optional
4
+ import json
5
+ from pathlib import Path
6
+
7
+ # Three.js template for the space simulation
8
+ THREE_JS_TEMPLATE = """
9
+ <!DOCTYPE html>
10
+ <html>
11
+ <head>
12
+ <title>Webspace Network 3D</title>
13
+ <style>
14
+ body { margin: 0; overflow: hidden; }
15
+ canvas { display: block; }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
20
+ <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js"></script>
22
+
23
+ <script>
24
+ // Scene setup
25
+ const scene = new THREE.Scene();
26
+ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
27
+ const renderer = new THREE.WebGLRenderer({ antialias: true });
28
+ renderer.setSize(window.innerWidth, window.innerHeight);
29
+ document.body.appendChild(renderer.domElement);
30
+
31
+ // Lighting
32
+ const ambientLight = new THREE.AmbientLight(0x404040);
33
+ scene.add(ambientLight);
34
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
35
+ directionalLight.position.set(1, 1, 1);
36
+ scene.add(directionalLight);
37
+
38
+ // Generate universe from seed
39
+ const universeData = {universe_json};
40
+ const celestialBodies = [];
41
+
42
+ // Create star system
43
+ function createSystem(systemData) {{
44
+ const starGeometry = new THREE.SphereGeometry(2, 32, 32);
45
+ const starMaterial = new THREE.MeshBasicMaterial({{
46
+ color: new THREE.Color(systemData.star_color),
47
+ emissive: new THREE.Color(systemData.star_color).multiplyScalar(0.5)
48
+ }});
49
+ const star = new THREE.Mesh(starGeometry, starMaterial);
50
+ scene.add(star);
51
+
52
+ // Create planets
53
+ systemData.planets.forEach((planet, i) => {{
54
+ const planetGeometry = new THREE.SphereGeometry(planet.size, 32, 32);
55
+ const planetMaterial = new THREE.MeshStandardMaterial({{
56
+ color: new THREE.Color(planet.color),
57
+ roughness: 0.8,
58
+ metalness: 0.2
59
+ }});
60
+ const planetMesh = new THREE.Mesh(planetGeometry, planetMaterial);
61
+
62
+ // Position in orbit
63
+ const orbitRadius = 5 + (i * 3);
64
+ planetMesh.position.x = orbitRadius;
65
+ planetMesh.userData = planet;
66
+
67
+ // Add click event
68
+ planetMesh.addEventListener('click', (event) => {{
69
+ const planetInfo = event.target.userData;
70
+ parent.postMessage({{type: 'planetSelected', data: planetInfo}}, '*');
71
+ event.stopPropagation();
72
+ }});
73
+
74
+ // Create orbit path
75
+ const orbit = new THREE.Line(
76
+ new THREE.BufferGeometry().setFromPoints(
77
+ new THREE.EllipseCurve(0, 0, orbitRadius, orbitRadius, 0, Math.PI * 2, false).getPoints(100)
78
+ ),
79
+ new THREE.LineBasicMaterial({ color: 0x888888, linewidth: 1 })
80
+ );
81
+ orbit.rotation.x = Math.PI / 2;
82
+
83
+ scene.add(planetMesh);
84
+ scene.add(orbit);
85
+ celestialBodies.push({{ mesh: planetMesh, orbitRadius, speed: 0.01 + Math.random() * 0.02 }});
86
+ }});
87
+ }}
88
+
89
+ // Initialize first system
90
+ createSystem(universeData.systems[0]);
91
+
92
+ // Player ship
93
+ let playerShip;
94
+ const loader = new THREE.GLTFLoader();
95
+ loader.load(
96
+ 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/SpaceShip/glTF/SpaceShip.gltf',
97
+ (gltf) => {{
98
+ playerShip = gltf.scene;
99
+ playerShip.scale.set(0.5, 0.5, 0.5);
100
+ playerShip.position.set(0, 0, 10);
101
+ scene.add(playerShip);
102
+ }}
103
+ );
104
+
105
+ // Camera controls
106
+ const controls = new THREE.OrbitControls(camera, renderer.domElement);
107
+ controls.target.set(0, 0, 0);
108
+ controls.maxDistance = 50;
109
+ camera.position.set(0, 20, 30);
110
+
111
+ // Handle window resize
112
+ window.addEventListener('resize', () => {{
113
+ camera.aspect = window.innerWidth / window.innerHeight;
114
+ camera.updateProjectionMatrix();
115
+ renderer.setSize(window.innerWidth, window.innerHeight);
116
+ }});
117
+
118
+ // Handle messages from Gradio
119
+ window.addEventListener('message', (event) => {{
120
+ if (event.data.type === 'travelToSystem') {{
121
+ // Transition to new system
122
+ scene.children = scene.children.filter(obj => obj.type !== 'Mesh');
123
+ createSystem(universeData.systems[event.data.systemIndex]);
124
+ }}
125
+ }});
126
+
127
+ // Animation loop
128
+ function animate() {{
129
+ requestAnimationFrame(animate);
130
+
131
+ // Rotate planets
132
+ celestialBodies.forEach(body => {{
133
+ body.mesh.position.x = Math.cos(Date.now() * body.speed) * body.orbitRadius;
134
+ body.mesh.position.z = Math.sin(Date.now() * body.speed) * body.orbitRadius;
135
+ }});
136
+
137
+ controls.update();
138
+ renderer.render(scene, camera);
139
+ }}
140
+ animate();
141
+ </script>
142
+ </body>
143
+ </html>
144
+ """
145
+
146
+ class UniverseGenerator:
147
+ def __init__(self, seed=42):
148
+ self.rng = np.random.RandomState(seed)
149
+ self.star_types = {
150
+ 'O': {'color': [0.7, 0.8, 1.0], 'temp': 30000},
151
+ 'B': {'color': [0.8, 0.9, 1.0], 'temp': 20000},
152
+ 'G': {'color': [1.0, 0.93, 0.7], 'temp': 5700}
153
+ }
154
+ self.planet_types = [
155
+ {'name': 'Lava', 'color': [0.8, 0.3, 0.1]},
156
+ {'name': 'Ocean', 'color': [0.1, 0.3, 0.8]},
157
+ {'name': 'Desert', 'color': [0.9, 0.8, 0.5]}
158
+ ]
159
+
160
+ def generate_system(self, index):
161
+ star_class = self.rng.choice(list(self.star_types.keys()))
162
+ system = {
163
+ 'name': f"{star_class}-{index}",
164
+ 'star_color': self.star_types[star_class]['color'],
165
+ 'planets': []
166
+ }
167
+
168
+ num_planets = self.rng.randint(3, 7)
169
+ for i in range(num_planets):
170
+ planet_type = self.rng.choice(self.planet_types)
171
+ system['planets'].append({
172
+ 'name': f"Planet-{i}",
173
+ 'type': planet_type['name'],
174
+ 'color': planet_type['color'],
175
+ 'size': self.rng.uniform(0.5, 1.5),
176
+ 'resources': self.rng.randint(1, 5),
177
+ 'habitability': self.rng.uniform(0, 1)
178
+ })
179
+
180
+ return system
181
+
182
+ def generate_universe(self, num_systems=5):
183
+ return {
184
+ 'systems': [self.generate_system(i) for i in range(num_systems)],
185
+ 'seed': 42
186
+ }
187
+
188
+ # Initialize universe
189
+ generator = UniverseGenerator()
190
+ universe = generator.generate_universe()
191
+
192
+ def get_threejs_app():
193
+ """Generate the Three.js HTML with current universe data"""
194
+ return THREE_JS_TEMPLATE.format(universe_json=json.dumps(universe))
195
+
196
+ def travel_to_system(system_index: int):
197
+ """Handle system transition"""
198
+ system_index = max(0, min(system_index, len(universe['systems'])-1))
199
+ return {
200
+ 'system': universe['systems'][system_index],
201
+ 'html': get_threejs_app()
202
+ }
203
+
204
+ with gr.Blocks(title="Webspace Network 3D") as demo:
205
+ gr.Markdown("# 🚀 Webspace Network 3D")
206
+ gr.Markdown("Explore procedurally generated star systems in your browser")
207
+
208
+ with gr.Row():
209
+ with gr.Column(scale=2):
210
+ # Three.js renderer
211
+ html = gr.HTML(get_threejs_app(), elem_id="threejs-container")
212
+
213
+ # Navigation controls
214
+ system_slider = gr.Slider(0, len(universe['systems'])-1, step=1, label="Star System")
215
+ travel_btn = gr.Button("Engage Hyperdrive")
216
+
217
+ with gr.Column(scale=1):
218
+ # Planet info display
219
+ planet_info = gr.JSON(label="Selected Planet")
220
+ system_info = gr.JSON(label="Current System", value=universe['systems'][0])
221
+
222
+ # Debug info
223
+ debug = gr.Textbox(label="Debug Console")
224
+
225
+ # Handle planet selection from Three.js
226
+ demo.load(
227
+ None,
228
+ None,
229
+ None,
230
+ _js="""
231
+ () => {
232
+ window.addEventListener('message', (event) => {
233
+ if (event.data.type === 'planetSelected') {
234
+ return event.data.data;
235
+ }
236
+ });
237
+ return null;
238
+ }
239
+ """,
240
+ outputs=planet_info
241
+ )
242
+
243
+ # Handle system travel
244
+ travel_btn.click(
245
+ travel_to_system,
246
+ inputs=system_slider,
247
+ outputs=[system_info, html],
248
+ _js="""
249
+ (index) => {
250
+ const iframe = document.querySelector('#threejs-container iframe');
251
+ iframe.contentWindow.postMessage({type: 'travelToSystem', systemIndex: index}, '*');
252
+ return index;
253
+ }
254
+ """
255
+ )
256
+
257
+ if __name__ == "__main__":
258
+ demo.launch()