技術參考

完整 Locus Package v2 製作指南

本頁內容
  1. 從可用的完整包開始
  2. 歸檔結構
  3. locusplace.json
  4. 封裝清單字段參考
  5. ZIP 內的 Package v2 元數據
  6. View:destination.json
  7. Room:space.json
  8. Experience:experience.json
  9. 可選能力與翻譯標籤
  10. 必填來源信息
  11. 安全與資源預算
  12. 文件和 URL 導入
  13. 包校驗與示例

狀態:正式的發佈、存儲、組合及完整功能導入契約。Locus 1.2.1 及以上版本可通過文件或公開 HTTPS URL 導入此歸檔,用於 View 和 Room。舊的扁平格式見 locus-asset-format.md 仍可作為兼容輸入。

一個 .zip 或 .locusplace 文件是一個普通 ZIP 歸檔,包含一個或多個 Package v2 Destination(產品名稱為 View)、Space(Room)及 Experience。Locus 自身和支持完整功能的可移植包均使用這一安全發佈與完整性封裝。ZIP 根目錄包含 locusplace.json 和 catalog/ 直接放置,不要再套一層父目錄。

校驗基于歸檔字節與 manifest,而非文件擴展名。完整包會保留其 packageID、內容 ID、 contentVersion 更新流及受支持的 Experience;導入相同內容哈希時為冪等操作,不產生變化。維護中的打包器和校驗器會生成並檢查這一確切格式。

此外層封裝只承載數據,不承載可執行擴展。對於同一個 Locus 二進制文件,運行時使用的每項 Package v2 能力,無論歸檔是內置、從 Library 下載,還是從文件或 URL 導入,內容語義都相同。來源可能影響使用權、自定義導入額度、更新權限、存儲、移除及 UI 標籤,但不會啓用另一套 Room/View schema 或渲染功能。腳本、插件、動態庫及可執行成員不屬於此格式。所有來源均遵守相同的路徑隔離、完整性、資源預算、結構解碼、引用閉合及最低版本檢查。

本指南介紹完整外層封裝及基礎 manifest。 字段參考 介紹可選的 View 與 Room 能力、相關資產、取值範圍及最低 app 版本。 外層封裝 schema 和 來源信息 schema 描述 JSON 的結構;打包器與校驗器還會檢查文件字節和跨字段規則。單憑 JSON Schema 無法校驗歸檔,也無法證明它在 Apple Vision Pro 上的體驗舒適。

從可用的完整包開始

克隆或下載 公開工具倉庫。在 macOS 上從該倉庫根目錄運行以下命令,需要 Python 3.9 或更高版本,以及安裝有 Xcode 並提供以下工具: xcrun usdchecker 和 xcrun usdcat。基礎校驗使用 Python 標準庫、 /usr/bin/sips 完成完整圖像解碼,並使用 Xcode 的 usdchecker 和 usdcat 處理模型。高級雲層、水體反射與接觸、無太陽天空檢查還需要 NumPy 和 Pillow: python3 -m pip install numpy pillow.

python3 examples/locusplace/build_examples.py /absolute/path/to/locusplace-examples
python3 tools/validate_locusplace.py --current-app-version 1.4.4 /absolute/path/to/locusplace-examples/view-only.locusplace
python3 tools/validate_locusplace.py --current-app-version 1.4.4 /absolute/path/to/locusplace-examples/room-only.locusplace
python3 tools/validate_locusplace.py --current-app-version 1.4.4 /absolute/path/to/locusplace-examples/combined.locusplace

目標目錄必須不存在或為空。這些小型合成示例用於驗證格式;漸變圖和立方體並非生產級場景或成品 Room。其源碼與生成內容採用 Apache-2.0 許可。參見 示例說明.

--current-app-version 指定本次校驗的目標 Locus 版本,校驗將以此 為準;它不會升級已安裝的 App,也不會賦予 App 新能力。工具保守地默認為 1.0.0;請明確指定目標版本。完整包導入要求 Locus 1.2.1 或更高版本,新字段還受各自最低版本限制。Room 的地面和中景控制要求支持這些字段的 1.4.4 或更新構建;本指南不表示該構建已經在 App Store 上架。

製作自己的包時,可將示例解壓到可編輯文件夾,或按下方結構創建目錄。替換資產與來源信息,使用自己的穩定 ID,並將輸出歸檔保存到 該文件夾之外的 路徑:

