Spaces:
Running
Running
FlyBrain V9.0.0 Space sync (v9 release, endless world, chunk streaming, FlyAsset compiler)
6343479 verified Download src/assets/compiler/compiler.py from timfromhcs/FlyBrain-Lab: direct link, hf CLI and curl.
- Browser
- Download file 4.7 kB
-
https://huggingface.co/spaces/timfromhcs/FlyBrain-Lab/resolve/main/src/assets/compiler/compiler.py
- Command line
-
hf download hf://spaces/timfromhcs/FlyBrain-Lab/src/assets/compiler/compiler.py
-
curl -L -o compiler.py https://huggingface.co/spaces/timfromhcs/FlyBrain-Lab/resolve/main/src/assets/compiler/compiler.py
4.7 kB
| """Autonomous Asset Compiler for FlyBrain V8/V9. | |
| Implements Sections 29, 32–36, 48: | |
| - Normalizes visual mesh into calibrated physical meters | |
| - Generates low-overhead physics collision proxy (Box / Capsule / Hull) | |
| - Emits schema_version 1 FlyAsset JSON package | |
| - Content-addressed hashing avoiding redundant generation | |
| """ | |
| import os | |
| import json | |
| import hashlib | |
| import numpy as np | |
| from typing import Dict, Any, List, Optional | |
| from src.assets.compiler.types import FlyAsset, AssetClass, ColliderType, CollisionProxy, REFERENCE_SCALES_M | |
| class AssetCompiler: | |
| def __init__(self, output_dir: str = "assets/compiled"): | |
| self.output_dir = os.path.abspath(output_dir) | |
| os.makedirs(self.output_dir, exist_ok=True) | |
| def compute_asset_id(self, semantic_name: str, input_hash: str, params: Dict[str, Any]) -> str: | |
| """Section 48: Content-addressed asset identifier.""" | |
| data = f"{semantic_name}_{input_hash}_{json.dumps(params, sort_keys=True)}" | |
| return hashlib.sha256(data.encode("utf-8")).hexdigest()[:16] | |
| def compile_asset(self, | |
| semantic_name: str, | |
| category: AssetClass, | |
| visual_mesh_path: str, | |
| generator_info: str = "procedural_builder", | |
| input_hash: str = "seed42", | |
| custom_dimensions: Optional[List[float]] = None, | |
| explicit_asset_id: Optional[str] = None) -> FlyAsset: | |
| """Compiles, scale-normalizes, and builds collision proxies for an asset.""" | |
| if explicit_asset_id: | |
| full_asset_id = explicit_asset_id | |
| else: | |
| asset_id = self.compute_asset_id(semantic_name, input_hash, {"cat": category.value}) | |
| full_asset_id = f"{semantic_name}_{asset_id}" | |
| # 1. Physical Scale Normalization (Section 34) | |
| if custom_dimensions: | |
| target_dims = [float(x) for x in custom_dimensions] | |
| elif semantic_name.lower() in REFERENCE_SCALES_M: | |
| target_dims = REFERENCE_SCALES_M[semantic_name.lower()] | |
| else: | |
| # Default heuristic based on category | |
| if category == AssetClass.STRUCTURE: | |
| target_dims = [5.0, 5.0, 3.0] | |
| elif category == AssetClass.VEGETATION: | |
| target_dims = [2.0, 2.0, 4.0] | |
| elif category == AssetClass.CREATURE: | |
| target_dims = [0.5, 0.3, 0.2] | |
| else: | |
| target_dims = [1.0, 1.0, 1.0] | |
| # 2. Collision Proxy Generation (Section 35) | |
| # Dedicated box or capsule collider | |
| if category in (AssetClass.STRUCTURE, AssetClass.STATIC): | |
| coll_type = ColliderType.BOX | |
| elif category in (AssetClass.CHARACTER, AssetClass.CREATURE): | |
| coll_type = ColliderType.CAPSULE | |
| else: | |
| coll_type = ColliderType.BOX | |
| density = 500.0 if category == AssetClass.VEGETATION else 1200.0 | |
| volume_m3 = target_dims[0] * target_dims[1] * target_dims[2] | |
| computed_mass = round(float(density * volume_m3), 2) | |
| collider = CollisionProxy( | |
| type=coll_type, | |
| dimensions_m=target_dims, | |
| offset_m=[0.0, 0.0, target_dims[2] / 2.0], | |
| mass_kg=max(0.1, computed_mass), | |
| friction=[0.8, 0.1, 0.01], | |
| restitution=0.05 | |
| ) | |
| # 3. Create Package | |
| asset = FlyAsset( | |
| schema_version=1, | |
| asset_id=full_asset_id, | |
| asset_class=category, | |
| source_hash=input_hash, | |
| generator=generator_info, | |
| visual_mesh=visual_mesh_path, | |
| dimensions_m=target_dims, | |
| collision={ | |
| "type": collider.type.value, | |
| "dimensions_m": collider.dimensions_m, | |
| "offset_m": collider.offset_m, | |
| "mass_kg": collider.mass_kg, | |
| "friction": collider.friction, | |
| "restitution": collider.restitution | |
| }, | |
| physics={ | |
| "mass": collider.mass_kg, | |
| "dynamic": category in (AssetClass.RIGID_DYNAMIC, AssetClass.CHARACTER, AssetClass.CREATURE) | |
| }, | |
| provenance={ | |
| "created_at": os.path.getmtime(visual_mesh_path) if os.path.exists(visual_mesh_path) else None, | |
| "semantic_name": semantic_name, | |
| "scale_normalization": "APPLIED_PHYSICAL_METERS" | |
| } | |
| ) | |
| # Save package manifest | |
| pkg_file = os.path.join(self.output_dir, f"{asset.asset_id}.json") | |
| with open(pkg_file, "w", encoding="utf-8") as f: | |
| json.dump(asset.to_dict(), f, indent=2) | |
| return asset | |