awacke1 commited on
Commit
9c98a20
ยท
verified ยท
1 Parent(s): 1d626f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -9
app.py CHANGED
@@ -2,6 +2,7 @@ import streamlit as st
2
  import os, base64, shutil, random
3
  from pathlib import Path
4
 
 
5
  @st.cache_data
6
  def load_aframe_and_extras():
7
  return """
@@ -17,6 +18,7 @@ def load_aframe_and_extras():
17
  let maxRotSpeed = 2;
18
  let rotAccel = 0.1;
19
 
 
20
  AFRAME.registerComponent('draggable', {
21
  init: function () {
22
  this.el.addEventListener('mousedown', this.onMouseDown.bind(this));
@@ -66,9 +68,11 @@ def load_aframe_and_extras():
66
  }
67
  });
68
 
 
69
  AFRAME.registerComponent('bouncing', {/* โ€ฆ */});
70
  AFRAME.registerComponent('moving-light', {/* โ€ฆ */});
71
 
 
72
  function moveCamera(view) {
73
  var rig = document.querySelector('#rig');
74
  var gw = 8, gh = 8;
@@ -78,7 +82,7 @@ def load_aframe_and_extras():
78
  var quadrantOffset = Math.max(gw, gh) / 4; // 2 units to center on quadrants
79
  var pos, rot;
80
 
81
- rot = {x: -90, y: 0, z: 0}; // Always top-down view
82
 
83
  switch(view) {
84
  case 'center':
@@ -113,6 +117,7 @@ def load_aframe_and_extras():
113
  rig.setAttribute('rotation', rot);
114
  }
115
 
 
116
  function flyCamera(action) {
117
  var rig = document.querySelector('#rig');
118
  var pos = rig.getAttribute('position');
@@ -169,6 +174,7 @@ def load_aframe_and_extras():
169
  rig.setAttribute('position', pos);
170
  }
171
 
 
172
  function updateCameraPosition() {
173
  var rig = document.querySelector('#rig');
174
  var pos = rig.getAttribute('position');
@@ -189,6 +195,7 @@ def load_aframe_and_extras():
189
 
190
  requestAnimationFrame(updateCameraPosition);
191
 
 
192
  function fireRaycast() {
193
  var cam = document.querySelector('[camera]');
194
  var dir = new THREE.Vector3(); cam.object3D.getWorldDirection(dir);
@@ -206,6 +213,7 @@ def load_aframe_and_extras():
206
  }
207
  }
208
 
 
209
  document.addEventListener('keydown', e => {
210
  switch(e.key.toLowerCase()){
211
  case '1': moveCamera('center'); break;
@@ -232,10 +240,12 @@ def load_aframe_and_extras():
232
  </script>
233
  """
234
 
 
235
  @st.cache_data
236
  def encode_file(path):
237
  with open(path,'rb') as f: return base64.b64encode(f.read()).decode()
238
 
 
239
  def create_aframe_entity(stem, ext, pos):
240
  ry = random.uniform(0,360)
241
  if ext == 'obj':
@@ -248,6 +258,7 @@ def create_aframe_entity(stem, ext, pos):
248
  'class="raycastable" draggable></a-entity>')
249
  return ''
250
 
 
251
  @st.cache_data
252
  def generate_tilemap(files, dirpath, gw=8, gh=8):
253
  img_exts = ['webp','png','jpeg','jpg']
@@ -258,6 +269,7 @@ def generate_tilemap(files, dirpath, gw=8, gh=8):
258
  models = [f for f in files if f.split('.')[-1] in model_exts]
259
  vids = [f for f in files if f.split('.')[-1] in vid_exts]
260
 
 
261
  assets = "<a-assets>"
262
  for f in files:
263
  stem = Path(f).stem; ext=f.split('.')[-1]
@@ -273,7 +285,9 @@ def generate_tilemap(files, dirpath, gw=8, gh=8):
273
  'loop autoplay muted></video>')
274
  assets += "</a-assets>"
275
 
 
276
  entities = ""
 
277
  if vids:
278
  v = vids[0]; s = Path(v).stem