python3 tools/pack_locusplace.py --current-app-version 1.4.4 MyEditablePlace MyPlace.zip
python3 tools/validate_locusplace.py --current-app-version 1.4.4 --json MyPlace.zip

打包器會重新計算 files 和 contentHash,校驗歸檔後才生成輸出文件。它拒絕覆蓋已有輸出,並保持可編輯源文件不變。通過以下入口導入結果: Places → 導入 → 導入 View 或 導入 Room → 文件,選擇與包內內容類型相符的導入入口。組合包會一起安裝其中的內容,也可通過直接指向 ZIP 的公開 HTTPS URL 導入。分享成品前,請在 Apple Vision Pro 上檢查每個座位、效果、燈光和聲音。

歸檔結構

example.locusplace
├── locusplace.json
└── catalog/
    ├── destinations/<destination-id>/
    │   ├── destination.json
    │   ├── provenance.json
    │   └── ...
    ├── spaces/<space-id>/
    │   ├── space.json
    │   ├── provenance.json
    │   └── ...
    └── experiences/<experience-id>/
        └── experience.json

除根目錄的 locusplace.json 以外,所有非目錄項都必須列入 files中。每個已聲明文件都必須存在。歸檔只能包含規定的三個目錄集合,每個文件都必須位於 contents中聲明的包 ID 對應目錄內。Package-v2 清單可向前兼容未知字段;但未知的封裝清單字段、不支持的格式版本、集合及內容模式會被安全拒絕。來源信息遵循其已公開的格式規範。

僅含 View 或僅含 Room 的歸檔會安裝可復用的目錄內容。目錄解析後,Locus 會生成默認配對:每個 View 與“你的房間”配對,也與每個聲明 View 開口的 Room 配對。顯式 Experience 僅替換其指定配對,可引用同一歸檔內的內容,或內置/已導入目錄中已有的穩定 ID。

locusplace.json

{
  "formatVersion": 1,
  "packageID": "place.example-combined",
  "contentVersion": "1.0.0",
  "minimumAppVersion": "1.0.0",
  "contents": {
    "destinationIDs": ["destination.example-view"],
    "spaceIDs": ["space.example-room"],
    "experienceIDs": ["experience.example-combined"]
  },
  "files": [
    {
      "path": "catalog/destinations/destination.example-view/destination.json",
      "byteCount": 214,
      "sha256": "<64 lowercase hex characters>"
    }
  ],
  "contentHash": "<64 lowercase hex characters>"
}

packageID 以及所有內容 ID 都是最長 128 字節的穩定 ASCII 標識符。必須以字母或數字開頭,之後只能使用字母、數字、 ., _,以及 -。版本號恰好由三個數字分量組成。若更新改變了字節內容,必須保留原先聲明的內容 ID,並提高 contentVersion。再次導入相同的 contentHash 為冪等操作,不產生變化。

contentHash 對按 Unicode 路徑排序的所有文件記錄計算 SHA-256。每條記錄貢獻以下 UTF-8 字節:

path NUL decimal-byteCount NUL lowercase-sha256 NUL

此哈希不受 JSON 空白及 ZIP 成員順序影響。校驗器還會流式覈實每個聲明文件的實際字節數、ZIP CRC 和 SHA-256。

封裝清單字段參考

字段 必填 含義
formatVersion 是 整數 1;未知的封裝格式版本會被安全拒絕。
packageID 是 此安裝及更新流的穩定標識,不是文件名。
contentVersion 是 三個數字部分,例如 1.2.0;相同 ID 下的字節發生變化時應提高版本。
minimumAppVersion 是 允許導入該歸檔的最低 Locus 版本,同樣由三個數字部分組成。
contents.destinationIDs 是 此 ZIP 所擁有且不重復的 View ID;沒有時使用 [] 表示沒有。
contents.spaceIDs 是 此 ZIP 所擁有且不重復的 Room ID;沒有時使用 [] 表示沒有。
contents.experienceIDs 是 此 ZIP 所擁有且不重復的 Experience ID;沒有時使用 [] 表示沒有。
files 是 自動生成的完整資源文件清單,不包含 locusplace.json.
files[].path 是 規範的歸檔相對 catalog/... 路徑。
files[].byteCount 是 解壓後的精確字節數。
files[].sha256 是 解壓後字節的 SHA-256,由 64 個小寫十六進制字符組成。
contentHash 是 上述規範化載荷清單的 SHA-256 標識。

