1*b7c941bbSAndroid Build Coastguard Workerimport os, bpy, struct 2*b7c941bbSAndroid Build Coastguard Workerfrom bpy_extras.io_utils import ExportHelper 3*b7c941bbSAndroid Build Coastguard Workerfrom bpy.props import StringProperty, BoolProperty, EnumProperty 4*b7c941bbSAndroid Build Coastguard Worker 5*b7c941bbSAndroid Build Coastguard Worker# This is a custom Blender export script to output an object to a format that's easy to use in 6*b7c941bbSAndroid Build Coastguard Worker# android. While open gl allows the use of an index buffer for vertices, the same cannot be done 7*b7c941bbSAndroid Build Coastguard Worker# for texture coordinates, which is why this script duplicates the vertices and normals. This 8*b7c941bbSAndroid Build Coastguard Worker# gives a larger but faster loading file, hence the tongue-in-cheek name "Compressed" object file. 9*b7c941bbSAndroid Build Coastguard Worker# The format is number of vertices + list of vertices (3 coord, 3 normal, 2 texcoord) 10*b7c941bbSAndroid Build Coastguard Workerbl_info = { 11*b7c941bbSAndroid Build Coastguard Worker "name": "COB Exporter", 12*b7c941bbSAndroid Build Coastguard Worker "description": "Exports the active scene into a Compressed Object file.", 13*b7c941bbSAndroid Build Coastguard Worker "author": "Stuart Scott", 14*b7c941bbSAndroid Build Coastguard Worker "version": (1, 0, 0), 15*b7c941bbSAndroid Build Coastguard Worker "blender": (2, 6, 2), 16*b7c941bbSAndroid Build Coastguard Worker "api": 36339, 17*b7c941bbSAndroid Build Coastguard Worker "location": "File > Export > COB Exporter (.cob)", 18*b7c941bbSAndroid Build Coastguard Worker "warning": "", # used for warning icon and text in addons panel 19*b7c941bbSAndroid Build Coastguard Worker "wiki_url": "", 20*b7c941bbSAndroid Build Coastguard Worker "tracker_url": "", 21*b7c941bbSAndroid Build Coastguard Worker "category": "Import-Export" 22*b7c941bbSAndroid Build Coastguard Worker } 23*b7c941bbSAndroid Build Coastguard Worker 24*b7c941bbSAndroid Build Coastguard Workerclass COBExporter(bpy.types.Operator, ExportHelper): 25*b7c941bbSAndroid Build Coastguard Worker '''Exports the current scene into a Compressed Object format.''' 26*b7c941bbSAndroid Build Coastguard Worker bl_idname = "export.cob_exporter" # this is important since its how bpy.ops.export.cob_exporter is constructed 27*b7c941bbSAndroid Build Coastguard Worker bl_label = "COB Exporter" 28*b7c941bbSAndroid Build Coastguard Worker 29*b7c941bbSAndroid Build Coastguard Worker filename_ext = ".cob" 30*b7c941bbSAndroid Build Coastguard Worker 31*b7c941bbSAndroid Build Coastguard Worker filter_glob = StringProperty(default="*.cob", options={'HIDDEN'}) 32*b7c941bbSAndroid Build Coastguard Worker 33*b7c941bbSAndroid Build Coastguard Worker def execute(self, context): 34*b7c941bbSAndroid Build Coastguard Worker mesh = context.active_object 35*b7c941bbSAndroid Build Coastguard Worker if mesh.type != 'MESH': 36*b7c941bbSAndroid Build Coastguard Worker print("Active object is not a mesh") 37*b7c941bbSAndroid Build Coastguard Worker return {'FINISHED'} 38*b7c941bbSAndroid Build Coastguard Worker if mesh.mode != 'OBJECT': 39*b7c941bbSAndroid Build Coastguard Worker bpy.ops.object.mode_set(mode='OBJECT', toggle=False) 40*b7c941bbSAndroid Build Coastguard Worker print("Writing "+mesh.name+" to "+self.filepath) 41*b7c941bbSAndroid Build Coastguard Worker uvtex = mesh.data.uv_textures.active # points to active texture 42*b7c941bbSAndroid Build Coastguard Worker f = open(self.filepath, 'wb') 43*b7c941bbSAndroid Build Coastguard Worker f.write(struct.pack(">i", len(uvtex.data) * 3))# write length 44*b7c941bbSAndroid Build Coastguard Worker for uv_index, uv_itself in enumerate(uvtex.data): 45*b7c941bbSAndroid Build Coastguard Worker # get uv for this face 46*b7c941bbSAndroid Build Coastguard Worker uvs = uv_itself.uv1, uv_itself.uv2, uv_itself.uv3 47*b7c941bbSAndroid Build Coastguard Worker for vertex_index, vertex_itself in enumerate(mesh.data.faces[uv_index].vertices): 48*b7c941bbSAndroid Build Coastguard Worker # for each vertex in the face 49*b7c941bbSAndroid Build Coastguard Worker vertex = mesh.data.vertices[vertex_itself] 50*b7c941bbSAndroid Build Coastguard Worker v = vertex.co.xyz 51*b7c941bbSAndroid Build Coastguard Worker n = vertex.normal.xyz 52*b7c941bbSAndroid Build Coastguard Worker t = uvs[vertex_index] 53*b7c941bbSAndroid Build Coastguard Worker f.write(struct.pack(">ffffffff", v[0], v[1], v[2], n[0], n[1], n[2], t[0], 1 - t[1])) 54*b7c941bbSAndroid Build Coastguard Worker f.close() 55*b7c941bbSAndroid Build Coastguard Worker return {'FINISHED'} 56*b7c941bbSAndroid Build Coastguard Worker 57*b7c941bbSAndroid Build Coastguard Worker @classmethod 58*b7c941bbSAndroid Build Coastguard Worker def poll(cls, context): 59*b7c941bbSAndroid Build Coastguard Worker return context.active_object != None 60*b7c941bbSAndroid Build Coastguard Worker 61*b7c941bbSAndroid Build Coastguard Worker# Only needed if you want to add into a dynamic menu 62*b7c941bbSAndroid Build Coastguard Workerdef menu_func(self, context): 63*b7c941bbSAndroid Build Coastguard Worker default_path = os.path.splitext(bpy.data.filepath)[0] + ".cob" 64*b7c941bbSAndroid Build Coastguard Worker self.layout.operator(COBExporter.bl_idname, text="Compressed Object (.cob)").filepath = default_path 65*b7c941bbSAndroid Build Coastguard Worker 66*b7c941bbSAndroid Build Coastguard Workerdef register(): 67*b7c941bbSAndroid Build Coastguard Worker bpy.utils.register_module(__name__) 68*b7c941bbSAndroid Build Coastguard Worker bpy.types.INFO_MT_file_export.append(menu_func) 69*b7c941bbSAndroid Build Coastguard Worker 70*b7c941bbSAndroid Build Coastguard Workerdef unregister(): 71*b7c941bbSAndroid Build Coastguard Worker bpy.utils.unregister_module(__name__) 72*b7c941bbSAndroid Build Coastguard Worker bpy.types.INFO_MT_file_export.remove(menu_func) 73*b7c941bbSAndroid Build Coastguard Worker 74*b7c941bbSAndroid Build Coastguard Workerif __name__ == "__main__": 75*b7c941bbSAndroid Build Coastguard Worker register() 76