279
  entities += (f'<a-video src="#{s}" width="{gw}" height="{gh}" '
@@ -295,11 +309,14 @@ def generate_tilemap(files, dirpath, gw=8, gh=8):
295
  if models:
296
  m = random.choice(models); ext = m.split('.')[-1]; s = Path(m).stem
297
  entities += create_aframe_entity(s, ext, f"{x} 0 {z}")
298
- return assets, entities
 
299
 
 
300
  def main():
301
  st.set_page_config(layout="wide")
302
  with st.sidebar:
 
303
  st.markdown("### ๐Ÿงญ Camera Views")
304
  st.markdown("**Select Quadrant** ๐Ÿ“ท")
305
  cols = st.columns(3)
@@ -315,22 +332,32 @@ def main():
315
  cols[1].button("โฌ‡๏ธ Bottom", on_click=lambda: st.session_state.update({'camera_view': 'back'}))
316
  cols[2].button("โ†˜๏ธ Bottom-Right", on_click=lambda: st.session_state.update({'camera_view': 'angle4'}))
317
 
 
318
  st.markdown("### โž• Add Media Files")
319
- ups = st.file_uploader("Add files (png, jpeg, obj, glb, mp4, etc.):", accept_multiple_files=True)
 
 
 
320
  st.markdown("### ๐Ÿ“‹ Uploaded Model Files")
321
  directory = st.text_input("Path:", ".", key="dir")
322
  if os.path.isdir(directory):
323
  files = [f for f in os.listdir(directory) if f.split('.')[-1] in ['obj', 'glb', 'gltf']]
324
  if files:
325
  for i, f in enumerate(files, 1):
326
- st.markdown(f"{i}. {f}")
 
 
 
 
327
  else:
328
- st.markdown("No model files found.")
329
 
 
330
  if not os.path.isdir(directory):
331
- st.sidebar.error("Invalid directory")
332
  return
333
 
 
334
  types = ['obj','glb','gltf','webp','png','jpeg','jpg','mp4']
335
  if ups:
336
  for up in ups:
@@ -338,14 +365,16 @@ def main():
338
  if ext in types:
339
  with open(os.path.join(directory,up.name),'wb') as f:
340
  shutil.copyfileobj(up,f)
341
- st.sidebar.success(f"Uploaded {up.name}")
 
342
  else:
343
- st.sidebar.warning(f"Skipped {up.name}")
344
 
345
  files = [f for f in os.listdir(directory) if f.split('.')[-1] in types]
346
 
347
  spot_h = max(8,8)*1.5
348
 
 
349
  scene = f"""
350
  <a-scene embedded style="height:100vh; width:100vw; position:fixed; top:0; left:0;">
351
  <a-entity id="rig" position="0 12 0" rotation="-90 0 0">
@@ -362,9 +391,12 @@ def main():
362
  <a-text id="score" value="Score:0" position="-1.5 2 -3" scale="0.5 0.5 0.5" color="white"></a-text>
363
  """
364
 
365
- assets, ents = generate_tilemap(files, directory, 8, 8)
 
 
366
  scene += assets + ents + "</a-scene>"
367
 
 
368
  view_cmd = st.session_state.get('camera_view', 'center')
369
  if view_cmd:
370
  scene += f"<script>moveCamera('{view_cmd}');</script>"
@@ -382,5 +414,6 @@ def main():
382
  height=1000
383
  )
384
 
 
385
  if __name__ == "__main__":
386
  main()
 
2
  import os, base64, shutil, random
3
  from pathlib import Path
4
 
5
+ # ๐Ÿš€ 1. Load Aframe and Scripts: Let's get the party started with Aframe and friends! ๐ŸŽ‰
6
  @st.cache_data
7
  def load_aframe_and_extras():
