Created
February 24, 2016 14:12
-
-
Save Numbers11/f7a44a24df43618149a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
global file | |
#import fbx | |
import sys | |
import math | |
#import FbxCommon | |
import functools | |
import itertools | |
import numpy as np | |
import bpy, mathutils | |
import bmesh | |
def readcstr(f): | |
buf = bytearray() | |
while True: | |
b = f.read(1) | |
if b is None or b == b'\0': | |
return buf.decode() | |
else: | |
buf.extend(b) | |
class BinaryReaderEOFException(Exception): | |
def __init__(self): | |
pass | |
def __str__(self): | |
return 'Not enough bytes in file to satisfy read request' | |
class BinaryReader: | |
# Map well-known type names into struct format characters. | |
typeNames = { | |
'int8' :'b', | |
'uint8' :'B', | |
'int16' :'h', | |
'uint16' :'H', | |
'int32' :'i', | |
'uint32' :'I', | |
'int64' :'q', | |
'uint64' :'Q', | |
'float' :'f', | |
'double' :'d', | |
'char' :'s'} | |
def __init__(self, fileName): | |
self.file = fileName | |
def read(self, typeName): | |
typeFormat = BinaryReader.typeNames[typeName.lower()] | |
typeSize = struct.calcsize(typeFormat) | |
value = self.file.read(typeSize) | |
if typeSize != len(value): | |
raise BinaryReaderEOFException | |
return struct.unpack(typeFormat, value)[0] | |
def readString(self, length): | |
typeFormat = str(length) + "s" | |
typeSize = struct.calcsize(typeFormat) | |
value = self.file.read(typeSize) | |
if typeSize != len(value): | |
raise BinaryReaderEOFException | |
return struct.unpack(typeFormat, value)[0] | |
def __del__(self): | |
self.file.close() | |
def readFileHeader(): | |
try: | |
signature = binaryReader.read('uint32') | |
unkown1 = binaryReader.read('uint32') | |
unkown2 = binaryReader.read('uint32') | |
blocknum = binaryReader.read('uint32') | |
#print blocknum | |
blocks = [] | |
for x in range(0, blocknum): | |
#struct.unpack('4s', name) | |
block = {} | |
block["name"] = binaryReader.readString(4) | |
#pos = BinaryReader.getPos(); | |
pos = file.tell() | |
block["offset"] = binaryReader.read('uint32') | |
block["link"] = pos + block["offset"]; | |
block["size"] = binaryReader.read('uint32') | |
blocks.append(block) | |
#print block | |
return blocks | |
except BinaryReaderEOFException: | |
# One of our attempts to read a field went beyond the end of the file. | |
print("Error: File seems to be corrupted.") | |
def readVBIB(offset): | |
file.seek(offset) | |
pos = file.tell() | |
header = {} | |
header["vertexHOffset"] = binaryReader.read('uint32') | |
header["vertexHLink"] = pos + header["vertexHOffset"] | |
header["vertexHCount"] = binaryReader.read('uint32') | |
pos = file.tell() | |
header["indexHOffset"] = binaryReader.read('uint32') | |
header["indexHLink"] = pos + header["indexHOffset"] | |
header["indexHCount"] = binaryReader.read('uint32') | |
return header | |
def readVertices(offset, count): | |
vertexgroups = [] | |
for x in range(0, count): | |
vertices = {} | |
file.seek(offset + x * 24) | |
vertices["count"] = binaryReader.read('uint32') | |
file.seek(offset + x * 24 + 16) | |
vertices["link"] = offset + x * 24 + 16 + binaryReader.read('uint32') | |
vertices["vertex"] = [] | |
vertices["boneid"] = [] | |
vertices["boneweight"] = [] | |
file.seek(offset + x * 24 + 4) | |
vertices["size"] = binaryReader.read('uint32'); | |
file.seek(vertices["link"]) | |
for q in range(0, vertices["count"]): | |
x = binaryReader.read("float") | |
y = binaryReader.read("float") | |
z = binaryReader.read("float") | |
bonenum = binaryReader.read("uint8") | |
#print bonenum | |
#print x, y, z | |
boneid1 = binaryReader.read("uint8") | |
boneid2 = binaryReader.read("uint8") | |
boneid3 = binaryReader.read("uint8") | |
#print boneid1,boneid2,boneid3 | |
boneweight1 = binaryReader.read("uint8") | |
boneweight2 = binaryReader.read("uint8") | |
boneweight3 = binaryReader.read("uint8") | |
#print boneweight1,boneweight2,boneweight3 | |
#not sure what any of this shit is except the vertices | |
binaryReader.read("char") #crap? | |
binaryReader.readString(vertices["size"] - 20) #skip whatever is still there | |
vertices["vertex"].append((x,y,z)) | |
vertices["boneid"].append([boneid1,boneid2,boneid3]) | |
vertices["boneweight"].append([boneweight1,boneweight2,boneweight3]) | |
vertexgroups.append(vertices) | |
return vertexgroups | |
def readAttributes(offset, count): | |
attributes = {} | |
for x in range(0, count): | |
file.seek(offset + x * 24 + 12) | |
acount = binaryReader.read("uint32") | |
print( acount) | |
file.seek(offset + 24 * x + 8) | |
pos = binaryReader.read("uint32") | |
# print pos | |
link = offset + 24 * x + 8 + pos | |
#print link | |
for y in range (0,acount): | |
here = link + y *56 | |
file.seek(here) | |
name = readcstr(file) | |
# print name | |
file.seek(here + 40) | |
attributes[name] = binaryReader.read("uint32") | |
return attributes | |
def readTexcoords(vertices, offset): | |
htexcoords = [] | |
for x in range (0,len(vertices)): | |
texcoords = [] | |
for y in range (0,len(vertices[x]["vertex"])): | |
file.seek(vertices[x]["link"] + y * vertices[x]["size"] + offset) | |
qbuffer = file.read(2) | |
u = np.frombuffer(qbuffer, dtype=np.float16)[0] | |
qbuffer = file.read(2) | |
v = 1 - np.frombuffer(qbuffer, dtype=np.float16)[0] | |
texcoords.append((u, v)) | |
htexcoords.append(texcoords) | |
return htexcoords | |
def readBlendIndices(vertices, offset): | |
hblendindices = [] | |
for x in range (0,len(vertices)): | |
blendindices = [] | |
for y in range (0,len(vertices[x]["vertex"])): | |
file.seek(vertices[x]["link"] + y * vertices[x]["size"] + offset) | |
a = binaryReader.read("uint8") | |
b = binaryReader.read("uint8") | |
c = binaryReader.read("uint8") | |
d = binaryReader.read("uint8") #bone num? unused? bullshit? you decide | |
#print a,b,c,d | |
blendindices.append((a,b,c,d)) | |
hblendindices.append(blendindices) | |
return hblendindices | |
def readBlendWeights(vertices, offset): | |
hblendweights = [] | |
for x in range (0,len(vertices)): | |
blendweights = [] | |
for y in range (0,len(vertices[x]["vertex"])): | |
file.seek(vertices[x]["link"] + y * vertices[x]["size"] + offset) | |
a = binaryReader.read("uint8") | |
b = binaryReader.read("uint8") | |
c = binaryReader.read("uint8") | |
#print(a,b,c) | |
blendweights.append((a,b,c)) | |
hblendweights.append(blendweights) | |
return hblendweights | |
def readIndices(offset, count): | |
indexgroups = [] | |
for x in range(0, count): | |
indices = {} | |
file.seek(offset + x * 24) | |
indices["count"] = binaryReader.read('uint32') | |
file.seek(offset + x * 24 + 16) | |
indices["link"] = offset + x * 24 + 16 + binaryReader.read('uint32') | |
indices["index"] = [] | |
file.seek(indices["link"]) | |
for q in range(0, int(indices["count"] / 3)): | |
a = binaryReader.read("uint16") | |
b = binaryReader.read("uint16") | |
c = binaryReader.read("uint16") | |
#print a,b,c | |
indices["index"].append((a,b,c)) | |
indexgroups.append(indices) | |
return indexgroups | |
#### | |
#blender stuff | |
def createMesh(origin, verts, faces, texcoords): | |
# Create mesh and object | |
me = bpy.data.meshes.new('Mesh') | |
ob = bpy.data.objects.new('MeshObject', me) | |
ob.location = origin | |
# Link object to scene | |
scn = bpy.context.scene | |
scn.objects.link(ob) | |
scn.objects.active = ob | |
scn.update() | |
# Create mesh from given verts, edges, faces. Either edges or | |
# faces should be [], or you ask for problems | |
me.from_pydata(verts, [], faces) | |
# Update mesh with new data | |
me.update(calc_edges=True) | |
me.uv_textures.new() | |
uv_data = me.uv_layers[0].data | |
for i in range(len(uv_data)): | |
uv_data[i].uv = texcoords[me.loops[i].vertex_index] | |
return ob | |
##MAIN PROGRAM | |
#read data from model | |
filename = 'C:\\Users\\Bene\\Desktop\\cube\\axe_model.vmesh_c' | |
file = open(filename, 'rb') | |
binaryReader = BinaryReader(file) | |
header = readFileHeader() | |
#print header | |
vbibheader = readVBIB(header[3]["link"]) | |
#print vbibheader | |
hvertices = readVertices(vbibheader["vertexHLink"], vbibheader["vertexHCount"]) | |
hindices = readIndices(vbibheader["indexHLink"], vbibheader["indexHCount"]) | |
print ("Number of vertices: ", hvertices[0]["count"]) | |
print ("Number of indices: ", int(hindices[0]["count"] / 3)) | |
attributes = readAttributes(vbibheader["vertexHLink"], vbibheader["vertexHCount"]) | |
print( attributes) | |
htexcoords = readTexcoords(hvertices, attributes["TEXCOORD"]) | |
#print htexcoords | |
if "BLENDWEIGHT" in attributes: | |
readBlendWeights(hvertices, attributes["BLENDWEIGHT"]) | |
if "BLENDINDICES" in attributes: | |
readBlendIndices(hvertices, attributes["BLENDINDICES"]) | |
vertices = hvertices[0]["vertex"] | |
indices = hindices[0]["index"] | |
texcoords = htexcoords[0] | |
createMesh((0,0,0), vertices, indices, texcoords) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment