3D-AFrame-VR / app.py
awacke1's picture
Update app.py
86942ee verified
raw
history blame
5.29 kB
import streamlit as st
import os
import random
@st.cache_data
def scan_assets():
"""Finds all textures, bump maps, and 3D models in the current folder."""
img_exts = (".jpg", ".jpeg", ".png", ".gif")
files = [f for f in os.listdir() if os.path.isfile(f)]
textures = [
f for f in files
if f.lower().endswith(img_exts)
and not any(tag in f.lower() for tag in ("bump", "normal"))
]
bump_maps = [
f for f in files
if f.lower().endswith(img_exts)
and any(tag in f.lower() for tag in ("bump", "normal"))
]
models = [
f for f in files
if f.lower().endswith((".glb", ".gltf", ".obj"))
]
return textures, bump_maps, models
def main():
st.title("🔳 A-Frame Tilemap with Random Models")
grid_size = st.sidebar.slider("Grid Size", min_value=1, max_value=20, value=10)
textures, bump_maps, models = scan_assets()
if not textures or not models:
st.warning("⚠️ Please add at least one texture image and one .glb/.obj file to this folder.")
return
# --- Prepare <a-assets> tags ---
asset_tags = []
for i, tex in enumerate(textures):
asset_tags.append(f'<img id="tex{i}" src="{tex}">')
if bump_maps:
# just pick the first bump map
asset_tags.append(f'<img id="grassBump" src="{bump_maps[0]}">')
for i, mdl in enumerate(models):
asset_tags.append(f'<a-asset-item id="model{i}" src="{mdl}"></a-asset-item>')
assets_html = "\n ".join(asset_tags)
# JavaScript arrays of IDs
texture_list = ", ".join(f'"#tex{i}"' for i in range(len(textures)))
model_list = ", ".join(f'"model{i}"' for i in range(len(models)))
has_bump_js = "true" if bump_maps else "false"
# Material setup for ground
if bump_maps:
ground_mat = (
"ground.setAttribute('material',"
"'color: #228B22; bumpMap: #grassBump; bumpScale: 0.2');"
)
else:
ground_mat = "ground.setAttribute('material','color: #228B22');"
# --- The A-Frame HTML template ---
html_template = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tilemap Scene</title>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/aframe-extras.loaders.min.js"></script>
</head>
<body>
<a-scene>
<a-assets>
{assets_html}
</a-assets>
<!-- Lighting -->
<a-entity light="type: ambient; color: #BBB"></a-entity>
<a-entity
light="type: directional; color: #FFF; intensity: 0.6"
position="1 1 0">
</a-entity>
<a-entity
light="type: point; intensity: 0.6"
position="0 5 0">
</a-entity>
<!-- Camera -->
<a-entity
camera
look-controls
position="0 {grid_size} {grid_size}">
</a-entity>
<!-- Container for dynamic tiles & models -->
<a-entity id="tilemap"></a-entity>
</a-scene>
<script>
document.addEventListener('DOMContentLoaded', function() {{
var scene = document.querySelector('a-scene');
var tilemap = document.querySelector('#tilemap');
var textures = [{texture_list}];
var models = [{model_list}];
var grid = {grid_size};
for (var i = 0; i < grid; i++) {{
for (var j = 0; j < grid; j++) {{
var x = i - grid/2;
var z = j - grid/2;
// --- Base tile ---
var tile = document.createElement('a-box');
tile.setAttribute('width', 1);
tile.setAttribute('height', 0.1);
tile.setAttribute('depth', 1);
var tex = textures[Math.floor(Math.random() * textures.length)];
tile.setAttribute('material', 'src: ' + tex + '; repeat: 1 1');
tile.setAttribute('position', x + ' 0 ' + z);
tilemap.appendChild(tile);
// --- Random model ---
var mi = Math.floor(Math.random() * models.length);
var mid = models[mi];
var modelEl = document.createElement('a-entity');
// load both .glb/.gltf and .obj via gltf-model (requires extras loader)
modelEl.setAttribute('gltf-model', '#' + mid);
modelEl.setAttribute('scale', '0.5 0.5 0.5');
modelEl.setAttribute('position', x + ' 0.5 ' + z);
tilemap.appendChild(modelEl);
}}
}}
// --- Ground plane ---
var ground = document.createElement('a-plane');
ground.setAttribute('width', grid * 2);
ground.setAttribute('height', grid * 2);
ground.setAttribute('rotation', '-90 0 0');
{ground_mat}
ground.setAttribute('position', '0 -0.05 0');
scene.insertBefore(ground, scene.firstChild);
}});
</script>
</body>
</html>
"""
html = html_template.format(
assets_html=assets_html,
texture_list=texture_list,
model_list=model_list,
grid_size=grid_size,
ground_mat=ground_mat
)
st.components.v1.html(html, height=600, scrolling=False)
if __name__ == "__main__":
main()