8
  return """
 
18
  let maxRotSpeed = 2;
19
  let rotAccel = 0.1;
20
 
21
+ // ๐Ÿ–ฑ๏ธ 1.1 Draggable Component: Click and drag like a pro! ๐Ÿ‹๏ธ
22
  AFRAME.registerComponent('draggable', {
23
  init: function () {
24
  this.el.addEventListener('mousedown', this.onMouseDown.bind(this));
 
68
  }
69
  });
70
 
71
+ // โ›น๏ธ 1.2 Bouncing and Lights: Keep the scene lively! โœจ
72
  AFRAME.registerComponent('bouncing', {/* โ€ฆ */});
73
  AFRAME.registerComponent('moving-light', {/* โ€ฆ */});
74
 
75
+ // ๐Ÿ“ธ 1.3 Move Camera: Snap to your favorite quadrant views! ๐Ÿ–ผ๏ธ
76
  function moveCamera(view) {
77
  var rig = document.querySelector('#rig');
78
  var gw = 8, gh = 8;
 
82
  var quadrantOffset = Math.max(gw, gh) / 4; // 2 units to center on quadrants
83
  var pos, rot;
84
 
85
+ rot = {x: -90, y: 0, z: 0}; // Always top-down view ๐Ÿ“‰
86
 
87
  switch(view) {
88
  case 'center':
 
117
  rig.setAttribute('rotation', rot);
118
  }
119
 
120
+ // โœˆ๏ธ 1.4 Fly Camera: Soar through the scene with style! ๐Ÿ›ฉ๏ธ
121
  function flyCamera(action) {
122
  var rig = document.querySelector('#rig');
123
  var pos = rig.getAttribute('position');
 
174
  rig.setAttribute('position', pos);
175
  }
176
 
177
+ // ๐Ÿ”„ 1.5 Update Camera: Keep the camera flying smoothly! ๐Ÿ•Š๏ธ
178
  function updateCameraPosition() {
179
  var rig = document.querySelector('#rig');
180
  var pos = rig.getAttribute('position');
 
195
 
196
  requestAnimationFrame(updateCameraPosition);
197
 
198
+ // ๐ŸŽฏ 1.6 Fire Raycast: Zap objects with a laser beam! โšก
199
  function fireRaycast() {
200
  var cam = document.querySelector('[camera]');
201
  var dir = new THREE.Vector3(); cam.object3D.getWorldDirection(dir);
 
213
  }
214
  }
215
 
216
+ // โŒจ๏ธ 1.7 Keyboard Listener: Take control with your keys! ๐ŸŽฎ
217
  document.addEventListener('keydown', e => {
218
  switch(e.key.toLowerCase()){
219
  case '1': moveCamera('center'); break;
 
240
  </script>
241
  """
242
 
243
+ # ๐Ÿ” 2. Encode File: Sneakily encode files into base64! ๐Ÿ•ต๏ธ
244
  @st.cache_data
245
  def encode_file(path):
246
  with open(path,'rb') as f: return base64.b64encode(f.read()).decode()
247
 
248
+ # ๐Ÿฐ 3. Create Aframe Entity: Build magical 3D models! ๐Ÿช„
249
  def create_aframe_entity(stem, ext, pos):
250
  ry = random.uniform(0,360)
251
  if ext == 'obj':
 
258
  'class="raycastable" draggable></a-entity>')
259
  return ''
260
 
261
+ # ๐Ÿ—บ๏ธ 4. Generate Tilemap: Craft the world one tile at a time! ๐ŸŒ
262
  @st.cache_data
263
  def generate_tilemap(files, dirpath, gw=8, gh=8):
264
  img_exts = ['webp','png','jpeg','jpg']
 
269
  models = [f for f in files if f.split('.')[-1] in model_exts]
270
  vids = [f for f in files if f.split('.')[-1] in vid_exts]
271
 
272
+ # ๐Ÿ“ฆ 4.1 Load Assets: Pack up all the goodies! ๐ŸŽ
273
  assets = "<a-assets>"
274
  for f in files:
275
  stem = Path(f).stem; ext=f.split('.')[-1]
 
285
  'loop autoplay muted></video>')
286
  assets += "</a-assets>"
287
 
288
+ # ๐Ÿž๏ธ 4.2 Build the Scene: Lay out the tiles and models! ๐Ÿก
289
  entities = ""
290
+ model_counts = {f: 0 for f in models} # Track spawned model counts ๐Ÿ“Š
291
  if vids:
292
  v = vids[0]; s = Path(v).stem
