diff options
| author | Treeki <treeki@gmail.com> | 2011-03-13 00:19:13 +0100 | 
|---|---|---|
| committer | Treeki <treeki@gmail.com> | 2011-03-13 00:19:13 +0100 | 
| commit | b0e0d63eab1e11d1a7f841afdc7eb18e7a9de3ba (patch) | |
| tree | 82802511dfa1f34b27c2b6ea708c4a5d94f40717 /oldStuff/3dlib/obj2tmdl.py | |
| parent | 7d4e4c0b34a613dd3c0220475ae4e448197522c1 (diff) | |
| download | kamek-b0e0d63eab1e11d1a7f841afdc7eb18e7a9de3ba.tar.gz kamek-b0e0d63eab1e11d1a7f841afdc7eb18e7a9de3ba.zip  | |
this branch now features only the level select stuff
Diffstat (limited to '')
| -rwxr-xr-x | oldStuff/3dlib/obj2tmdl.py | 478 | 
1 files changed, 0 insertions, 478 deletions
diff --git a/oldStuff/3dlib/obj2tmdl.py b/oldStuff/3dlib/obj2tmdl.py deleted file mode 100755 index c726851..0000000 --- a/oldStuff/3dlib/obj2tmdl.py +++ /dev/null @@ -1,478 +0,0 @@ -#!/usr/bin/env python
 -# Obj2tmdl
 -# Converter for Wavefront OBJ => Treeki Model
 -
 -import os
 -import struct
 -import sys
 -u32 = struct.Struct('>I')
 -u16 = struct.Struct('>H')
 -u8 = struct.Struct('>B')
 -f32 = struct.Struct('>f')
 -
 -sys.path.append('/home/Treeki/Wii.py/Wii.py')
 -import Wii
 -
 -class MaterialLib:
 -	class Material:
 -		pass
 -	
 -	
 -	def __init__(self, filename):
 -		self.current_mat = None
 -		self.materials = {}
 -		
 -		for line in open(filename, 'r'):
 -			self.parse_line(line)
 -	
 -	
 -	def parse_line(self, line):
 -		line = line.strip()
 -		if line == '' or line[0] == '#':
 -			return
 -		
 -		line = line.split()
 -		cmd = line[0]
 -		
 -		if cmd == 'newmtl':
 -			self.current_mat = MaterialLib.Material()
 -			self.materials[line[1]] = self.current_mat
 -			
 -		elif cmd == 'map_Ka':
 -			self.current_mat.texture = ' '.join(line[1:])
 -			
 -		elif cmd == 'Kd':
 -			r = int(float(line[1]) * 255)
 -			g = int(float(line[2]) * 255)
 -			b = int(float(line[3]) * 255)
 -			self.current_mat.colour = (r,g,b,255)
 -	
 -	
 -	def prepare_textures(self):
 -		# get a list of every texture file used
 -		self.texture_id = {}
 -		textures = []
 -		id = 0
 -		
 -		for mat in self.materials.values():
 -			if hasattr(mat, 'texture'):
 -				if mat.texture not in textures:
 -					textures.append(mat.texture)
 -					self.texture_id[mat.texture] = id
 -					id += 1
 -		
 -		
 -		if len(textures) == 0:
 -			self.tpl = None
 -			return
 -		
 -		# create a gxtexconv script file and an ID mapping
 -		#script = []
 -		#self.texture_id = {}
 -		#
 -		#for tex, id in zip(textures, range(len(textures))):
 -		#	script.append('<filepath=\"%s\" id=\"tex%d\" colfmt=5 />' % (tex.replace('\\','/'),id))
 -		#	self.texture_id[id] = tex
 -		#
 -		#print script
 -		#
 -		#open('texture_script_temp_0991.scf', 'w').write('\n'.join(script))
 -		#
 -		#os.system('gxtexconv -s texture_script_temp_0991.scf -o generated_texture_0991.tpl')
 -		
 -		# fix this later
 -		texture_files = [tex.replace('\\','/').replace(' ','\\ ').replace('.jpg','.png') for tex in textures]
 -		print 'zetsubou wpng RGB5A3 %s generated_texture_0991.tpl' % ' '.join(texture_files)
 -		os.system('zetsubou wpng RGB5A3 %s generated_texture_0991.tpl' % ' '.join(texture_files))
 -		self.tpl = open('generated_texture_0991.tpl', 'rb').read()
 -		
 -		#os.remove('texture_script_temp_0991.scf')
 -		os.remove('generated_texture_0991.tpl')
 -
 -
 -
 -class ObjReader:
 -	class ObjShape:
 -		def __init__(self, name):
 -			self.face_groups = [						\
 -				ObjReader.ObjFaceGroup('quads'),		\
 -				ObjReader.ObjFaceGroup('triangles')]
 -			
 -			self.quad_group, self.tri_group = self.face_groups
 -			
 -			self.shape_name = name
 -			self.material_name = None
 -	
 -	
 -	class ObjFace:
 -		__slots__ = ('vertices', 'texcoords', 'normals')
 -		
 -		def __init__(self, vertices, texcoords, normals):
 -			self.vertices = vertices
 -			self.texcoords = texcoords
 -			self.normals = normals
 -	
 -	
 -	class ObjFaceGroup:
 -		def __init__(self, type):
 -			self.type = type
 -			self.faces = []
 -	
 -	
 -	def __init__(self):
 -		self.material_lib = None
 -		
 -		self.vertex_lists = []
 -		self.texcoord_lists = []
 -		self.normal_lists = []
 -		self.shapes = []
 -		
 -		self.current_shape = None
 -	
 -	
 -	def parse_line(self, line):
 -		line = line.strip()
 -		if line == '' or line[0] == '#':
 -			return
 -		
 -		line = line.split()
 -		cmd = line[0]
 -		
 -		if cmd == 'v':
 -			self.vertex_lists.append(map(float, line[1:]))
 -			
 -		elif cmd == 'vt':
 -			tc = map(float, line[1:])[:2] # chop off third coord
 -			tc[1] = 1.0 - tc[1]
 -			self.texcoord_lists.append(tc)
 -			
 -		elif cmd == 'vn':
 -			self.normal_lists.append(map(float, line[1:]))
 -			
 -		elif cmd == 'f':
 -			v, t, n = [], [], []
 -			
 -			if len(line) == 4:
 -				# triangle
 -				group = self.current_shape.tri_group
 -			elif len(line) == 5:
 -				# quad
 -				group = self.current_shape.quad_group
 -			
 -			for entry in line[1:]:
 -				entry_split = map(lambda x:-1 if x == '' else int(x), entry.split('/'))
 -				
 -				v.append(self.vertex_lists[entry_split[0] - 1])
 -				
 -				if entry_split[1] == -1:
 -					t.append([0.0, 0.0])
 -				else:
 -					t.append(self.texcoord_lists[entry_split[1] - 1])
 -				
 -				if entry_split[2] == -1:
 -					n.append([0.0, 0.0, 0.0])
 -				else:
 -					n.append(self.normal_lists[entry_split[2] - 1])
 -			
 -			group.faces.append(ObjReader.ObjFace(v, t, n))
 -			
 -		#elif cmd == 'g':
 -		#	self.current_shape = ObjReader.ObjShape(line[1])
 -		#	self.shapes.append(self.current_shape)
 -			
 -		elif cmd == 'mtllib':
 -			self.material_lib = MaterialLib(' '.join(line[1:]))
 -			
 -		elif cmd == 'usemtl':
 -			self.current_shape = ObjReader.ObjShape(line[1])
 -			self.shapes.append(self.current_shape)
 -			self.current_shape.material_name = line[1]
 -
 -
 -
 -# === Treeki Model Format ===
 -# Header:
 -#
 -# struct tmdl_header {
 -# 	u32 magic;				// always TMDL
 -# 	u32 version;			// currently 2
 -# 	u32 shape_count;
 -# };
 -# [[Followed by an array of u32s for each shape offset]]
 -#
 -# struct tmdl_shape {
 -# 	u32 dl_offset;			// must be aligned to 0x20
 -# 	u32 dl_size;			// must be aligned to 0x20
 -# 	u32 mat_offset;
 -#	u32 pos_arr_offset;		// must be aligned to 0x20
 -#	u32 pos_arr_size;		// must be aligned to 0x20
 -#	u32 nrm_arr_offset;		// must be aligned to 0x20
 -#	u32 nrm_arr_size;		// must be aligned to 0x20
 -#	u32 uv_arr_offset;		// must be aligned to 0x20
 -#	u32 uv_arr_size;		// must be aligned to 0x20
 -# };
 -#
 -# struct tmdl_material {
 -# 	u32 texture_id;			// once the model is bound, points to id within tpl
 -# };
 -#
 -# dl_offset points to a GX display list which is used for
 -# rendering the model in question.
 -
 -
 -class TmdlWriter:
 -	def __init__(self):
 -		self.shapes = []
 -	
 -	
 -	def build_with_obj(self, obj):
 -		self.shapes = obj.shapes
 -		self.material_lib = obj.material_lib
 -		self.materials = obj.material_lib.materials
 -		
 -		self.material_lib.prepare_textures()
 -	
 -	
 -	def pack(self):
 -		offset = 0
 -		
 -		header = struct.pack('>4sI I', 'TMDL', 2, len(self.shapes))
 -		offset += len(header)
 -		
 -		# reserve space for the shape offsets, we'll add them later
 -		offset += (4 * len(self.shapes))
 -		
 -		# create the materials
 -		material_offs = {}
 -		material_data = ''
 -		
 -		for name,material in self.materials.iteritems():
 -			material_offs[name] = offset
 -			material_struct = self.build_material_struct(material)
 -			material_data += material_struct
 -			offset += len(material_struct)
 -		
 -		
 -		# create the shapes -- first, we'll assemble the GX arrays and DLs
 -		shape_arrays = []
 -		packed_shape_arrays = []
 -		shape_display_lists = []
 -		
 -		print 'Building shapes... [%d]' % len(self.shapes)
 -		
 -		count = 0
 -		for shape in self.shapes:
 -			pos = self.build_array_from_shape_attr(shape, 'vertices')
 -			nrm = self.build_array_from_shape_attr(shape, 'normals')
 -			uv = self.build_array_from_shape_attr(shape, 'texcoords')
 -			shape_arrays.append((pos,nrm,uv))
 -			
 -			ppos = self.pack_data_array(pos)
 -			pnrm = self.pack_data_array(nrm)
 -			puv = self.pack_data_array(uv)
 -			packed_shape_arrays.append((ppos,pnrm,puv))
 -			
 -			dl = self.build_display_list_with_shape(shape, pos, nrm, uv)
 -			shape_display_lists.append(dl)
 -			count += 1
 -			
 -			print '%d done' % count
 -		
 -		print 'Shapes built'
 -		
 -		
 -		# calculate offsets to every display list
 -		# shape struct is currently 36 bytes, change this if the size changes
 -		# also, make sure they're aligned to an offset of 0x20
 -		temp_offset = offset + (len(self.shapes) * 36)
 -		
 -		if temp_offset & 0x1f != 0:
 -			aligned_offset = (temp_offset + 0x20) & ~0x1f
 -			dl_start_padding = '\0' * (aligned_offset - temp_offset)
 -			temp_offset = aligned_offset
 -		else:
 -			dl_start_padding = ''
 -		
 -		shape_display_list_offsets = []
 -		for dl in shape_display_lists:
 -			shape_display_list_offsets.append(temp_offset)
 -			temp_offset += len(dl)
 -		
 -		# calculate offsets to every GX array
 -		pos_array_offsets = []
 -		nrm_array_offsets = []
 -		uv_array_offsets = []
 -		
 -		for pos,nrm,uv in packed_shape_arrays:
 -			pos_array_offsets.append(temp_offset)
 -			temp_offset += len(pos)
 -			nrm_array_offsets.append(temp_offset)
 -			temp_offset += len(nrm)
 -			uv_array_offsets.append(temp_offset)
 -			temp_offset += len(uv)
 -		
 -		
 -		# and now, create the shape structs themselves
 -		shape_offsets = []
 -		shape_data = ''
 -		
 -		for shape, dl, dl_offset, pos_offs, nrm_offs, uv_offs, (pos, nrm, uv) in	\
 -			zip(self.shapes, shape_display_lists, shape_display_list_offsets,		\
 -				pos_array_offsets, nrm_array_offsets, uv_array_offsets,				\
 -				packed_shape_arrays):
 -			
 -			# first off, store the offset
 -			shape_offsets.append(offset)
 -			
 -			# now build the struct
 -			shape_struct = struct.pack('>IIIIIIIII',					\
 -				dl_offset, len(dl), material_offs[shape.material_name],	\
 -				pos_offs, len(pos),										\
 -				nrm_offs, len(nrm),										\
 -				uv_offs, len(uv))
 -			
 -			shape_data += shape_struct
 -			offset += len(shape_struct)
 -		
 -		
 -		# almost there!
 -		print 'Packing model...'
 -		
 -		tmdl_bits = [header]
 -		tmdl_add = tmdl_bits.append
 -		
 -		for offs in shape_offsets:
 -			tmdl_add(u32.pack(offs))
 -		
 -		tmdl_add(material_data)
 -		tmdl_add(shape_data)
 -		tmdl_add(dl_start_padding)
 -		
 -		tmdl_bits += shape_display_lists
 -		
 -		for pos,nrm,uv in packed_shape_arrays:
 -			tmdl_bits.append(pos)
 -			tmdl_bits.append(nrm)
 -			tmdl_bits.append(uv)
 -		
 -		return ''.join(tmdl_bits)
 -	
 -	
 -	def build_material_struct(self, material):
 -		texture_id = 0xFFFFFFFF
 -		if hasattr(material, 'texture'):
 -			texture_id = self.material_lib.texture_id[material.texture]
 -		
 -		cR, cG, cB, cA = material.colour
 -		return struct.pack('>IBBBB', texture_id, cR, cG, cB, cA)
 -	
 -	
 -	def build_array_from_shape_attr(self, shape, attr):
 -		assemble = []
 -		
 -		for g in shape.face_groups:
 -			for f in g.faces:
 -				assemble += f.__dict__[attr]
 -		
 -		final = []
 -		for i in assemble:
 -			if i not in final:
 -				final.append(i)
 -		
 -		if len(final) >= 0xFFFE:
 -			print '=== WARNING! List too big! ==='
 -		
 -		return final
 -	
 -	
 -	def pack_data_array(self, data):
 -		out = []
 -		
 -		for piece in data:
 -			for bit in piece:
 -				out.append(f32.pack(bit))
 -		
 -		packed = ''.join(out)
 -		
 -		if len(packed) % 0x20 != 0:
 -			aligned = (len(packed) + 0x1f) & ~0x1fe
 -			packed += '\0' * (aligned - len(packed))
 -		
 -		return packed
 -	
 -	
 -	def build_display_list_with_shape(self, shape, vtx_list, nrm_list, uv_list):
 -		# http://hitmen.c02.at/files/yagcd/yagcd/chap5.html
 -		# assume vertex descriptor: [data is specified in this order]
 -		# GXClearVtxDesc()
 -		# GXSetVtxDesc(GX_VA_POS, GX_DIRECT)
 -		# GXSetVtxDesc(GX_VA_NRM, GX_DIRECT)
 -		# GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT)
 -		
 -		dl_bits = []
 -		_dl_add = dl_bits.append
 -		
 -		_vtx_index = vtx_list.index
 -		_nrm_index = nrm_list.index
 -		_uv_index = uv_list.index
 -		
 -		_u16_pack = u16.pack
 -		
 -		for face_group in shape.face_groups:
 -			if len(face_group.faces) == 0:
 -				continue
 -			
 -			vtx_num = reduce(lambda x,y:x+len(y.vertices), face_group.faces, 0)
 -			
 -			# commands: GX_QUADS = 0x80, GX_TRIANGLES = 0x90
 -			if face_group.type == 'quads':
 -				_dl_add('\x80') # opcode
 -			elif face_group.type == 'triangles':
 -				_dl_add('\x90') # opcode
 -			
 -			_dl_add(u16.pack(vtx_num))
 -			
 -			# now send over the data
 -			for face in face_group.faces:
 -				for v, t, n in zip(face.vertices, face.texcoords, face.normals):
 -					_dl_add(_u16_pack(_vtx_index(v)))
 -					_dl_add(_u16_pack(_nrm_index(n)))
 -					_dl_add(_u16_pack(_uv_index(t)))
 -		
 -		# done!
 -		return self.build_display_list(dl_bits)
 -	
 -	
 -	def build_display_list(self, dl_bits):
 -		# assemble it
 -		dl = ''.join(dl_bits)
 -		
 -		# pad the display list to 0x20 bytes with GX_NOP (0x00)
 -		if len(dl) % 0x20 != 0:
 -			pad_count = ((len(dl) + 0x20) & ~0x1F) - len(dl)
 -			dl += '\x00' * pad_count
 -		
 -		return dl
 -
 -
 -#file = r'H:\ISOs\NSMBWii\testmush3'
 -#file = 'testmdl2'
 -#file = 'simple2'
 -file = sys.argv[1]
 -shortfn = file[file.rfind('/')+1:]
 -
 -obj = ObjReader()
 -for line in open(file+'.obj'):
 -	obj.parse_line(line)
 -
 -tmdl = TmdlWriter()
 -tmdl.build_with_obj(obj)
 -
 -tmdl_file = tmdl.pack()
 -tpl_file = tmdl.material_lib.tpl
 -
 -arc = Wii.U8()
 -arc['t3d'] = None
 -arc['t3d/mdl_%s.tmdl' % shortfn] = tmdl_file
 -if tpl_file: arc['t3d/tex_%s.tpl' % shortfn] = tpl_file
 -arc.dumpFile('%s.arc' % file)
  | 