ZIP 內的 Package v2 元數據

完整外層封裝使用 formatVersion: 1;每個 destination.json, space.json 和 experience.json 使用 formatVersion: 2。以下參考中的 Room v1–v10 編號 扁平兼容格式參考 屬於獨立的扁平格式 space.json 輸入。不要修改完整包的 space.json 設為版本 10 來使用烘焙光照層。在完整包中,可選能力由其有類型定義的字段啓用,最低版本要求則由以下字段限定: minimumAppVersion.

包內資源路徑均相對於清單所在目錄,而非 ZIP 根目錄。每個引用都必須解析為該包內的普通文件。基礎 Package-v2 清單允許向前兼容的元數據,但單個能力配置可能採用封閉字段集。不要假設未知字段會被渲染。外層封裝清單拒絕未知字段,來源信息須遵循已公開的格式規範。

坐標採用右手系,單位為米,+Y 向上、−Z 向前。四元數順序為 [x, y, z, w]。變換可包含 translationMeters (三個有限數值)、 orientationXYZW (四個有限數值組成的非零長度四元數),以及 scale (三個有限正數)。

View: destination.json

{
  "formatVersion": 2,
  "id": "destination.example-view",
  "title": "Example View",
  "panorama": {
    "path": "panorama.jpg",
    "projection": "equirectangular",
    "width": 8192,
    "height": 4096,
    "initialYawDegrees": 0
  },
  "provenance": "provenance.json"
}
字段 必填 含義與校驗
formatVersion 是 整數 2.
id 是 穩定的 View ID,必須與目錄及外層封裝中的 ID 相同。
title 是 非空的用戶可見 View 名稱。
panorama.path 是 最終 JPEG 或 PNG,路徑相對於包目錄;類型由解碼字節決定,而非僅看擴展名。
panorama.projection 是 恰好為 equirectangular.
panorama.width, height 是 準確聲明的正解碼尺寸,且 width == 2 * height.
panorama.initialYawDegrees 否 標準全景坐標系中的有限旋轉角;默認值為 0.
sourceImage 否 可選的包內相對路徑 JPEG/PNG 審核圖像。它不會參與渲染,但完整包可將其作為經過類型識別、解碼和預算檢查的數據保留。可編輯源文件與 DCC 源文件仍須放在運行時 ZIP 之外。
thumbnail 否 包內相對路徑的 JPEG/PNG 目錄圖像。
caption 否 供人閱讀的描述。
generation.generator 否 真實的生成器或工具名稱。
generation.model 否 可選的模型或工作流版本。
generation.generatedAt 否 可選時間戳;推薦 RFC 3339 UTC。
depthLayers[] Package v2 中不支持;公開 ZIP 導入不支持 預留的有序深度資產。在產品運行時與字節級校驗器支持其編碼之前,公開導入會拒絕該字段。
midground.path 否 兩種 Experience Mode 都會渲染的運行時中景 USDZ。內置、Library 和導入的包均遵守同一套成員允許清單、結構與資源預算。參見 中景參考.
midground.transform 否 用於以下內容的可選有限變換: midground.path.
midground.terrainEntities 否 以下字段中不重復且非空的地面單元名稱: midground.path;運行時據此調整 Room 佔地範圍下的地形。
midground.water 否 App 渲染的水面聲明,包含經校驗的遮罩/法線貼圖,以及 字段參考.
sky 否 App 渲染的程序化夜空(星星、銀河及可選極光),通過經校驗的 2:1 灰度遮罩 sky.mask;要求 minimumAppVersion >= 1.2.4。參閱 天空參考.
gpuTexture, gpuTextures 否 經過校驗的 ASTC KTX1 輔助紋理,用戶 ZIP 與 Library 包均可使用。v1 全景輔助紋理要求 1.2.3;v2 源圖數組要求 1.3.0。源文件哈希、尺寸和 mip 層級必須匹配。
water, clouds, fireflies 否 運行時水體(含發光)、繪制雲層運動與螢火蟲聲明;要求 minimumAppVersion >= 1.3.0。其引用資源及資源預算遵循共同的 Package-v2 合同。
environment.sunPath 否 作者聲明的無太陽天空及可選遮罩太陽圓盤;要求 1.3.0 及其作者聲明。
celestial 否 動畫天體及其引用紋理;要求 1.2.4,或其可選功能要求的更高版本(雲層運動/演化要求 1.3.0).
nearOrbit 否 近軌道配置、紋理資產及與內容綁定的回退證明。v1 和 v2 要求 1.3.0;v2 包含分塊清單、分塊圖像及其 GPU 旁路紋理。
splat.variants, splat.ply Package v2 中不支持;公開 ZIP 導入不支持 預留的未來資產引用。splat 後端已移除,因此公開導入會拒絕整個字段。
splat.metricScaleFactor Package v2 中不支持;公開 ZIP 導入不支持 預留契約中的有限正縮放值。
splat.groundPlaneOffset Package v2 中不支持;公開 ZIP 導入不支持 預留契約中的有限地面偏移量。
splat.placement Package v2 中不支持;公開 ZIP 導入不支持 預留契約中的可選共享變換。
environment 否 下方為可見 View 亮度、可選的小型 SDR Room 光照圖及直射太陽光默認值。
audio.path Package v2 中不支持;公開 ZIP 導入不支持 預留的運行時音頻文件。在產品支持完整音頻字節校驗與播放之前,公開導入會拒絕該字段。
audio.loops 與 Package v2 音頻一起使用;公開 ZIP 導入不支持 保留合同中控制是否循環的布爾值。
provenance 導入支持 來源信息 JSON,路徑相對於包目錄。

