乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      3dTiles 數(shù)據(jù)規(guī)范詳解[4.2] i3dm瓦片二進制數(shù)據(jù)文件結構

       Coder編程 2021-11-19

      i3dm,即 Instanced 3D Model,實例三維模型的意思。

      諸如樹木、路燈、路邊的垃圾桶、長椅等具有明顯 重復 特征的數(shù)據(jù)。這類數(shù)據(jù)用得較少(笑,現(xiàn)在都喜歡搞BIM、傾斜攝影、精模、白模等)

      我的git地址:github.com/onsummer
      轉載請規(guī)范化轉載。出處:@秋意正寒 https://www.cnblogs.com/onsummer/p/13252897.html

      瓦片文件二進制布局(文件結構)

      與 b3dm 一致,文件頭多了個屬性。

      1. 文件頭:32byte

      i3dm的文件頭有8個屬性,前7個與b3dm是一樣的。

      屬性的官方名稱 字節(jié)長 類型 含義
      magic 4 string(或char[4]) 該瓦片文件的類型,在i3dm中是 "i3dm"
      version 4 uint32 該瓦片的版本,目前限定是 1.
      byteLength 4 uint32 該瓦片文件的文件大小,單位:byte
      featureTableJSONByteLength 4 uint32 要素表的JSON文本(二進制形式)長度
      featureTableBinaryByteLength 4 uint32 要素表的二進制數(shù)據(jù)長度
      batchTableJSONByteLength 4 uint32 批量表的JSON文本(二進制形式)長度
      batchTableBinaryByteLength 4 uint32 批量表的二進制數(shù)據(jù)長度
      gltfFormat 4 uint32 gltf在i3dm瓦片中存在的形式

      其中,前7個和b3dm意義一樣,不做解釋。

      第8個,gltfFormat 只有兩個值:0和1.

      0,則位于 i3dm 瓦片文件最后的 gltf 內(nèi)容是一個 uri,指向gltf的數(shù)據(jù)內(nèi)容(可能是Base64 DataURL,也可能是其他地方的地址,筆者沒見過...)

      1,則位于 i3dm 瓦片文件最后的 gltf 內(nèi)容是 二進制的 glb,大多數(shù)情況見的是這個。

      默認情況,gltf 是 y 軸朝上,3dTiles 是z軸朝上,需要坐標轉換。

      2. 要素表

      在上篇,有介紹到要素表存在 全局屬性要素屬性。在 i3dm 中,這對概念就能得到很好的解釋。

      ① 要素表的全局屬性

      屬性名 數(shù)據(jù)類型 描述 是否必須
      INSTANCES_LENGTH uint32 instance的個數(shù)
      RTC_CENTER float32[3] 如果坐標是相對坐標,那么相對中心由此屬性給出
      QUANTIZED_VOLUME_OFFSET float32[3] 量化空間范圍體的偏移量 否,與要素屬性中的POSITION_QUANTIZED 共存亡
      QUANTIZED_VOLUME_SCALE float32[3] 量化空間范圍體的縮放比例 否,與要素屬性中的POSITION_QUANTIZED 共存亡
      EAST_NORTH_UP boolean 如果這個屬性值是true,而且每個實例的方向沒有定義,那么每個實例將默認指向WGS84橢球的正東、正北方向。

      第一第二個能與 b3dm 中的 BATCH_LENGTHRTC_CENTER 類比來理解,就不解釋了。

      最后一個屬性指示當前 i3dm 瓦片的坐標軸朝向。

      下列要著重介紹這個所謂的 QUANTIZED_VOLUME,即 量化空間范圍體。

      量化空間范圍體

      這個詞“量化空間范圍體”是我自己意譯的。

      每個瓦片,都有它自己的空間范圍,為了節(jié)約數(shù)據(jù)占用,可以使用相對坐標來記錄每個 instance 的位置,也即記錄全局屬性中的 RTC_CENTER 屬性。

      但是,即便用了相對坐標,instance 的坐標值仍然是 FLOAT 類型,占 4字節(jié)。

      假設,存在一個矩形空間,它的左下角點的坐標是 (x, y, z),將矩形空間按 \(2^{16}\) 等分其 x、y、z 三個方向,定義矩形空間的三條邊長對應瓦片本身的坐標空間的縮放比例為 (ScaleX, ScaleY, ScaleZ),如下圖所示:

      這樣,被細分出來的每一個 “小矩形”,都有它自己在這個矩形空間的量化坐標,因為 x、y、z 三個方向被分割成了 \(2^{16}\) 塊,我們可以使用 uint16 類型的數(shù)值來記錄坐標,這樣每個數(shù)字只占了 16bit,也即 2byte,比 FLOAT 的4byte 小了一倍,對于頂點數(shù)據(jù)的壓縮十分具有價值。

      那么,如何將 (16464, 2172, 63312) 這個量化的坐標映射回瓦片原本的坐標呢?參考公式:

      \(\vec{Position} = Scale * \displaystyle\frac{\vec{PositionQuantized}}{65535} + \vec{Offset}\)

      即量化坐標 PositionQuantized 各個坐標分量乘上縮放因子( Scale / 65535 ),然后加偏移坐標即可。

      三個方向的縮放因子 QUANTIZED_VOLUME_SCALE:float[3] 和 偏移量 QUANTIZED_VOLUME_OFFSET:float[3] 作為全局屬性寫在要素表JSON中。

      如果這兩個全局屬性未定義,則 逐要素屬性中的 POSITION_QUANTIZED 這個量化坐標也不會存在,即使用原有的 float 類型坐標記法。

      需要注意的是,量化坐標和普通坐標只能二選一,如果都不存在,那么這個 i3dm 瓦片就不會被渲染。

      看到這,是否能理解“要素表的全局屬性是對于整個瓦片文件而言”這句話了呢?

      ② 要素表的(逐)要素屬性

      屬性名稱 數(shù)據(jù)類型 描述 是否必須
      POSITION float32[3] 模型實例的坐標 是,與POSITION_QUANTIZED二選一
      POSITION_QUANTIZED uint16[3] 量化空間范圍體內(nèi)的模型實例坐標 是,與POSITION二選一
      NORMAL_UP float32[3] 模型上方向向量 否,與NORMAL_RIGHT共存亡
      NORMAL_RIGHT float32[3] 模型右方向向量,必須與up向量正交 否,與NORMAL_UP共存亡
      NORMAL_UP_OCT32P uint16[2] 模型上方向向量,32位精度八進制編碼 否,與NORMAL_RIGHT_OCT32P共存亡
      NORMAL_RIGHT_OCT32P uint16[2] 模型右方向向量,必須與up向量正交,32位精度8進制編碼 否,與NORMAL_UP_OCT32P共存亡
      SCALE float32 該 instance 對于 gltf 的縮放比例
      SCALE_NON_UNIFORM float32[3] 該 instance 在三個方向上的縮放比例
      BATCH_ID uin8/uint16(默認)/uint32 用于在批量表里檢索數(shù)據(jù)用的batchId

      當 i3dm 瓦片中逐個 instance 的POSITION 被定義時,量化坐標 POSITION_QUANTIZED 就不應存在,反之亦然。

      接下來四個方向向量屬性(法線)NORMAL_UP、NORMAL_RIGHTNORMAL_UP_OCT32PNORMAL_RIGHT_OCT32P 也是一對反依賴的逐要素屬性。

      SCALE 屬性定義了當前要素(instance或實例)對使用的 gltf 模型的縮放比例。

      SCALE_NON_UNIFORM 屬性與 SCALE 屬性差不多,只不過是在三個方向上分別不同的縮放比例。

      BATCH_ID,是當前要素(instance或實例)的 id 號,將 要素 與 批量表中的屬性 二者聯(lián)系起來。

      個人覺得,應該叫 INSTANCE_ID 更合適一些?

      默認方向

      如果不給定要素屬性中與方向有關的向量時,每個實例的朝向有一個默認值:在WGS84橢球上,上方向指向正北,右方向指向正東。

      ③ 要素表的JSON

      上述所有屬性全部會記錄在要素表的 JSON 中,對于 全局屬性,其值記錄在 JSON 中,對于其要素屬性,因為要素(即instance)很多的時候寫在JSON中體積會變大,所以使用 JSON引用要素表二進制數(shù)據(jù)體 的形式。

      下列是一個要素表的JSON:

      {
          INSTANCES_LENGTH : 4, // 有4個實例
          POSITION : {
              byteOffset : 0 // POSITION的值從ftBinary的第0字節(jié)起開始計算
          }
      }
      

      讀者不妨回顧上一篇,b3dm的要素表JSON,并未出現(xiàn)有對要素表體引用的屬性,在這里出現(xiàn)了:POSITION,它從要素表體的第 0 個字節(jié)開始記錄數(shù)據(jù)。

      POSITION 這個逐要素(實例、instance)屬性的定義,早已在上文提及,即三個 FLOAT 類型數(shù)字為一組,一共 INSTANCES_LENGTH 組的數(shù)據(jù),記錄在要素表體。這是 instance 坐標數(shù)據(jù),寫在 JSON 中雖然沒問題,但是會造成空間浪費,以二進制形式記錄會比較劃算。

      ④ 要素表體

      要素表JSON中引用的二進制數(shù)據(jù)均順次記錄在此。

      3. 批量表

      批量表與 b3dm 的一致,均為 JSON 記錄屬性元數(shù)據(jù),批量表體記錄屬性具體數(shù)據(jù)。此處不再舉例。

      4. 要素舉例說明

      此部分參考官方文檔。

      ① 僅有 POSITION 的 i3dm 瓦片

      var featureTableJSON = {
          INSTANCES_LENGTH : 4, // 有4個實例
          POSITION : {
              byteOffset : 0 // POSITION的值從ftBinary的第0字節(jié)起開始計算
          }
      };
      
      var featureTableBinary = new Buffer(new Float32Array([
          0.0, 0.0, 0.0,
          1.0, 0.0, 0.0,
          0.0, 0.0, 1.0,
          1.0, 0.0, 1.0
      ]).buffer);
      

      使用 JavaScript 語言記錄了 要素表JSON,以及要素表二進制數(shù)據(jù)(以ES6 TypedArray 形式)。

      ② 使用量化位置與八進制方向向量

      var featureTableJSON = {
          INSTANCES_LENGTH : 4, // 有4個實例
          QUANTIZED_VOLUME_OFFSET : [-250.0, 0.0, -250.0],
          QUANTIZED_VOLUME_SCALE : [500.0, 0.0, 500.0],
          POSITION_QUANTIZED : {
              byteOffset : 0
          },
          NORMAL_UP_OCT32P : {
              byteOffset : 24
          },
          NORMAL_RIGHT_OCT32P : {
              byteOffset : 40
          }
      };
      
      var positionQuantizedBinary = new Buffer(new Uint16Array([
          0, 0, 0,
          65535, 0, 0,
          0, 0, 65535,
          65535, 0, 65535
      ]).buffer);
      
      var normalUpOct32PBinary = new Buffer(new Uint16Array([
          32768, 65535,
          32768, 65535,
          32768, 65535,
          32768, 65535
      ]).buffer);
      
      var normalRightOct32PBinary = new Buffer(new Uint16Array([
          65535, 32768,
          65535, 32768,
          65535, 32768,
          65535, 32768
      ]).buffer);
      
      var featureTableBinary = Buffer.concat([positionQuantizedBinary, normalUpOct32PBinary, normalRightOct32PBinary]);
      

      規(guī)定了全局屬性 QUANTIZED_VOLUME_OFFSETQUANTIZED_VOLUME_SCALE,規(guī)定了量化坐標 POSITION_QUANTIZED、八進制上方向和右方向向量NORMAL_UP_OCT32PNORMAL_RIGHT_OCT32P 在要素表體中的起始偏移值。

      于是,使用三個 TypedArray 構造的 Buffer 對象,再拼接在一起,即要素表體 featureTableBinary。

      5. 字節(jié)對齊與編碼端序

      與b3dm里寫的一致,可以回看:https://www.cnblogs.com/onsummer/p/13252896.html

      6. 擴展(extensions)和額外信息(extras)

      同樣,這部分內(nèi)容與b3dm篇章內(nèi)介紹的一致,會在后續(xù)文章內(nèi)介紹。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多