293
  entities += (f'<a-video src="#{s}" width="{gw}" height="{gh}" '
 
309
  if models:
310
  m = random.choice(models); ext = m.split('.')[-1]; s = Path(m).stem
311
  entities += create_aframe_entity(s, ext, f"{x} 0 {z}")
312
+ model_counts[m] += 1 # Increment count for this model ๐Ÿ“ˆ
313
+ return assets, entities, model_counts
314
 
315
+ # ๐ŸŽจ 5. Main Function: Paint the canvas of your 3D world! ๐Ÿ–Œ๏ธ
316
  def main():
317
  st.set_page_config(layout="wide")
318
  with st.sidebar:
319
+ # ๐Ÿงญ 5.1 Camera Views UI: Pick your perfect angle! ๐Ÿ“
320
  st.markdown("### ๐Ÿงญ Camera Views")
321
  st.markdown("**Select Quadrant** ๐Ÿ“ท")
322
  cols = st.columns(3)
 
332
  cols[1].button("โฌ‡๏ธ Bottom", on_click=lambda: st.session_state.update({'camera_view': 'back'}))
333
  cols[2].button("โ†˜๏ธ Bottom-Right", on_click=lambda: st.session_state.update({'camera_view': 'angle4'}))
334
 
335
+ # ๐Ÿ“‚ 5.2 File Uploader: Drop your media treasures here! ๐Ÿ’Ž
336
  st.markdown("### โž• Add Media Files")
337
+ ups = st.file_uploader(
338
+ "Add files (๐Ÿ–ผ๏ธ png/jpeg, ๐Ÿฐ obj/glb/gltf, ๐Ÿ“น mp4, etc.):",
339
+ accept_multiple_files=True
340
+ )
341
  st.markdown("### ๐Ÿ“‹ Uploaded Model Files")
342
  directory = st.text_input("Path:", ".", key="dir")
343
  if os.path.isdir(directory):
344
  files = [f for f in os.listdir(directory) if f.split('.')[-1] in ['obj', 'glb', 'gltf']]
345
  if files:
346
  for i, f in enumerate(files, 1):
347
+ # Add emoji based on file type and show spawn count ๐Ÿ–Œ๏ธ
348
+ ext = f.split('.')[-1]
349
+ emoji = "๐Ÿฐ" if ext == 'obj' else "๐Ÿฏ" # ๐Ÿฐ for obj, ๐Ÿฏ for glb/gltf
350
+ count = st.session_state.get('model_counts', {}).get(f, 0)
351
+ st.markdown(f"{i}. {emoji} {f} (Spawned: {count})")
352
  else:
353
+ st.markdown("No model files found. ๐Ÿ•ธ๏ธ")
354
 
355
+ # ๐Ÿšจ 5.3 Directory Check: Make sure the path exists! ๐Ÿ›ค๏ธ
356
  if not os.path.isdir(directory):
357
+ st.sidebar.error("Invalid directory ๐Ÿšซ")
358
  return
359
 
360
+ # ๐Ÿ“ฅ 5.4 Handle Uploads: Bring in the new files! ๐Ÿ“ฆ
361
  types = ['obj','glb','gltf','webp','png','jpeg','jpg','mp4']
362
  if ups:
363
  for up in ups:
 
365
  if ext in types:
366
  with open(os.path.join(directory,up.name),'wb') as f:
367
  shutil.copyfileobj(up,f)
368
+ emoji = "๐Ÿ–ผ๏ธ" if ext in ['webp', 'png', 'jpeg', 'jpg'] else "๐Ÿฐ" if ext in ['obj', 'glb', 'gltf'] else "๐Ÿ“น"
369
+ st.sidebar.success(f"Uploaded {emoji} {up.name}")
370
  else:
371
+ st.sidebar.warning(f"Skipped {up.name} ๐Ÿšง")
372
 
373
  files = [f for f in os.listdir(directory) if f.split('.')[-1] in types]
374
 
375
  spot_h = max(8,8)*1.5
376
 
377
+ # ๐ŸŒ 5.5 Build the Scene: Create your 3D masterpiece! ๐ŸŽฌ
378
  scene = f"""
379
  <a-scene embedded style="height:100vh; width:100vw; position:fixed; top:0; left:0;">
380
  <a-entity id="rig" position="0 12 0" rotation="-90 0 0">
 
391
  <a-text id="score" value="Score:0" position="-1.5 2 -3" scale="0.5 0.5 0.5" color="white"></a-text>
392
  """
393
 
394
+ # ๐Ÿ—๏ธ 5.6 Add Assets and Entities: Fill the world with wonders! ๐ŸŒŸ
395
+ assets, ents, model_counts = generate_tilemap(files, directory, 8, 8)
396
+ st.session_state['model_counts'] = model_counts # Store counts for display ๐Ÿ“Š
397
  scene += assets + ents + "</a-scene>"
398
 
399
+ # ๐ŸŽฅ 5.7 Apply Camera Actions: Lights, camera, action! ๐ŸŽฌ
400
  view_cmd = st.session_state.get('camera_view', 'center')
401
  if view_cmd:
402
  scene += f"<script>moveCamera('{view_cmd}');</script>"
 
414
  height=1000
415
  )
416
 
417
+ # ๐Ÿ 6. Run the Show: Letโ€™s launch this 3D adventure! ๐ŸŽญ
418
  if __name__ == "__main__":
419
  main()