完整 ZIP 接受該 App 版本實際使用的字段,以及明確保留的元數據,例如 sourceImage;前提是能驗證資源類型及其是否符合資源預算。 midground 屬於公共運行時契約,要求 minimumAppVersion >= 1.2.1. depthLayers, splat,以及舊版 audio 塊仍為預留或已停用,當前沒有運行時使用方。因此當前二進制文件會對所有來源拒絕這些內容,而不會接受未經類型校驗的路徑。後續二進制文件實現某項能力時,必須將該字段的資產引用、類型與預算檢查、運行時使用方及最低 app 版本一並加入公共契約,不得另設公開導入開關。

推薦 12,288×6,144(12K),但這不是強制要求。 較低的分辨率,例如 8,192×4,096、6,144×3,072 或 4,096×2,048,只要嚴格為 2:1 並聲明真實解碼尺寸,也都是有效的。不要僅為標稱 12K 而放大小尺寸源圖:這不會增加細節,只會浪費內存。

全景坐標固定如下: u = 0.5 對應 yaw 0,即初始正前方/世界 −Z; u 向東、即 +X 方向遞增;接縫位於 u = 0/1,對應 yaw ±180°;圖像最上方一行是天頂。 initialYawDegrees 在此坐標系內旋轉圖像,不會重新定義坐標系。

可選 View 光照:

{
  "environment": {
    "imageBasedLight": "thumbnail.jpg",
    "skyGainEV": 0,
    "exposureEV": 0,
    "horizonPitchDegrees": 0,
    "colorGrade": {"contrast": 1.15, "saturation": 1.2},
    "directSun": {"enabled": false, "illuminanceLux": 5000}
  }
}
字段 含義
imageBasedLight 獨立的 2:1 JPEG/PNG,僅用於照亮 Room 幾何體及反射。不得復用 panorama.path;推薦 1024×512,省略時使用中性的渲染照明回退值。
skyGainEV 僅用於可見全景的有限 EV 增益。
exposureEV 僅用於 IBL 的有限 EV 增益。
horizonPitchDegrees 作者設置的有限地平線校正量。
colorGrade.contrast 可選的 SDR 可見全景對比度,範圍為 0.5 至 2.0; 1.0 為中性值。
colorGrade.saturation 可選的 SDR 可見全景飽和度,範圍為 0.0 至 2.0; 1.0 為中性值。
directSun.enabled 是否由作者配置獨立的方向光。
directSun.azimuthDegrees, elevationDegrees 有限方向角;啓用時兩項均為必填。
directSun.illuminanceLux 有限、非負的照度。

調色只影響顯示的 SDR 全景圖。它復用原圖紋理,不會把 View 轉換成 HDR,也不會補回源圖缺失的高光細節。關閉的太陽仍可保存 5000 lux,使得 添加陽光 從 app 默認值開始,不改變包中作者設定的關閉狀態。

