Структура упаковки и распаковки не правильно - PullRequest
3 голосов
/ 10 июня 2019

Я пытаюсь создать простой куб в GLTF. Я использую скрипт Python для записи индекса и буфера вершин в двоичные данные. Вот мой код;

import base64
import struct

indices = [
    0,  1,  2,  0,  2,  3,  # Front
    4,  5,  6,  4,  6,  7,  # Right
    8,  9,  10, 8,  10, 11, # Back
    12, 13, 14, 12, 14, 15, # Left
    16, 17, 18, 16, 18, 19, # Upper
    20, 21, 22, 20, 22, 23  # Bottom
]

faces = [
    [   # Front
        -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0,
        1.0, 1.0, 1.0,
        -1.0, 1.0, 1.0
    ],
    [   # Right
        1.0, 1.0, 1.0,
        1.0, 1.0, -1.0,
        1.0, -1.0, -1.0,
        1.0, -1.0, 1.0
    ],
    [   # Back
        -1.0, -1.0, -1.0,
        1.0, -1.0, -1.0,
        1.0, 1.0, -1.0,
        -1.0, 1.0, -1.0
    ],
    [   # Left
        -1.0, -1.0, -1.0,
        -1.0, -1.0, 1.0,
        -1.0, 1.0, 1.0,
        -1.0, 1.0, -1.0
    ],
    [   # Upper
        1.0, 1.0, 1.0,
        -1.0, 1.0, 1.0,
        -1.0, 1.0, -1.0,
        1.0, 1.0, -1.0
    ],
    [   # Bottom
        -1.0, -1.0, -1.0,
        1.0, -1.0, -1.0,
        1.0, -1.0, 1.0,
        -1.0, -1.0, 1.0
    ]
]

length = 2 * len(indices) + 4 * len(faces) * len(faces[0])
buffer = bytearray(length)
offset = 0

# Write index array.
for index in indices:
    struct.pack_into('H', buffer, offset, index)
    offset = offset + 1

# Write vertex array.
for face in faces:
    for vertex in face:
        struct.pack_into('f', buffer, offset, vertex)
        offset = offset + 1

# Test
index_format = 'H' * 36
vertex_format = 'f' * 72
data_format = index_format + vertex_format
print(data_format)
print(struct.unpack(data_format, buffer))

# Write to base64.
b64 = base64.b64encode(buffer)
print(b64)

Проблема в том, что когда я распаковываю данные, они дают странные значения, которые приходят из ниоткуда:

(256, 2, 770, 1284, 1030, 1798, 2312, 2058, 2826, 3340, 3086, 3854, 4368, 4114, 4882, 5396, 5142, 5910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.831554006032442e-39, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

Понятия не имею, что я делаю не так. Если я упаковываю данные в тот же формат, который я использую для распаковки, почему эти значения могут отличаться?

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Вы уже опубликовали ответ, пока я работал над моим. Однако вот вариант, который является:

  • Компакт (упаковка выполняется в 2 строки кода)
  • Общее (полностью опирается на индексы и грани структура)

code.py

#!/usr/bin/env python3

import sys
import base64
import struct


def main():
    indices = [
        0,  1,  2,  0,  2,  3,  # Front
        4,  5,  6,  4,  6,  7,  # Right
        8,  9,  10, 8,  10, 11, # Back
        12, 13, 14, 12, 14, 15, # Left
        16, 17, 18, 16, 18, 19, # Upper
        20, 21, 22, 20, 22, 23  # Bottom
    ]

    faces = [
        [   # Front
            -1.0, -1.0, 1.0,
            1.0, -1.0, 1.0,
            1.0, 1.0, 1.0,
            -1.0, 1.0, 1.0
        ],
        [   # Right
            1.0, 1.0, 1.0,
            1.0, 1.0, -1.0,
            1.0, -1.0, -1.0,
            1.0, -1.0, 1.0
        ],
        [   # Back
            -1.0, -1.0, -1.0,
            1.0, -1.0, -1.0,
            1.0, 1.0, -1.0,
            -1.0, 1.0, -1.0
        ],
        [   # Left
            -1.0, -1.0, -1.0,
            -1.0, -1.0, 1.0,
            -1.0, 1.0, 1.0,
            -1.0, 1.0, -1.0
        ],
        [   # Upper
            1.0, 1.0, 1.0,
            -1.0, 1.0, 1.0,
            -1.0, 1.0, -1.0,
            1.0, 1.0, -1.0
        ],
        [   # Bottom
            -1.0, -1.0, -1.0,
            1.0, -1.0, -1.0,
            1.0, -1.0, 1.0,
            -1.0, -1.0, 1.0
        ]
    ]

    # @TODO - cfati: Relevant code is below (3 lines)
    format = "H" * len(indices) + "f" * sum((len(face) for face in faces))
    buf = struct.pack(format, *indices + [i for face in faces for i in face])
    buf_b64 = base64.b64encode(buf)

    print("Format: {:}".format(format))
    print("\nBuffer unpacked: {:}".format(struct.unpack(format, buf)))
    print("\nBuffer base64'ed: {:}".format(buf_b64))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()
    print("\nDone.")

выход

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q056530761]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32

Format: HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Buffer unpacked: (0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0)

Buffer base64'ed: b'AAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACAAKAAsADAANAA4ADAAOAA8AEAARABIAEAASABMAFAAVABYAFAAWABcAAACAvwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAvwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAPwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/'

Done.
0 голосов
/ 10 июня 2019

Я разобрался с решением.Проблема в том, что я только увеличиваю offset на 1. При записи unsigned short я должен увеличивать его на 2. А при написании float я должен увеличивать на 4.

Правильнокод:

# Write index array.
for index in indices:
    struct.pack_into('H', buffer, offset, index)
    offset = offset + 2

# Write vertex array.
for face in faces:
    for vertex in face:
        struct.pack_into('f', buffer, offset, vertex)
        offset = offset + 4
...