more checks
This commit is contained in:
parent
42cc294f62
commit
1d36b5e5b4
175
obj2gbs.py
175
obj2gbs.py
@ -5,6 +5,7 @@ from lib.fileutils import *
|
|||||||
from lib.game import Vec3, VecRGB, cross
|
from lib.game import Vec3, VecRGB, cross
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
GBS_VERSION = 0xaa0100be
|
GBS_VERSION = 0xaa0100be
|
||||||
GBSFlagNormals = 0x0001
|
GBSFlagNormals = 0x0001
|
||||||
@ -14,6 +15,38 @@ GBSFlagCalcNormals = 0x0008
|
|||||||
GBSFlagMaxLit = (1 << 31)
|
GBSFlagMaxLit = (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
|
def check(gbs_file, materials):
|
||||||
|
with open("data.json") as fp:
|
||||||
|
d = json.load(fp)
|
||||||
|
|
||||||
|
possible_binfiles = []
|
||||||
|
|
||||||
|
for binfile in d:
|
||||||
|
if gbs_file in d[binfile]["objects"]:
|
||||||
|
possible_binfiles.append(binfile)
|
||||||
|
|
||||||
|
if not possible_binfiles:
|
||||||
|
print("ERROR: %s was not found in any bin file. Your model won't be loaded by the game at all." % gbs_file)
|
||||||
|
print("Please use a supported model name. Check the models archive for a valid name.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
possible_texfiles = []
|
||||||
|
for material in materials:
|
||||||
|
tex = material.texture.replace(".tga", "")
|
||||||
|
found_in = []
|
||||||
|
for possible_binfile in possible_binfiles:
|
||||||
|
if tex in d[possible_binfile]["textures"]:
|
||||||
|
found_in.append(possible_binfile)
|
||||||
|
possible_texfiles.append(possible_binfile)
|
||||||
|
if not found_in:
|
||||||
|
print("ERROR: texture %s is not a supported texture name or is referenced by another bin file which is not loaded with your object." % tex)
|
||||||
|
print("Please check the textures archive for a valid name.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
loaded = list(set(possible_texfiles) & set(possible_binfiles))
|
||||||
|
print("INFO: Your model will be loaded when one of these are loaded on the map: %s" % ", ".join(loaded))
|
||||||
|
|
||||||
|
|
||||||
def resize(l: List, t, num):
|
def resize(l: List, t, num):
|
||||||
l.clear()
|
l.clear()
|
||||||
for i in range(num):
|
for i in range(num):
|
||||||
@ -96,13 +129,11 @@ def obj_read_materials(matlib_file) -> List[OBJMaterial]:
|
|||||||
mat = OBJMaterial()
|
mat = OBJMaterial()
|
||||||
materials.append(mat)
|
materials.append(mat)
|
||||||
mat.name = arr[1].rstrip()
|
mat.name = arr[1].rstrip()
|
||||||
print("NEW MAT: %s" % mat.name)
|
|
||||||
curr_mat = mat
|
curr_mat = mat
|
||||||
if arr[0] == "map_Ka" or arr[0] == "map_Kd":
|
if arr[0] == "map_Ka" or arr[0] == "map_Kd":
|
||||||
matname_without_ext = "".join(arr[1:]).split("/")[-1]
|
matname_without_ext = "".join(arr[1:]).split("/")[-1]
|
||||||
matname_without_ext = "".join(matname_without_ext.split(".")[0:-1])
|
matname_without_ext = "".join(matname_without_ext.split(".")[0:-1])
|
||||||
curr_mat.texture = matname_without_ext
|
curr_mat.texture = matname_without_ext
|
||||||
print("MAT %s HAS TEXTURE %s" % (curr_mat.name, curr_mat.texture))
|
|
||||||
return materials
|
return materials
|
||||||
|
|
||||||
|
|
||||||
@ -125,137 +156,6 @@ class GbsData:
|
|||||||
self.MaxObjs: List[MaxObj] = []
|
self.MaxObjs: List[MaxObj] = []
|
||||||
self.SubObjs: List[SubObject] = []
|
self.SubObjs: List[SubObject] = []
|
||||||
|
|
||||||
def read(self, file):
|
|
||||||
debug = True
|
|
||||||
self.name = os.path.basename(file)
|
|
||||||
with open(file, "rb") as fp:
|
|
||||||
version_header = read_int(fp)
|
|
||||||
if version_header != GBS_VERSION:
|
|
||||||
raise Exception("File does not appear to be a GBS file.")
|
|
||||||
|
|
||||||
self.optionsflags = read_int(fp)
|
|
||||||
self.num_vertices = read_int(fp)
|
|
||||||
resize(self.vertices, Vec3, self.num_vertices)
|
|
||||||
for i in range(self.num_vertices):
|
|
||||||
self.vertices[i].x = read_float(fp)
|
|
||||||
self.vertices[i].y = read_float(fp)
|
|
||||||
self.vertices[i].z = read_float(fp)
|
|
||||||
|
|
||||||
if self.optionsflags & GBSFlagNormals:
|
|
||||||
self.nndefs = read_int(fp)
|
|
||||||
self.num_normals = read_int(fp)
|
|
||||||
resize(self.normals, int, self.num_normals)
|
|
||||||
for i in range(self.num_normals):
|
|
||||||
self.normals[i] = read_short(fp)
|
|
||||||
|
|
||||||
self.nverts = read_int(fp)
|
|
||||||
if debug: print("NVERTS=%s, NUMVERTICES=%s, options=%s" % (self.nverts, self.num_vertices, self.optionsflags))
|
|
||||||
resize(self.indexed_vertices, int, self.nverts)
|
|
||||||
for i in range(self.nverts):
|
|
||||||
self.indexed_vertices[i] = read_short(fp)
|
|
||||||
if debug: print(self.indexed_vertices)
|
|
||||||
|
|
||||||
if self.optionsflags & GBSFlagNormals:
|
|
||||||
resize(self.indexed_normals, int, self.nverts)
|
|
||||||
for i in range(self.nverts):
|
|
||||||
self.indexed_normals[i] = read_short(fp)
|
|
||||||
|
|
||||||
if self.optionsflags & GBSFlagUVs:
|
|
||||||
resize(self.vertuv, UV, self.nverts)
|
|
||||||
if debug: print("Read %s UV" % self.nverts)
|
|
||||||
for i in range(self.nverts):
|
|
||||||
self.vertuv[i].u = read_float(fp)
|
|
||||||
self.vertuv[i].v = read_float(fp) * -1
|
|
||||||
|
|
||||||
if self.optionsflags & GBSFlagRGBs:
|
|
||||||
resize(self.vertrgb, VecRGB, self.nverts)
|
|
||||||
if debug: print("Read %s RGB" % self.nverts)
|
|
||||||
for i in range(self.nverts):
|
|
||||||
self.vertrgb[i].r = read_byte(fp)
|
|
||||||
self.vertrgb[i].g = read_byte(fp)
|
|
||||||
self.vertrgb[i].b = read_byte(fp)
|
|
||||||
|
|
||||||
# Get number of objects
|
|
||||||
self.nmobjs = read_int(fp)
|
|
||||||
if debug: print("NMOBJS = %s" % self.nmobjs)
|
|
||||||
resize(self.MaxObjs, MaxObj, self.nmobjs)
|
|
||||||
for maxobj in self.MaxObjs:
|
|
||||||
print("Processing new maxobj")
|
|
||||||
fileMaxObj = FileMaxObj()
|
|
||||||
fileMaxObj.vstart = read_int(fp)
|
|
||||||
fileMaxObj.vcount = read_int(fp)
|
|
||||||
fileMaxObj.nstart = read_int(fp)
|
|
||||||
fileMaxObj.ncount = read_int(fp)
|
|
||||||
fileMaxObj.noffset = read_int(fp)
|
|
||||||
print("vstart=%s vcount=%s nstart=%s ncount=%s noffset=%s" % (fileMaxObj.vstart, fileMaxObj.vcount, fileMaxObj.nstart, fileMaxObj.ncount, fileMaxObj.noffset))
|
|
||||||
maxobj.vstart = fileMaxObj.vstart
|
|
||||||
maxobj.vcount = fileMaxObj.vcount
|
|
||||||
maxobj.nstart = fileMaxObj.nstart
|
|
||||||
maxobj.ncount = fileMaxObj.ncount
|
|
||||||
maxobj.noffset = fileMaxObj.noffset
|
|
||||||
maxobj.fstart = 0
|
|
||||||
maxobj.fcount = 0
|
|
||||||
maxobj.sostart = 0
|
|
||||||
maxobj.socount = 0
|
|
||||||
|
|
||||||
# verify max obj
|
|
||||||
nmcount = 0
|
|
||||||
for maxobj in self.MaxObjs:
|
|
||||||
nmcount += maxobj.vcount
|
|
||||||
assert nmcount == self.num_vertices
|
|
||||||
|
|
||||||
self.nsobjs = read_int(fp)
|
|
||||||
print("Subobject count: %s" % self.nsobjs)
|
|
||||||
resize(self.SubObjs, SubObject, self.nsobjs)
|
|
||||||
num_faces = 0
|
|
||||||
len_tridata = 0
|
|
||||||
for ns in range(self.nsobjs):
|
|
||||||
if debug: print("Processing subobj %s" % ns)
|
|
||||||
object = self.SubObjs[ns]
|
|
||||||
object.objname = read_string(fp, 32)
|
|
||||||
object.maxobjindex = read_int(fp)
|
|
||||||
object.totaltris = read_int(fp)
|
|
||||||
if debug: print("read %s totaltris" % object.totaltris)
|
|
||||||
num_faces += object.totaltris
|
|
||||||
object.ntris = read_int(fp)
|
|
||||||
|
|
||||||
assert ((object.ntris - 1) / 3 == object.totaltris)
|
|
||||||
|
|
||||||
resize(object.tridata, int, object.ntris + 1)
|
|
||||||
if debug: print("read gbs: totaltris: %s, tridata is %s long, ntris: %s" % (object.totaltris, len(object.tridata), object.ntris))
|
|
||||||
len_tridata += object.ntris + 1
|
|
||||||
for i in range(object.ntris):
|
|
||||||
object.tridata[i] = read_short(fp)
|
|
||||||
|
|
||||||
# if debug: print("tridata: %s" % object.tridata)
|
|
||||||
|
|
||||||
object.verticeref_start = read_int(fp)
|
|
||||||
object.verticeref_count = read_int(fp)
|
|
||||||
if self.optionsflags & GBSFlagUVs:
|
|
||||||
object.texname = read_string(fp, 32)
|
|
||||||
object.bumptexture = read_string(fp, 32)
|
|
||||||
|
|
||||||
object.falloff = read_float(fp)
|
|
||||||
if self.optionsflags & GBSFlagRGBs:
|
|
||||||
object.blend = read_float(fp)
|
|
||||||
|
|
||||||
object.flags = read_int(fp)
|
|
||||||
object.emissive = read_int(fp)
|
|
||||||
object.ambient = read_int(fp)
|
|
||||||
object.diffuse = read_int(fp)
|
|
||||||
object.specular = read_int(fp)
|
|
||||||
object.power = read_float(fp)
|
|
||||||
if debug: print("%s (%s) falloff: %s, blend: %s, flags:%s, emissive: %s, ambiant: %s, diffuse: %s, specular: %s, power: %s" % (object.objname, object.texname, object.falloff, object.blend, object.flags, object.emissive, object.ambient, object.diffuse, object.specular, object.power))
|
|
||||||
|
|
||||||
maxobj = self.MaxObjs[object.maxobjindex]
|
|
||||||
maxobj.fcount += object.totaltris
|
|
||||||
if not maxobj.socount:
|
|
||||||
maxobj.socount = ns
|
|
||||||
|
|
||||||
maxobj.socount += 1
|
|
||||||
if debug: print("read num_faces: %s, len_tridata: %s" % (num_faces, len_tridata))
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def evaluate_tridata(tridata, tri_idx, count):
|
def evaluate_tridata(tridata, tri_idx, count):
|
||||||
if count == 0:
|
if count == 0:
|
||||||
@ -368,14 +268,11 @@ class GbsData:
|
|||||||
current_object = o
|
current_object = o
|
||||||
if arr[0] == "usemtl":
|
if arr[0] == "usemtl":
|
||||||
mtl_name = arr[1].rstrip()
|
mtl_name = arr[1].rstrip()
|
||||||
print("mtl_name: %s" % mtl_name)
|
|
||||||
mtl = [mat for mat in materials if mat.name == mtl_name][0]
|
mtl = [mat for mat in materials if mat.name == mtl_name][0]
|
||||||
print("FOUND MTL: %s for name %s" % (mtl.texture, mtl_name))
|
|
||||||
current_object.material = mtl
|
current_object.material = mtl
|
||||||
last_material = mtl
|
last_material = mtl
|
||||||
if arr[0] == "mtllib":
|
if arr[0] == "mtllib":
|
||||||
matlib_file = arr[1].rstrip()
|
matlib_file = arr[1].rstrip()
|
||||||
print("Reading mtllib %s" % matlib_file)
|
|
||||||
materials = obj_read_materials("%s/%s" % (os.path.dirname(obj_file), matlib_file))
|
materials = obj_read_materials("%s/%s" % (os.path.dirname(obj_file), matlib_file))
|
||||||
|
|
||||||
num_faces = sum([len(o.faces) for o in objects])
|
num_faces = sum([len(o.faces) for o in objects])
|
||||||
@ -393,6 +290,8 @@ class GbsData:
|
|||||||
print("Your model has %s UV. Giants only supports a maximum of 65k UV per model" % len(uv_ind))
|
print("Your model has %s UV. Giants only supports a maximum of 65k UV per model" % len(uv_ind))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
check(os.path.basename(obj_file).replace(".obj", ""), materials)
|
||||||
|
|
||||||
len_vertices = len(vertices)
|
len_vertices = len(vertices)
|
||||||
len_normals = len(normals)
|
len_normals = len(normals)
|
||||||
|
|
||||||
@ -450,13 +349,10 @@ class GbsData:
|
|||||||
# start write subobjects
|
# start write subobjects
|
||||||
data.put_long(len(objects))
|
data.put_long(len(objects))
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
print("Writing object %s" % obj.name)
|
|
||||||
data.put_string_size(obj.name, 32)
|
data.put_string_size(obj.name, 32)
|
||||||
data.put_long(0) # max obj index
|
data.put_long(0) # max obj index
|
||||||
data.put_long(len(obj.faces)) # totaltris
|
data.put_long(len(obj.faces)) # totaltris
|
||||||
print("wrote %s totaltris" % len(obj.faces))
|
|
||||||
data.put_long(3 * len(obj.faces) + 1) # ntris
|
data.put_long(3 * len(obj.faces) + 1) # ntris
|
||||||
print("wrote %s ntris" % (3 * len(obj.faces) + 1))
|
|
||||||
|
|
||||||
data.put_short(len(obj.faces))
|
data.put_short(len(obj.faces))
|
||||||
for face in obj.faces: # obj.faces.length == ntris
|
for face in obj.faces: # obj.faces.length == ntris
|
||||||
@ -467,7 +363,6 @@ class GbsData:
|
|||||||
data.put_long(0) # verticeref_start
|
data.put_long(0) # verticeref_start
|
||||||
data.put_long(nverts) # verticeref_count
|
data.put_long(nverts) # verticeref_count
|
||||||
if options & GBSFlagUVs:
|
if options & GBSFlagUVs:
|
||||||
print("Writing texture to GBS: %s" % obj.material.texture)
|
|
||||||
data.put_string_size(obj.material.texture, 32) # texture
|
data.put_string_size(obj.material.texture, 32) # texture
|
||||||
data.put_string_size(obj.material.texture, 32) # bump
|
data.put_string_size(obj.material.texture, 32) # bump
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user