visibleSkyHDR 和 hdrManifest 已停用,會被拒絕。外層包中的 EXR 不可作為可見 View 或 Room 光照圖。OpenEXR 仍可作為 Room 資產的 USDZ 紋理格式,並在模型內部校驗。

Room: space.json

{
  "formatVersion": 2,
  "id": "space.example-room",
  "title": "Example Room",
  "scene": "scene.usdz",
  "thumbnail": "thumbnail.jpg",
  "caption": "A quiet house arranged around a sunlit courtyard.",
  "previewCamera": {
    "yawDegrees": -28,
    "pitchDegrees": -10,
    "zoom": 1.0
  },
  "seatedOrigin": {
    "translationMeters": [0, 0, 0],
    "orientationXYZW": [0, 0, 0, 1]
  },
  "safeHeadVolume": {
    "centerMeters": [0, 1.2, 0],
    "sizeMeters": [1.2, 0.6, 1.2]
  },
  "destinationOpenings": [
    {
      "id": "front",
      "transform": {
        "translationMeters": [0, 1.2, -2],
        "orientationXYZW": [0, 0, 0, 1]
      },
      "widthMeters": 4,
      "heightMeters": 2.5
    }
  ],
  "collision": {"mode": "embedded"},
  "teleportCatalog": {"path": "teleport-points.json", "houseID": "example-room"},
  "quality": {
    "status": "unverified",
    "triangleCount": 0,
    "materialCount": 0,
    "entityCount": 0,
    "maxTextureDimension": 0
  },
  "provenance": "provenance.json"
}
字段 必填 含義與校驗
formatVersion 是 整數 2.
id 是 穩定的 Room ID,必須與目錄及外層封裝中的 ID 相同。
title 是 非空的用戶可見 Room 名稱。
scene 是 自包含的 USDZ,路徑相對於包目錄。 .blend 以及其他製作源文件均不可替代最終資產,也不得放在包內其他位置。
thumbnail 否 Room 卡片顯示的 JPEG 或 PNG,路徑相對於包目錄。若聲明,文件必須存在且能完整解碼,並計入歸檔圖像預算;省略則使用默認圖標。
caption 否 非空的用戶可見文案,用於 關於此 Room,最多 2,000 個 UTF-8 字節。
previewCamera.yawDegrees, pitchDegrees 否 有邊界的 3D 預覽所用的有限初始角度,不影響沈浸式擺放。
previewCamera.zoom 以及相機 有邊界的 3D 預覽所用的有限正初始縮放值。重置會返回此初始姿態;查看器會將其限制在支持的交互範圍內。
seatedOrigin.translationMeters 是 用於定位作者設定的落座地面參考點的三個有限米制分量。
seatedOrigin.orientationXYZW 是 四個有限且歸一化的四元數分量;落座坐標系必須保持直立,不可有俯仰或側傾。
safeHeadVolume.centerMeters 是 Room 坐標中的三個有限米制分量。
safeHeadVolume.sizeMeters 是 三個有限且嚴格為正的尺寸。
destinationOpenings 是 矩形開口數組。獨立的純 Room 導入必須恰好有一個開口;零個或多個開口則要求作者在同一歸檔中提供 virtual-space Experience。
destinationOpenings[].id 每項 Experience 組合使用的唯一包 ID。
destinationOpenings[].transform 每項 必填的位置與四元數姿態。
destinationOpenings[].widthMeters, heightMeters 每項 有限且嚴格為正的尺寸。
collision.mode 是 embedded 或 separate.
collision.path 有條件 以下情況下禁止使用: embedded;對於 separate時則必須提供包內相對路徑指向的獨立 USDZ,並按照與 scene相同的成員、紋理和幾何規則進行校驗。其幾何數據與場景幾何共同計入 Room 的資源預算。僅改名的製作源文件不合法。
quality.status 是 unverified 或 verified.
quality.triangleCount, materialCount, entityCount, maxTextureDimension 是 作者填寫的非負測量值。零表示未測量;實際 USD 會單獨檢查。
teleportCatalog.path 是 傳送點 JSON,路徑相對於包目錄。選中的房屋必須至少有一個點,否則 Room 無法進入 Virtual Space。其 1 MiB JSON 預算按字段用途強制執行,即使文件名不以下列擴展名結尾: .json;文件系統的大小寫或 Unicode 別名不能繞過此限制。
teleportCatalog.houseID 是 用於選擇該 JSON 中一個非空房屋條目的 ID,條目位於 houses 數組中。
spatialAdaptation.wallEntities 否 不重復且非空的牆體 USD 實體名;此元數據不會隱藏牆體。
spatialAdaptation.roofEntities 否 不重復、非空且與牆體名稱不重疊的名稱。
spatialAdaptation.deskEntitiesByTeleportID 否 從已聲明的傳送點 ID 到非空的作者指定桌子實體名的映射。
provenance 是 來源信息 JSON,路徑相對於包目錄。

