Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
import base64
|
4 |
+
from pathlib import Path
|
5 |
+
import shutil
|
6 |
+
import random
|
7 |
+
|
8 |
+
# 🌈 Load A-Frame and custom components
|
9 |
+
@st.cache_data
|
10 |
+
def load_aframe_and_extras():
|
11 |
+
return """
|
12 |
+
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
|
13 |
+
<script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script>
|
14 |
+
<script>
|
15 |
+
// 🕹️ Make objects draggable
|
16 |
+
AFRAME.registerComponent('draggable', {
|
17 |
+
// ... (draggable component code remains the same)
|
18 |
+
});
|
19 |
+
|
20 |
+
// 🦘 Make objects bounce
|
21 |
+
AFRAME.registerComponent('bouncing', {
|
22 |
+
// ... (bouncing component code remains the same)
|
23 |
+
});
|
24 |
+
|
25 |
+
// 💡 Create moving light sources
|
26 |
+
AFRAME.registerComponent('moving-light', {
|
27 |
+
// ... (moving-light component code remains the same)
|
28 |
+
});
|
29 |
+
|
30 |
+
// 📷 Camera controls
|
31 |
+
function moveCamera(direction) {
|
32 |
+
var camera = document.querySelector('[camera]');
|
33 |
+
var rig = document.querySelector('#rig');
|
34 |
+
var pos = rig.getAttribute('position');
|
35 |
+
var rot = rig.getAttribute('rotation');
|
36 |
+
var speed = 0.5;
|
37 |
+
var rotationSpeed = 5;
|
38 |
+
|
39 |
+
switch(direction) {
|
40 |
+
case 'up':
|
41 |
+
pos.z -= speed;
|
42 |
+
break;
|
43 |
+
case 'down':
|
44 |
+
pos.z += speed;
|
45 |
+
break;
|
46 |
+
case 'left':
|
47 |
+
pos.x -= speed;
|
48 |
+
break;
|
49 |
+
case 'right':
|
50 |
+
pos.x += speed;
|
51 |
+
break;
|
52 |
+
case 'rotateLeft':
|
53 |
+
rot.y += rotationSpeed;
|
54 |
+
break;
|
55 |
+
case 'rotateRight':
|
56 |
+
rot.y -= rotationSpeed;
|
57 |
+
break;
|
58 |
+
case 'reset':
|
59 |
+
pos = {x: 0, y: 10, z: 0};
|
60 |
+
rot = {x: -90, y: 0, z: 0};
|
61 |
+
break;
|
62 |
+
case 'ground':
|
63 |
+
pos = {x: 0, y: 1.6, z: 0};
|
64 |
+
rot = {x: 0, y: 0, z: 0};
|
65 |
+
break;
|
66 |
+
}
|
67 |
+
|
68 |
+
rig.setAttribute('position', pos);
|
69 |
+
rig.setAttribute('rotation', rot);
|
70 |
+
}
|
71 |
+
|
72 |
+
// ⌨️ Keyboard controls
|
73 |
+
document.addEventListener('keydown', function(event) {
|
74 |
+
switch(event.key.toLowerCase()) {
|
75 |
+
case 'q':
|
76 |
+
moveCamera('rotateLeft');
|
77 |
+
break;
|
78 |
+
case 'e':
|
79 |
+
moveCamera('rotateRight');
|
80 |
+
break;
|
81 |
+
case 'z':
|
82 |
+
moveCamera('reset');
|
83 |
+
break;
|
84 |
+
case 'c':
|
85 |
+
moveCamera('ground');
|
86 |
+
break;
|
87 |
+
}
|
88 |
+
});
|
89 |
+
</script>
|
90 |
+
"""
|
91 |
+
|
92 |
+
# ... (The rest of the functions remain the same)
|
93 |
+
|
94 |
+
# 🎭 Main function to run the Streamlit app
|
95 |
+
def main():
|
96 |
+
st.set_page_config(layout="wide")
|
97 |
+
|
98 |
+
with st.sidebar:
|
99 |
+
st.markdown("### 🤖 3D AI Using Claude 3.5 Sonnet for AI Pair Programming")
|
100 |
+
|
101 |
+
st.markdown("[Open 3D Animation Toolkit](https://huggingface.co/spaces/awacke1/3d_animation_toolkit)", unsafe_allow_html=True)
|
102 |
+
|
103 |
+
st.markdown("### ⬆️ Upload")
|
104 |
+
uploaded_files = st.file_uploader("Add files:", accept_multiple_files=True, key="file_uploader")
|
105 |
+
|
106 |
+
st.markdown("### 🎮 Camera Controls")
|
107 |
+
col1, col2, col3 = st.columns(3)
|
108 |
+
with col1:
|
109 |
+
st.button("⬅️", on_click=lambda: st.session_state.update({'camera_move': 'left'}))
|
110 |
+
st.button("🔄↺", on_click=lambda: st.session_state.update({'camera_move': 'rotateLeft'}))
|
111 |
+
st.button("🔝", on_click=lambda: st.session_state.update({'camera_move': 'reset'}))
|
112 |
+
with col2:
|
113 |
+
st.button("⬆️", on_click=lambda: st.session_state.update({'camera_move': 'up'}))
|
114 |
+
st.button("🔄↻", on_click=lambda: st.session_state.update({'camera_move': 'rotateRight'}))
|
115 |
+
st.button("👀", on_click=lambda: st.session_state.update({'camera_move': 'ground'}))
|
116 |
+
with col3:
|
117 |
+
st.button("➡️", on_click=lambda: st.session_state.update({'camera_move': 'right'}))
|
118 |
+
st.button("⬇️", on_click=lambda: st.session_state.update({'camera_move': 'down'}))
|
119 |
+
|
120 |
+
st.markdown("### 🗺️ Grid Size")
|
121 |
+
grid_width = st.slider("Grid Width", 1, 8, 8)
|
122 |
+
grid_height = st.slider("Grid Height", 1, 5, 5)
|
123 |
+
|
124 |
+
st.markdown("### ℹ️ Instructions")
|
125 |
+
st.write("- WASD: Move camera")
|
126 |
+
st.write("- Q/E: Rotate camera left/right")
|
127 |
+
st.write("- Z: Reset camera to top view")
|
128 |
+
st.write("- C: Move camera to ground level")
|
129 |
+
st.write("- Click and drag to move objects")
|
130 |
+
st.write("- Mouse wheel to zoom")
|
131 |
+
st.write("- Right-click and drag to rotate view")
|
132 |
+
|
133 |
+
st.markdown("### 📁 Directory")
|
134 |
+
directory = st.text_input("Enter path:", ".", key="directory_input")
|
135 |
+
|
136 |
+
# ... (The rest of the main function remains the same)
|
137 |
+
|
138 |
+
camera_move = st.session_state.get('camera_move', None)
|
139 |
+
if camera_move:
|
140 |
+
aframe_scene += f"<script>moveCamera('{camera_move}');</script>"
|
141 |
+
st.session_state.pop('camera_move')
|
142 |
+
|
143 |
+
st.components.v1.html(load_aframe_and_extras() + aframe_scene, height=600)
|
144 |
+
|
145 |
+
if __name__ == "__main__":
|
146 |
+
main()
|