feat: Add legacy shaders, model I/O, and project panel functionality
continuous-integration/drone/push Build is passing

- Introduced `legacy-shaders.js` containing vertex and fragment shaders for rendering.
- Implemented `model-io.js` for parsing and encoding GLB files, ensuring compatibility with glTF 2.0.
- Created `project-panel.js` to manage project resources and survey overlays, enhancing user interaction.
- Added `solar.js` for calculating solar positions based on UTC time, latitude, and longitude.
- Developed `three-renderer.js` as a standard backend for Three.js, managing scene rendering and material synchronization.
- Included a new GLB model `dum.glb` for testing and demonstration purposes.
- Established `data_checks.mjs` for validating model data and ensuring integrity of assets.
- Created `prepare_export.py` to facilitate Blender GLB exports, maintaining material and node references.
- Added `vendor_three.py` to download and configure a local version of Three.js for the project.
This commit is contained in:
martin.fencl
2026-10-22 01:04:21 +02:00
parent c5fcd79fe9
commit ba7790daba
85 changed files with 21 additions and 18 deletions
+2 -9
View File
@@ -1,10 +1,3 @@
<?php
// Upload this whole folder, not only this file. No Node.js or database required.
header('Content-Type: text/html; charset=utf-8');
header('X-Content-Type-Options: nosniff');
$file = __DIR__ . '/app.html';
if (!is_readable($file)) {
http_response_code(500);
exit('Chybi app.html. Nahrajte celou slozku locenice.');
}
readfile($file);
readfile(__DIR__ . '/dum_3D_slunce.html');

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 325 KiB

Before

Width:  |  Height:  |  Size: 575 KiB

After

Width:  |  Height:  |  Size: 575 KiB

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 203 KiB

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@@ -8,7 +8,7 @@ import json
import bpy
ROOT=Path(__file__).resolve().parent.parent
SOURCE=ROOT/'locenice'/'models'/'dum.glb'
SOURCE=ROOT/'models'/'dum.glb'
TARGET=Path(__file__).resolve().parent/'dum_locenice.blend'
if not SOURCE.is_file():
raise FileNotFoundError(SOURCE)
@@ -16,7 +16,7 @@ if TARGET.exists():
raise FileExistsError(f'Rename or remove {TARGET} before running again.')
bpy.ops.wm.read_factory_settings(use_empty=True)
bpy.ops.import_scene.gltf(filepath=str(SOURCE))
defaults=json.loads((ROOT/'locenice'/'data'/'catalog.json').read_text())['defaults']
defaults=json.loads((ROOT/'data'/'catalog.json').read_text())['defaults']
scene=bpy.context.scene
scene.unit_settings.system='METRIC'
scene.unit_settings.scale_length=1.0
@@ -60,6 +60,6 @@ Blender reorders glTF nodes, materials and textures. The included web manifest
is indexed for the supplied GLB; the preparation tool rebinds stable IDs.
A changed wall or cabinet also requires checking web collision volumes / camera presets.
''')
scene['locenice_metadata_json']=json.dumps(json.loads((ROOT/'locenice'/'data'/'scene.json').read_text()),ensure_ascii=False)
scene['locenice_metadata_json']=json.dumps(json.loads((ROOT/'data'/'scene.json').read_text()),ensure_ascii=False)
bpy.ops.wm.save_as_mainfile(filepath=str(TARGET))
print('Saved:',TARGET)
+10
View File
@@ -0,0 +1,10 @@
<?php
// Upload this whole folder, not only this file. No Node.js or database required.
header('Content-Type: text/html; charset=utf-8');
header('X-Content-Type-Options: nosniff');
$file = __DIR__ . '/app.html';
if (!is_readable($file)) {
http_response_code(500);
exit('Chybi app.html. Nahrajte celou slozku locenice2.');
}
readfile($file);
@@ -1,8 +1,8 @@
import fs from 'node:fs';
import assert from 'node:assert/strict';
import {parseGLB,encodeGLB} from '../locenice/js/model-io.js';
import {solarPosition} from '../locenice/js/solar.js';
const root=new URL('../locenice/',import.meta.url);
import {parseGLB,encodeGLB} from '../js/model-io.js';
import {solarPosition} from '../js/solar.js';
const root=new URL('../',import.meta.url);
const bytes=new Uint8Array(fs.readFileSync(new URL('models/dum.glb',root)));
const {gltf,binary}=parseGLB(bytes);
const catalog=JSON.parse(fs.readFileSync(new URL('data/catalog.json',root),'utf8'));
@@ -102,7 +102,7 @@ def rebind(source,edited,output,metadata=None):
if __name__=='__main__':
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('edited',type=Path);parser.add_argument('--out',type=Path,default=Path('prepared'))
parser.add_argument('--source',type=Path,default=ROOT/'locenice'/'models'/'dum.glb')
parser.add_argument('--source',type=Path,default=ROOT/'models'/'dum.glb')
args=parser.parse_args()
print(rebind(args.source,args.edited,args.out))
print('Back up the website first. Replace models/dum.glb AND data/scene.json together.')
@@ -1,12 +1,12 @@
"""Optional: download pinned Three.js r180 locally, on a computer with internet.
python tools/vendor_three.py
Then upload the generated locenice/vendor folder AND data/app-config.json.
Then upload the generated locenice2/vendor folder AND data/app-config.json.
Does not upload anything. No credentials or server-side installer required.
"""
from pathlib import Path
from urllib.request import Request, urlopen
import json, re, hashlib
ROOT=Path(__file__).resolve().parent.parent/'locenice'
ROOT=Path(__file__).resolve().parent.parent
BASE='https://raw.githubusercontent.com/mrdoob/three.js/r180/'
VENDOR=ROOT/'vendor'/'three-r180'
seen=set()