USDZ 使用米制、右手坐標系、+Y 朝上,且僅包含受支持的運行時 USD、紋理與音頻成員。USDZ 成員必須以存儲方式寫入,不得壓縮。校驗器會加載並展平真實 stage,統計幾何體;即使 quality 值很小或為零,也無法掩蓋超預算模型。

必填傳送點 JSON(選中的房屋必須至少有一個點):

{
  "houses": {
    "example-room": [
      {
        "id": "work-desk",
        "title": "Work desk",
        "anchorXZ": [0.5, 0.5],
        "sourceFloorOffset": 0,
        "eyeHeight": 1.15,
        "yawRadians": 0
      }
    ]
  }
}

anchorXZ 是兩個有限的歸一化數值,範圍為 0...1; sourceFloorOffset 以作者模型單位計量,必須有限且非負; eyeHeight 以米計量,必須有限且為正; yawRadians 是在世界坐標系中繞 +Y 的有限模型旋轉角。點 ID 必須唯一,標題不得為空。

Experience: experience.json

{
  "formatVersion": 2,
  "id": "experience.example-combined",
  "title": "Example Room · Example View",
  "destinationID": "destination.example-view",
  "spaceID": "space.example-room",
  "supportedModes": ["virtual-space"],
  "composition": {
    "destinationOpeningID": "front",
    "destinationYawDegrees": 0,
    "destinationPitchDegrees": 0,
    "destinationExposureOffsetEV": 0
  },
  "compatibility": {
    "minimumViewerVersion": "1.0.0",
    "requiredCapabilities": ["world-tracking"]
  }
}
字段 必填 含義與校驗
formatVersion 是 整數 2.
id 是 穩定的 Experience ID。
title 是 非空的用戶可見單元名稱。
destinationID 是 此 ZIP 中或已安裝的穩定 View ID。
spaceID 有條件 穩定的 Room ID;以下字段要求它: virtual-space;通常在以下模式省略: room-portal.
supportedModes 是 非空且元素不重復的數組,只能包含 virtual-space 或 room-portal.
composition.destinationOpeningID 有條件 以下情況下必填: virtual-space;指定所引用 Room 中的一個開口。
composition.destinationYawDegrees 否 此組合的有限天空對齊偏移量。
composition.destinationPitchDegrees 否 此組合的有限天空俯仰偏移量。
composition.destinationExposureOffsetEV 否 此組合的有限相對曝光偏移量。
compatibility.minimumViewerVersion 否 聲明式最低 viewer 版本字符串。
compatibility.requiredCapabilities 否 聲明式能力標識字符串。

純 View 和純 Room ZIP 會安裝可復用內容,並加入默認組合矩陣。只有需要覆蓋某個組合的開口、朝向、曝光、標題、模式或兼容性時,才需要顯式 Experience。引用可指向同一歸檔內的內容,或內置及已安裝的穩定 ID;任何無法解析的引用都會使整個導入失敗。

可選能力與翻譯標籤

將可選字段寫入其所屬 View 或 Room 的清單,並把每個引用資源放在相應清單旁。 字段參考 涵蓋媒體與蒙版、聲音及 Room 音樂、中景與風、水體、天空、雲層、太陽路徑、天體、近軌道、黑洞、點光源、GPU 輔助紋理、座位與分組、燈光、動畫、視頻表面、粒子及烘焙光照層。它也定義了 localizations, provenanceDetail,以及 Room 的 viewGroundFloorOffsetMeters, viewGroundKeepOut,以及 viewMidgroundVisibility 控制項。

