feat(simulation): optimize and persist collision viewing

This commit is contained in:
DCCONSTRUCTIONS
2026-08-26 15:18:34 +03:00
parent 5e97fa293f
commit a65ae9c285
13 changed files with 662 additions and 65 deletions
+75 -4
View File
@@ -26,6 +26,7 @@ from k1link.simulation.gaussian_pipeline_gateway import (
PROJECT_SCHEMA: Final = "missioncore.simulation-project/v1"
WORLD_MANIFEST_SCHEMA: Final = "missioncore.simulation-world-manifest/v1"
VIEWER_SETTINGS_SCHEMA: Final = "missioncore.simulation-viewer-settings/v1"
PROJECT_ID_PATTERN: Final = re.compile(r"^sim-[a-f0-9]{32}$")
SOURCE_FILE_ID_PATTERN: Final = re.compile(r"^src-[0-9]{5}-[a-f0-9]{8}$")
PROVIDER_JOB_ID_PATTERN: Final = re.compile(r"^gsp-[0-9]{14}-[a-f0-9]{8}$")
@@ -142,6 +143,7 @@ class SimulationProjectStore:
},
"artifacts": [],
"world_manifest": None,
"viewer_settings": _default_viewer_settings(),
"error": None,
"created_at_utc": now,
"updated_at_utc": now,
@@ -189,6 +191,19 @@ class SimulationProjectStore:
self._write(document)
return document
def update_viewer_settings(
self,
project_id: str,
settings: dict[str, Any],
) -> dict[str, Any]:
normalized = _viewer_settings(settings)
with self._lock:
document = self._read(project_id)
document["viewer_settings"] = normalized
document["updated_at_utc"] = utc_now_iso()
self._write(document)
return document
def upload_state(self, project_id: str, file_id: str) -> tuple[int, int]:
with self._lock:
document = self._read(project_id)
@@ -239,7 +254,7 @@ class SimulationProjectStore:
def begin_build(self, project_id: str) -> dict[str, Any]:
with self._lock:
document = self._read(project_id)
if document["status"] not in {"uploading", "failed"}:
if document["status"] not in {"uploading", "failed", "ready"}:
raise SimulationProjectConflictError("simulation project cannot start a build")
if any(
int(item["uploaded_bytes"]) != int(item["byte_length"])
@@ -371,6 +386,7 @@ class SimulationProjectStore:
or document.get("project_id") != project_id
):
raise SimulationProjectError("persisted simulation project identity is invalid")
document.setdefault("viewer_settings", _default_viewer_settings())
return document
def _write(self, document: dict[str, Any]) -> None:
@@ -421,7 +437,7 @@ class SimulationProjectService:
def begin_build(self, project_id: str) -> dict[str, Any]:
project = self.store.get(project_id)
if project.get("status") == "failed":
if project.get("status") in {"failed", "ready"}:
job_id = project["provider"].get("job_id")
if isinstance(job_id, str):
provider = self.provider_factory()
@@ -616,7 +632,7 @@ def _world_manifest(project_id: str, artifacts: list[dict[str, Any]]) -> dict[st
},
"transforms": {
"world_from_visual": [1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1],
"world_from_collision": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
"world_from_collision": [-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1],
},
}
@@ -628,11 +644,66 @@ def _collision_profile(scene_type: str) -> dict[str, Any]:
"seed_position": [0, 1, 0],
"capsule_height": 1.6,
"capsule_radius": 0.2,
"voxel_size": 0.05,
"voxel_size": 0.2 if scene_type == "outdoor" else 0.1,
"mesh_shape": "smooth",
}
def _default_viewer_settings() -> dict[str, Any]:
return {
"schema_version": VIEWER_SETTINGS_SCHEMA,
"quality": "high",
"visual": {"inverted": True, "axis": "x"},
"collision": {"inverted": True, "axis": "y"},
"camera": {
"invert_horizontal": True,
"invert_vertical": False,
},
}
def _viewer_settings(value: object) -> dict[str, Any]:
if not isinstance(value, dict) or set(value) != {
"schema_version", "quality", "visual", "collision", "camera"
}:
raise SimulationProjectError("simulation viewer settings contract is invalid")
if value.get("schema_version") != VIEWER_SETTINGS_SCHEMA:
raise SimulationProjectError("simulation viewer settings version is unsupported")
quality = value.get("quality")
if quality not in {"low", "medium", "high", "ultra", "maximum"}:
raise SimulationProjectError("simulation viewer quality is invalid")
def layer(name: str) -> dict[str, Any]:
raw = value.get(name)
if not isinstance(raw, dict) or set(raw) != {"inverted", "axis"}:
raise SimulationProjectError(f"simulation {name} transform is invalid")
inverted = raw.get("inverted")
axis = raw.get("axis")
if not isinstance(inverted, bool) or axis not in {"x", "y", "z"}:
raise SimulationProjectError(f"simulation {name} transform is invalid")
return {"inverted": inverted, "axis": axis}
camera = value.get("camera")
if not isinstance(camera, dict) or set(camera) != {
"invert_horizontal", "invert_vertical"
}:
raise SimulationProjectError("simulation camera settings are invalid")
horizontal = camera.get("invert_horizontal")
vertical = camera.get("invert_vertical")
if not isinstance(horizontal, bool) or not isinstance(vertical, bool):
raise SimulationProjectError("simulation camera settings are invalid")
return {
"schema_version": VIEWER_SETTINGS_SCHEMA,
"quality": quality,
"visual": layer("visual"),
"collision": layer("collision"),
"camera": {
"invert_horizontal": horizontal,
"invert_vertical": vertical,
},
}
def _project_name(value: str) -> str:
normalized = " ".join(value.split())
if not 1 <= len(normalized) <= 120: