Files
Mujoco_WASM/web_platform/src/map/MapStackComposer.ts
T
chenlin a9b07e0abf
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
feat(web-platform): release V0.8.1 常规地图优化
2026-09-03 13:18:35 +08:00

69 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ProjectManifest } from '../project/types';
import { resolveProjectMap } from './MapLoader';
import { composeProjectMap } from './MapComposer';
import { composePhysicalMap } from './physicalMap';
import { isSystemTerrainPreset, type PlacedMapAsset } from './types';
export interface MapStackComposition {
data: Uint8Array;
geomCount: number;
warnings: string[];
}
/** 将全部已放置地图实例依次合成到同一 MJCF;源地图条目本身不会自动进入场景。 */
export function composePlacedMapAssets(
source: Uint8Array,
generatedScenePath: string,
manifest: ProjectManifest,
assets: readonly PlacedMapAsset[],
): MapStackComposition {
let data = source;
let geomCount = 0;
const warnings: string[] = [];
const spawnOwnerId = assets.find(
(asset) => asset.selection.kind === 'project' && asset.selection.spawnPointId,
)?.id;
// 程序地形最后合成,确保工程地图或机器人自带的无限 plane 不会覆盖沟壑/深坑。
const orderedAssets = [
...assets.filter(
(asset) =>
asset.selection.kind !== 'builtin' || !isSystemTerrainPreset(asset.selection.config.preset),
),
...assets.filter(
(asset) =>
asset.selection.kind === 'builtin' && isSystemTerrainPreset(asset.selection.config.preset),
),
];
for (const asset of orderedAssets) {
if (asset.selection.kind === 'builtin') {
const composed = composePhysicalMap(data, asset.selection.config, {
instanceId: asset.id,
preserveExistingGround: true,
});
data = composed.data;
geomCount += composed.geomCount;
if (composed.summary) warnings.push(`${asset.name}:${composed.summary}`);
continue;
}
const resolvedMap = resolveProjectMap(manifest, asset.selection.descriptorPath);
const composed = composeProjectMap(
data,
generatedScenePath,
manifest,
resolvedMap,
asset.selection,
{
instanceId: asset.id,
applySpawnPoint: asset.id === spawnOwnerId,
},
);
data = composed.data;
geomCount += composed.geomCount;
warnings.push(...composed.warnings, `${asset.name}:${composed.summary}`);
}
return { data, geomCount, warnings };
}