例如,以下可選字段應放入其他內容已完整的 Room manifest 中,並要求外層封裝的 minimumAppVersion: "1.4.4" 或更高版本:

{
  "viewGroundFloorOffsetMeters": 0.2,
  "viewGroundKeepOut": false,
  "viewMidgroundVisibility": "terrainOnly"
}

這些字段在導入、內置和 Library 內容中含義相同。字段參考中的 Library 能力名稱屬於 Library offer;不要將自行編造的 requiredCapabilities 字段添加到 locusplace.json。完整包導入流程會檢查最低 App 版本和實際的類型化內容。

必填來源信息

每個導入的 Destination 和 Space 都指向來源 JSON 文檔,記錄作者或機構、許可或保留所有權利聲明(二選一)、要求的署名、修改說明、是否使用 AI,以及適用時的 AI 提供方。來源頁面/原始資源 URL 可選,但必須為 HTTPS,且不含憑據或片段。來源信息缺失、超出大小限制或格式錯誤都會使整個導入失敗。參閱 來源信息參考.

{
  "formatVersion": 1,
  "creatorOrAgency": "Your name or studio",
  "sourcePageURL": "https://example.com/project",
  "originalAssetURL": "https://example.com/original",
  "license": {
    "identifier": "YOUR-LICENSE-ID",
    "name": "Your license name",
    "url": "https://example.com/license"
  },
  "requestedCredit": "Credit line requested by the creator",
  "modificationNotes": "Converted and packaged for Locus.",
  "aiGenerated": false
}
字段 必填 含義與約束
formatVersion 是 整數 1.
creatorOrAgency 是 非空的作者或工作室名稱,最多 200 個字符。
sourcePageURL 否 公開 HTTPS 項目頁面;不得包含憑據或片段。
originalAssetURL 否 公開 HTTPS 來源頁面;記錄來源,而不嵌入原文件。
license.identifier 有條件 非空標識符,最多 100 個字符;使用以下對象時必填: license。Locus 不會替作者選擇資源許可。
license.name 有條件 非空名稱,最多 200 個字符;使用以下對象時必填: license.
license.url 有條件 公開 HTTPS 許可 URL;使用以下對象時必填: license.
rights.statement 有條件 非空權利聲明,最多 1,000 個字符;應搭配 rights.url 而不是 license.
rights.url 有條件 公開 HTTPS 權利聲明 URL;以下兩項必須恰好提供一項: license 或 rights 為必填。
requestedCredit 是 非空署名文本,最多 1,000 個字符。
modificationNotes 是 非空製作說明,最多 2,000 個字符。
aiGenerated 是 布爾值。
aiProvider 有條件 以下情況下為必填且不得為空: aiGenerated 為 true;為 false 時禁止提供,最多 200 個字符。
importSource 否 僅保留給 Locus 直接從圖像創建的 View: photos, files或 url。外部作者製作的包應省略它。

該文檔限 64 KiB。替換資產後,不要繼續使用入門示例的來源信息。倉庫許可與用戶資產許可是兩項獨立聲明。

ZIP 用於運行時交付,不是製作源文件備份。每個載荷文件都必須能從已識別的 Package v2 資產字段引用到;無引用文件一律拒絕,即使它們已列在 locusplace.json.files. .blend, .blend1, .blend2, .fbx, .obj, .mtl, .gltf,以及 .glb 文件即使已聲明也會被拒絕。這些源文件應保留在 ZIP 之外。Room 交付最終 USDZ;打包 View 交付最終 2:1 全景,以及可選的一張小型 2:1 JPEG/PNG Room 光照圖。

安全與資源預算

校驗檢查實際字節,不靠擴展名。它會拒絕路徑穿越、絕對路徑或非規範路徑、反斜槓、控制字符、大小寫或 Unicode 衝突、符號鏈接、重復條目、加密內容、未聲明文件、哈希不匹配、不受支持的 manifest、損壞圖像、USDZ 內無效 EXR 紋理、損壞的 USDZ 結構、壓縮的 USDZ 成員及不受支持的 USDZ 資產類型。Room 預算基於系統加載器實際解析的 USD stage 檢查;作者自報的質量信息只是製作元數據,無法降低這些統計值。

