File size: 5,293 Bytes
4d125bc
86942ee
 
4d125bc
 
86942ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d125bc
 
86942ee
 
 
 
 
 
0c656b8
3d06b33
86942ee
4d125bc
 
86942ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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()