-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathreadnav_gzrs2.py
91 lines (70 loc) · 3.27 KB
/
readnav_gzrs2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#####
# Most of the code is based on logic found in...
#
### GunZ 1
# - RNavigationMesh.h/.cpp
#
# Please report maps and models with unsupported features to me on Discord: Krunk#6051
#####
import os, io
from .constants_gzrs2 import *
from .classes_gzrs2 import *
from .io_gzrs2 import *
from .lib_gzrs2 import *
def readNav(self, file, path, state):
file.seek(0, os.SEEK_END)
fileSize = file.tell()
file.seek(0, os.SEEK_SET)
if state.logNavHeaders or state.logNavData:
print("=================== Read Nav ===================")
print()
id = readUInt(file)
version = readUInt(file)
if state.logNavHeaders:
print(f"Path: { path }")
print(f"ID: { hex(id) }")
print(f"Version: { hex(version) }")
print()
if id != NAV_ID or version != NAV_VERSION:
self.report({ 'ERROR' }, f"GZRS2: NAV header invalid! { hex(id) }, { hex(version) }")
return { 'CANCELLED' }
vertexCount = readInt(file)
vertices = readCoordinateArray(file, vertexCount, state.convertUnits, True)
if state.logNavData:
output = "Vertices: {:<6d}".format(vertexCount)
output += " Min: ({:>5.02f}, {:>5.02f}, {:>5.02f}) Max: ({:>5.02f}, {:>5.02f}, {:>5.02f})".format(*vecArrayMinMax(vertices, 3)) if vertexCount > 0 else ''
print(output)
state.navVerts = vertices
faceCount = readInt(file)
indices = readUShortArray(file, faceCount * 3)
if state.logNavData:
output = "Faces: {:<3d}".format(faceCount)
output += " Min & Max: ({:>3d}, {:>3d})".format(min(indices), max(indices)) if faceCount > 0 else ''
print(output)
state.navFaces = tuple(tuple(indices[f * 3 + i] for i in range(3)) for f in range(faceCount))
invalidCount = 0
for face in state.navFaces:
if (face[0] < 0 or face[1] < 0 or face[2] < 0 or
face[0] >= vertexCount or face[1] >= vertexCount or face[2] >= vertexCount or
face[0] == face[1] or face[1] == face[2] or face[2] == face[0]):
invalidCount += 1
if invalidCount > 0:
self.report({ 'ERROR' }, f"GZRS2: NAV import contained { invalidCount } invalid face indices! { path }")
return { 'CANCELLED' }
linkIndices = readIntArray(file, faceCount * 3)
if state.logNavData:
output = "Links: {:<3d}".format(faceCount)
output += " Min & Max: ({:>3d}, {:>3d})".format(min(linkIndices), max(linkIndices)) if faceCount > 0 else ''
print(output)
print()
invalidCount = sum(1 for index in linkIndices if index >= faceCount)
if invalidCount > 0:
self.report({ 'ERROR' }, f"GZRS2: NAV import contained { invalidCount } negative link indices! { path }")
return { 'CANCELLED' }
state.navLinks = tuple(tuple(linkIndices[f * 3 + i] for i in range(3)) for f in range(faceCount))
if state.logNavHeaders or state.logNavData:
bytesRemaining = fileSize - file.tell()
if bytesRemaining > 0:
self.report({ 'ERROR' }, f"GZRS2: NAV import finished with bytes remaining! { path }, { hex(id) }, { hex(version) }")
print(f"Bytes Remaining: { bytesRemaining }")
print()