-
Notifications
You must be signed in to change notification settings - Fork 0
/
GravityRush2_evb.py
117 lines (98 loc) · 3.53 KB
/
GravityRush2_evb.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Noesis Gravity Rush 2 .evb Extractor
from inc_noesis import *
import noesis
import rapi
import os
debug = False
global_scale = 100
def registerNoesisTypes():
handle = noesis.register('Gravity Rush 2 evb database', '.evb')
noesis.setHandlerTypeCheck(handle, noepyCheckType)
noesis.setHandlerLoadModel(handle, noepyLoadModel)
if debug:
noesis.logPopup() # please comment out when done.
return 1
def noepyCheckType(data):
file = NoeBitStream(data)
if len(data) < 4:
return 0
header = file.readBytes(4).decode('ASCII').rstrip("\0")
if header == 'FBKK':
return 1
return 0
# loading the bones!
def noepyLoadModel(data, mdlList):
global bs
bs = NoeBitStream(data)
global bones
bones = []
bs.seek(0x38, NOESEEK_ABS)
file_name = loadStringFromPointer(bs.readUInt())
print("Filename: " + file_name)
bs.seek(0x24, NOESEEK_REL)
num_of_data_chunk = bs.readUInt()
bs.seek(bs.readUInt() - 4, NOESEEK_REL)
for dataChunkIndex in range(num_of_data_chunk):
readDataChunk(bs.readUInt())
mdl = NoeModel()
mdl.setBones(bones)
mdlList.append(mdl)
return 1
def readDataChunk(offset):
origonal_offset = bs.tell()
bs.seek(offset - 4, NOESEEK_REL)
print("Loading Data Chunk at " + hex(bs.tell()))
# print("Upstream - " + hex(origonal_offset))
# print("offset - " + hex(offset))
bs.seek(0x08, NOESEEK_REL)
name = loadStringFromPointer(bs.readUInt())
print("Data Chunk name: " + name)
bs.seek(0x24, NOESEEK_REL)
subdata_chunk_count = bs.readUInt()
subindex_chunk_location = bs.tell() + bs.readUInt()
bs.seek(0x18, NOESEEK_REL)
# Loading root bone
rotation = NoeQuat.fromBytes(bs.readBytes(16))
translation = NoeVec3.fromBytes(bs.readBytes(12)) * NoeVec3((global_scale, global_scale, global_scale))
bs.seek(4, NOESEEK_REL)
scale = NoeVec3.fromBytes(bs.readBytes(12))
boneMat = rotation.toMat43(transposed=1)
boneMat[3] = translation
boneIndex = len(bones)
bones.append(NoeBone(boneIndex, name, boneMat))
bs.seek(0x18, NOESEEK_REL)
parent_name = loadStringFromPointer(bs.readUInt())
print("Parent name: " + parent_name)
# Loading Sub Index Chunk
bs.seek(subindex_chunk_location, NOESEEK_ABS)
for subDataChunkIndex in range(subdata_chunk_count):
readSubDataChunk(bs.readUInt(), boneIndex)
bs.seek(origonal_offset, NOESEEK_ABS)
return
def readSubDataChunk(offset, parentBoneIndex):
origonal_offset = bs.tell()
bs.seek(offset - 4, NOESEEK_REL)
print("Loading Sub Data Chunk at " + hex(bs.tell()))
bs.seek(0x08, NOESEEK_REL)
name = loadStringFromPointer(bs.readUInt())
print("Sub Data Chunk name: " + name)
bs.seek(0x0C, NOESEEK_REL)
bs.seek(bs.readUInt() - 4, NOESEEK_REL)
# Loading bone
rotation = NoeQuat.fromBytes(bs.readBytes(16))
translation = NoeVec3.fromBytes(bs.readBytes(12)) * NoeVec3((global_scale, global_scale, global_scale))
bs.seek(4, NOESEEK_REL)
scale = NoeVec3.fromBytes(bs.readBytes(12))
boneMat = rotation.toMat43(transposed=1)
boneMat[3] = translation
#boneMat *= bones[parentBoneIndex].getMatrix()
boneIndex = len(bones)
bones.append(NoeBone(boneIndex, name, boneMat, None, parentBoneIndex))
bs.seek(origonal_offset, NOESEEK_ABS)
return
def loadStringFromPointer(offset):
origonal_offset = bs.tell()
bs.seek(offset - 4, NOESEEK_REL)
string = bs.readBytes(64).split(b'\x00')[0].decode('UTF8')
bs.seek(origonal_offset, NOESEEK_ABS)
return string