Spaces:
Runtime error
Runtime error
Upload index.html with huggingface_hub
Browse files- index.html +207 -0
index.html
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pygame
|
2 |
+
from pygame.locals import *
|
3 |
+
from OpenGL.GL import *
|
4 |
+
from OpenGL.GLU import *
|
5 |
+
import numpy as np
|
6 |
+
from scipy import ndimage
|
7 |
+
import random
|
8 |
+
|
9 |
+
# Simple 3D Earth Viewer with atmosphere, clouds, terrain, and stars
|
10 |
+
# Uses PyOpenGL and pygame for rendering
|
11 |
+
|
12 |
+
def create_sphere(radius, slices, stacks):
|
13 |
+
vertices = []
|
14 |
+
normals = []
|
15 |
+
texcoords = []
|
16 |
+
indices = []
|
17 |
+
|
18 |
+
for i in range(stacks + 1):
|
19 |
+
V = i / stacks
|
20 |
+
phi = V * np.pi
|
21 |
+
|
22 |
+
for j in range(slices + 1):
|
23 |
+
U = j / slices
|
24 |
+
theta = U * 2 * np.pi
|
25 |
+
|
26 |
+
x = radius * np.sin(phi) * np.cos(theta)
|
27 |
+
y = radius * np.cos(phi)
|
28 |
+
z = radius * np.sin(phi) * np.sin(theta)
|
29 |
+
|
30 |
+
vertices.append([x, y, z])
|
31 |
+
nx, ny, nz = x/radius, y/radius, z/radius
|
32 |
+
normals.append([nx, ny, nz])
|
33 |
+
texcoords.append([U, V])
|
34 |
+
|
35 |
+
for i in range(stacks):
|
36 |
+
for j in range(slices):
|
37 |
+
first = i * (slices + 1) + j
|
38 |
+
second = first + slices + 1
|
39 |
+
indices.append(first)
|
40 |
+
indices.append(second)
|
41 |
+
indices.append(first + 1)
|
42 |
+
|
43 |
+
indices.append(second)
|
44 |
+
indices.append(second + 1)
|
45 |
+
indices.append(first + 1)
|
46 |
+
|
47 |
+
return np.array(vertices), np.array(normals), np.array(texcoords), np.array(indices)
|
48 |
+
|
49 |
+
def create_terrain_noise(resolution=64):
|
50 |
+
# Generate procedural terrain (heightmap)
|
51 |
+
noise = np.random.randn(resolution, resolution) * 0.01
|
52 |
+
noise = ndimage.gaussian_filter(noise, sigma=2)
|
53 |
+
return noise
|
54 |
+
|
55 |
+
def create_starfield(num_stars=1000):
|
56 |
+
stars = []
|
57 |
+
for _ in range(num_stars):
|
58 |
+
theta = np.random.uniform(0, 2*np.pi)
|
59 |
+
phi = np.arccos(1 - np.random.uniform(0, 1))
|
60 |
+
r = 100 + np.random.uniform(0, 10)
|
61 |
+
x = r * np.sin(phi) * np.cos(theta)
|
62 |
+
y = r * np.cos(phi)
|
63 |
+
z = r * np.sin(phi) * np.sin(theta)
|
64 |
+
stars.append([x, y, z])
|
65 |
+
return np.array(stars)
|
66 |
+
|
67 |
+
def load_texture_from_solid_color(color, width=64, height=64):
|
68 |
+
texture_data = np.zeros((height, width, 3), dtype=np.uint8)
|
69 |
+
texture_data[:, :] = color
|
70 |
+
texture_data = texture_data.tobytes()
|
71 |
+
|
72 |
+
texture_id = glGenTextures(1)
|
73 |
+
glBindTexture(GL_TEXTURE_2D, texture_id)
|
74 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
75 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
76 |
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)
|
77 |
+
return texture_id
|
78 |
+
|
79 |
+
def load_simple_earth_texture():
|
80 |
+
# Create a simple blue marble-like texture
|
81 |
+
width, height = 1024, 512
|
82 |
+
texture_data = np.zeros((height, width, 3), dtype=np.uint8)
|
83 |
+
|
84 |
+
for y in range(height):
|
85 |
+
for x in range(width):
|
86 |
+
# Simple Earth approximation with blue oceans and green/brown continents
|
87 |
+
u, v = x / width, y / height
|
88 |
+
if np.sin(2*np.pi*u) * np.sin(np.pi*v) > 0.5 or (u-0.3)**2 + (v-0.5)**2 < 0.02:
|
89 |
+
texture_data[y, x] = [30, 100, 200] # Ocean
|
90 |
+
elif np.random.rand() < 0.3:
|
91 |
+
texture_data[y, x] = [100, 180, 80] # Land
|
92 |
+
else:
|
93 |
+
texture_data[y, x] = [30, 100, 200]
|
94 |
+
|
95 |
+
texture_data = texture_data.tobytes()
|
96 |
+
texture_id = glGenTextures(1)
|
97 |
+
glBindTexture(GL_TEXTURE_2D, texture_id)
|
98 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
99 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
100 |
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)
|
101 |
+
return texture_id
|
102 |
+
|
103 |
+
class Earth3DViewer:
|
104 |
+
def __init__(self):
|
105 |
+
pygame.init()
|
106 |
+
self.display = (800, 600)
|
107 |
+
pygame.display.set_mode(self.display, DOUBLEBUF | OPENGL)
|
108 |
+
pygame.display.set_caption("3D Earth Viewer")
|
109 |
+
|
110 |
+
gluPerspective(45, (self.display[0]/self.display[1]), 0.1, 100.0)
|
111 |
+
glTranslatef(0.0, 0.0, -15)
|
112 |
+
|
113 |
+
# Create Earth
|
114 |
+
self.vertices, self.normals, self.texcoords, self.indices = create_sphere(6.0, 32, 32)
|
115 |
+
self.cloud_vertices, _, _, _ = create_sphere(6.05, 32, 32) # Slightly bigger for cloud layer
|
116 |
+
self.atmosphere_vertices, _, _, _ = create_sphere(6.2, 32, 32) # Atmosphere glow
|
117 |
+
|
118 |
+
# Load textures
|
119 |
+
self.earth_texture = load_simple_earth_texture()
|
120 |
+
self.cloud_texture = load_texture_from_solid_color([200, 200, 255], 64, 64)
|
121 |
+
self.atmosphere_texture = load_texture_from_solid_color([150, 200, 255, 100], 64, 64)
|
122 |
+
|
123 |
+
# Create procedural terrain displacement (conceptual)
|
124 |
+
self.terrain_noise = create_terrain_noise(32)
|
125 |
+
|
126 |
+
# Stars
|
127 |
+
self.stars = create_starfield(500)
|
128 |
+
|
129 |
+
self.rotation = 0
|
130 |
+
self.cloud_rotation = 0
|
131 |
+
|
132 |
+
def draw_sphere(self, vertices, texture_id, blend=False, alpha=1.0):
|
133 |
+
if blend:
|
134 |
+
glEnable(GL_BLEND)
|
135 |
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE)
|
136 |
+
glDepthMask(GL_FALSE)
|
137 |
+
|
138 |
+
glBindTexture(GL_TEXTURE_2D, texture_id)
|
139 |
+
glEnable(GL_TEXTURE_2D)
|
140 |
+
|
141 |
+
glBegin(GL_TRIANGLES)
|
142 |
+
for i in range(0, len(self.indices), 3):
|
143 |
+
for j in range(3):
|
144 |
+
idx = self.indices[i + j]
|
145 |
+
glTexCoord2fv(self.texcoords[idx])
|
146 |
+
glVertex3fv(vertices[idx])
|
147 |
+
glEnd()
|
148 |
+
|
149 |
+
glDisable(GL_TEXTURE_2D)
|
150 |
+
if blend:
|
151 |
+
glDisable(GL_BLEND)
|
152 |
+
glDepthMask(GL_TRUE)
|
153 |
+
|
154 |
+
def draw_stars(self):
|
155 |
+
glEnable(GL_POINT_SMOOTH)
|
156 |
+
glPointSize(1.0)
|
157 |
+
glColor3f(1, 1, 1)
|
158 |
+
glBegin(GL_POINTS)
|
159 |
+
for star in self.stars:
|
160 |
+
glVertex3fv(star)
|
161 |
+
glEnd()
|
162 |
+
|
163 |
+
def render(self):
|
164 |
+
while True:
|
165 |
+
for event in pygame.event.get():
|
166 |
+
if event.type == pygame.QUIT:
|
167 |
+
pygame.quit()
|
168 |
+
return
|
169 |
+
|
170 |
+
# Handle rotation
|
171 |
+
self.rotation += 0.5
|
172 |
+
self.cloud_rotation += 0.6
|
173 |
+
|
174 |
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
175 |
+
glEnable(GL_DEPTH_TEST)
|
176 |
+
|
177 |
+
# Draw stars (background)
|
178 |
+
glPushMatrix()
|
179 |
+
glRotatef(self.rotation * 0.01, 0, 1, 0)
|
180 |
+
self.draw_stars()
|
181 |
+
glPopMatrix()
|
182 |
+
|
183 |
+
# Draw Earth
|
184 |
+
glPushMatrix()
|
185 |
+
glRotatef(self.rotation, 0, 1, 0)
|
186 |
+
self.draw_sphere(self.vertices, self.earth_texture)
|
187 |
+
glPopMatrix()
|
188 |
+
|
189 |
+
# Draw clouds
|
190 |
+
glPushMatrix()
|
191 |
+
glRotatef(self.cloud_rotation, 0, 1, 0)
|
192 |
+
self.draw_sphere(self.cloud_vertices, self.cloud_texture, blend=True, alpha=0.3)
|
193 |
+
glPopMatrix()
|
194 |
+
|
195 |
+
# Draw atmosphere glow
|
196 |
+
glPushMatrix()
|
197 |
+
glRotatef(self.rotation, 0, 1, 0)
|
198 |
+
glColor4f(0.5, 0.8, 1.0, 0.1)
|
199 |
+
self.draw_sphere(self.atmosphere_vertices, self.atmosphere_texture, blend=True, alpha=0.1)
|
200 |
+
glPopMatrix()
|
201 |
+
|
202 |
+
pygame.display.flip()
|
203 |
+
pygame.time.wait(30)
|
204 |
+
|
205 |
+
if __name__ == "__main__":
|
206 |
+
app = Earth3DViewer()
|
207 |
+
app.render()
|