字節級圖像允許清單是嚴格限定的:導入的全景、 sourceImage, thumbnail,以及 imageBasedLight 柵格圖像字段僅允許 JPEG 或 PNG;USDZ 紋理可用 JPEG、PNG 或 OpenEXR。不會隱式接受其他 ImageIO 可解碼格式。外層包中的 3D 製作格式也會被拒絕。USDZ 僅允許包含 USD/USDA/USDC、JPEG、PNG、OpenEXR、M4A、WAV 和 MP3 成員。

資源預算 v1 限制
下載文件或本地歸檔 1 GiB
ZIP 條目數 4,096
根 manifest 1 MiB
任一資源文件 768 MiB
解壓後載荷總量 2 GiB
壓縮比 200:1
任一導入的 JSON 文件 1 MiB
來源信息 JSON 64 KiB
圖像尺寸 32,768 px
一張圖像 1.5 億像素
所有 View 圖像 5 億像素
USDZ 條目數 4,096
USDZ 文件大小/解壓後字節數 768 MiB / 1.5 GiB
USDZ 紋理尺寸/總像素數 16,384 px/5 億
已加載的 Room 幾何體 500 萬個三角形、1,024 個材質、100,000 個實體

文件和 URL 導入

導入 View 時,可以從照片、文件或公開的直接 HTTPS URL 選擇一張 JPG、PNG 或 HEIC。Locus 會將圖像規範化為僅含 Destination 的 Package v2,並通過同一個校驗器和原子安裝流程處理這個臨時包。文件和 URL 也支持完整的 Package v2 ZIP,可用於 View、Room,以及包含訪客所選內容類型的組合包。現有扁平 View/Room ZIP 仍可作為兼容輸入。如果格式錯誤的歸檔包含 locusplace.json ,會被視為無效完整包而拒絕,絕不會回退到扁平解析器。URL 導入拒絕憑據、片段、localhost、 .local及非公網 DNS 解析結果。每次請求只解析一次主機名,所有返回地址都必須是公網地址。TLS 連接會連接到解析得到的確切數字 IP,同時驗證原始主機名。每次重定向都會在建立新連接前重新解析並固定地址,最多跟隨五次重定向;聲明大小和實際流式下載大小都受到限制。

校驗與目錄解析在同一卷的私有暫存目錄內完成。整個庫的咨詢鎖會串行處理清單、配額檢查及提交。首次安裝使用排他的原子重命名,更新使用原子目錄交換。任何失敗都會移除暫存內容,並保持已安裝包不變。

包校驗與示例

以下命令維護髮布及完整功能導入所用的完整 Package v2 外層封裝。舊扁平格式工具仍記錄在 locus-asset-format.md.

無需安裝即可校驗任意一種文件名:

python3 tools/validate_locusplace.py --current-app-version 1.4.4 MyPlace.locusplace
python3 tools/validate_locusplace.py --current-app-version 1.4.4 MyPlace.zip
python3 tools/validate_locusplace.py --current-app-version 1.4.4 --json MyPlace.locusplace

Python 代碼使用標準庫、通過以下方式調用的 macOS ImageIO: /usr/bin/sips,以及 USD 工具 usdchecker 和 usdcat (隨 Xcode/命令行工具安裝)。完成 JPEG 或 PNG 結構校驗後,ImageIO 會解碼全部像素;EXR 校驗僅用於 USDZ 內部的紋理。USD 工具會加載實際的房間 USD 場景、展開其圖層並測量幾何數據。任何校驗失敗都會返回非零退出碼。檢查範圍涵蓋歸檔、完整性、Package-v2、來源信息、圖像/EXR 和 USDZ。安裝及跨目錄引用解析仍以 visionOS 導入器為準。

將可編輯目錄打包為普通 ZIP,重新計算所有完整性記錄,並僅在校驗器接受結果後輸出:

python3 tools/pack_locusplace.py --current-app-version 1.4.4 MyEditablePlace MyPlace.zip

在臨時目錄或已忽略的目錄中生成真實的純 View、純 Room 和組合示例歸檔,然後校驗:

python3 examples/locusplace/build_examples.py /tmp/locusplace-examples
for package in /tmp/locusplace-examples/*.locusplace; do
  python3 tools/validate_locusplace.py --current-app-version 1.4.4 "$package"
done

示例從源代碼生成,無須下載私有資產或調用付費服務。構建器與預期目錄結構記錄在 示例 README.