Python 结构打包和解包不正确

Python 结构打包和解包不正确,python,data-structures,buffer,binary-data,gltf,Python,Data Structures,Buffer,Binary Data,Gltf,我试图在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

我试图在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)

我不知道我做错了什么。如果我使用与解包时相同的格式打包数据,为什么这些值会不同?

我找到了解决方案。问题是我只是将
偏移量增加了1。在编写
无符号short
时,我应该将其增加2。当写浮动时,我应该增加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

当我在写我的答案时,你已经发布了答案。但是,这里有一个变体:

  • 紧凑型(包装分为两行代码)
  • 一般(完全依赖于索引和面结构)
code.py:

#/usr/bin/env蟒蛇3
导入系统
导入base64
导入结构
def main():
指数=[
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
]
]
#@TODO-cfati:相关代码如下(3行)
format=“H”*len(索引)+“f”*sum((len(面)表示面中的面))
buf=struct.pack(格式,*索引+[i表示面中的面,i表示面中的面])
buf_b64=base64.b64编码(buf)
打印(“格式:{:}”。格式(格式))
打印(“\n缓冲解包:{:}”。格式(struct.unpack(format,buf)))
打印(“\nBuffer base64'ed:{:}”。格式(buf_b64))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{:s}on{:s}\n.”格式(sys.version,sys.platform))
main()
打印(“\n完成”)
输出


您的预期输出是什么?您只是稍微快了一点;)此外,您还可以在格式说明符之前放置一个数字,以便有效地重复它:
struct.pack_into(f'{len(index)}H',buffer,offset,*index)
注意,glTF总是使用少量的endian编码,但是Python将在这里使用平台本机endianness,除非您另有说明。
[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.