nuclear@39: # Goat3D Blender >2.63 exporter nuclear@40: import bpy nuclear@36: import ctypes nuclear@36: from ctypes import * nuclear@36: from ctypes.util import find_library nuclear@33: nuclear@40: GOAT3D_MAT_ATTR_DIFFUSE = "diffuse".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_SPECULAR = "specular".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_SHININESS = "shininess".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_NORMAL = "normal".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_BUMP = "bump".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_REFLECTION = "reflection".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_TRANSMISSION = "transmission".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_IOR = "ior".encode('utf-8') nuclear@40: GOAT3D_MAT_ATTR_ALPHA = "alpha".encode('utf-8') nuclear@40: nuclear@40: # these must match the goat3d_vertex_attr enumeration values in goat3d.h nuclear@40: GOAT3D_MESH_ATTR_VERTEX = 0 nuclear@40: GOAT3D_MESH_ATTR_NORMAL = 1 nuclear@40: GOAT3D_MESH_ATTR_TANGENT = 2 nuclear@40: GOAT3D_MESH_ATTR_TEXCOORD = 3 nuclear@40: GOAT3D_MESH_ATTR_SKIN_WEIGHT = 4 nuclear@40: GOAT3D_MESH_ATTR_SKIN_MATRIX = 5 nuclear@40: GOAT3D_MESH_ATTR_COLOR = 6 nuclear@40: nuclear@33: nuclear@38: def export(oper, ctx, fname): nuclear@38: print("Exporting goat3d file: " + fname) nuclear@33: nuclear@39: lib = init_libgoat() nuclear@39: if not lib: nuclear@39: return False nuclear@39: nuclear@39: # initiaize a goat3d object and start filling it up with data nuclear@39: goat = lib.goat3d_create() nuclear@39: if not goat: nuclear@39: oper.report({'ERROR'}, "Failed to create goat3d object") nuclear@39: return False nuclear@39: nuclear@39: lib.goat3d_set_name(goat, fname.encode('utf-8')) nuclear@39: nuclear@39: export_env(ctx, goat, lib) nuclear@39: export_meshes(ctx, goat, lib) nuclear@39: export_nodes(ctx, goat, lib) nuclear@39: nuclear@39: lib.goat3d_save(goat, fname.encode('utf-8')) nuclear@39: lib.goat3d_free(goat) nuclear@39: return True nuclear@39: nuclear@39: def export_env(ctx, goat, lib): nuclear@39: return False nuclear@39: nuclear@40: def export_material(bmtl, goat, lib): nuclear@40: name = bmtl.name.encode("utf-8") nuclear@40: nuclear@40: mtl = lib.goat3d_create_mtl() nuclear@40: lib.goat3d_set_mtl_name(mtl, name) nuclear@40: nuclear@40: s = bmtl.diffuse_intensity nuclear@40: col = bmtl.diffuse_color nuclear@40: lib.goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, c_float(col[0] * s), c_float(col[1] * s), c_float(col[2] * s), 1.0) nuclear@40: nuclear@40: s = bmtl.specular_intensity nuclear@40: col = bmtl.specular_color nuclear@40: lib.goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_SPECULAR, c_float(col[0] * s), c_float(col[1] * s), c_float(col[2] * s), 1.0) nuclear@40: lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, c_float(bmtl.specular_hardness)) nuclear@40: lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_ALPHA, c_float(bmtl.alpha)) nuclear@40: nuclear@40: if bmtl.raytrace_mirror.use: nuclear@40: lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_REFLECTION, c_float(bmtl.raytrace_mirror.reflect_factor)) nuclear@40: if bmtl.use_transparency and bmtl.transparency_method == 'RAYTRACE': nuclear@40: lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_IOR, c_float(bmtl.raytrace_transparency.ior)) nuclear@40: lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, 1.0) nuclear@40: nuclear@40: # grab all the textures and apply them to the correct attributes nuclear@40: for texslot in bmtl.texture_slots: nuclear@40: if not texslot: nuclear@40: continue nuclear@40: nuclear@40: tex = texslot.texture nuclear@40: if tex.type != 'IMAGE': nuclear@40: print("ignoring texture " + tex.name + ": not an image!") nuclear@40: continue nuclear@40: nuclear@40: fname = tex.image.filepath.encode('ascii') nuclear@40: nuclear@40: attr = "" nuclear@40: if texslot.use_map_color_diffuse or texslot.use_map_diffuse: nuclear@40: attr = GOAT3D_MAT_ATTR_DIFFUSE nuclear@40: elif texslot.use_map_color_spec or texslot.use_map_specular: nuclear@40: attr = GOAT3D_MAT_ATTR_SPECULAR nuclear@40: elif texslot.use_map_color_reflection or texslot.use_map_reflect: nuclear@40: attr = GOAT3D_MAT_ATTR_REFLECTION nuclear@40: elif texslot.use_map_hardness: nuclear@40: attr = GOAT3D_MAT_ATTR_SHININESS nuclear@40: elif texslot.use_map_alpha: nuclear@40: attr = GOAT3D_MAT_ATTR_ALPHA nuclear@40: elif texslot.use_map_normal: nuclear@40: attr = GOAT3D_MAT_ATTR_NORMAL nuclear@40: nuclear@40: if attr != "": nuclear@40: lib.goat3d_set_mtl_attrib_map(mtl, attr, fname) nuclear@40: nuclear@40: lib.goat3d_add_mtl(goat, mtl) nuclear@40: return mtl nuclear@40: nuclear@39: nuclear@39: def export_meshes(ctx, goat, lib): nuclear@39: print("exporting " + str(len(ctx.scene.objects)) + " objects") nuclear@39: for obj in ctx.scene.objects: nuclear@39: if obj.type != 'MESH': nuclear@39: continue nuclear@39: nuclear@40: bmesh = obj.data nuclear@39: # make sure we get a tesselated mesh nuclear@40: bmesh.update(calc_tessface = True) nuclear@39: nuclear@40: # create goat3d mesh and set the data nuclear@40: mesh = lib.goat3d_create_mesh() nuclear@40: lib.goat3d_set_mesh_name(mesh, bmesh.name.encode("utf-8")) nuclear@40: nuclear@40: # get the material, add it to the scene and apply it to this mesh nuclear@40: for bmtl in bmesh.materials: nuclear@40: mtl = export_material(bmtl, goat, lib) nuclear@40: lib.goat3d_set_mesh_mtl(mesh, mtl) nuclear@40: break # we only care about one material nuclear@40: nuclear@40: for vert in bmesh.vertices: nuclear@40: v = vert.co nuclear@40: n = vert.normal nuclear@40: lib.goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_VERTEX, v[0], v[1], v[2]) nuclear@40: lib.goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_NORMAL, n[0], n[1], n[2]) nuclear@40: nuclear@40: for face in bmesh.tessfaces: nuclear@39: fverts = face.vertices nuclear@40: lib.goat3d_add_mesh_face(mesh, fverts[0], fverts[1], fverts[2]) nuclear@39: nuclear@40: lib.goat3d_add_mesh(goat, mesh) nuclear@39: return False nuclear@39: nuclear@39: nuclear@39: def export_nodes(ctx, goat, lib): nuclear@39: return False nuclear@39: nuclear@39: def init_libgoat(): nuclear@38: # load all relevant functions from libgoat3d nuclear@38: libname = find_library("goat3d") nuclear@38: if not libname: nuclear@38: oper.report({'ERROR'}, "Could not find the goat3d library! make sure it's installed.") nuclear@39: return None nuclear@33: nuclear@39: lib = CDLL(libname) nuclear@39: if not lib: nuclear@38: oper.report({'ERROR'}, "Could not open goat3d library!") nuclear@39: return None nuclear@37: nuclear@39: lib.goat3d_create.argtypes = None nuclear@39: lib.goat3d_create.restype = c_void_p nuclear@36: nuclear@39: lib.goat3d_free.argtypes = [c_void_p] nuclear@39: lib.goat3d_free.restype = None nuclear@36: nuclear@39: lib.goat3d_set_name.argtypes = [c_void_p, c_char_p] nuclear@36: nuclear@39: lib.goat3d_set_ambient3f.argtypes = [c_void_p, c_float, c_float, c_float] nuclear@39: lib.goat3d_set_ambient3f.restype = None nuclear@36: nuclear@39: lib.goat3d_add_mtl.argtypes = [c_void_p, c_void_p] nuclear@39: lib.goat3d_add_mtl.restype = None nuclear@36: nuclear@39: lib.goat3d_create_mtl.argtypes = None nuclear@39: lib.goat3d_create_mtl.restype = c_void_p nuclear@36: nuclear@39: lib.goat3d_set_mtl_name.argtypes = [c_void_p, c_char_p] nuclear@39: lib.goat3d_set_mtl_name.restype = None nuclear@33: nuclear@40: lib.goat3d_set_mtl_attrib1f.argtypes = [c_void_p, c_char_p, c_float] nuclear@40: lib.goat3d_set_mtl_attrib1f.restype = None nuclear@40: nuclear@39: lib.goat3d_set_mtl_attrib4f.argtypes = [c_void_p, c_char_p, c_float, c_float, c_float, c_float] nuclear@39: lib.goat3d_set_mtl_attrib4f.restype = None nuclear@33: nuclear@39: lib.goat3d_set_mtl_attrib_map.argtypes = [c_void_p, c_char_p, c_char_p] nuclear@39: lib.goat3d_set_mtl_attrib_map.restype = None nuclear@33: nuclear@39: lib.goat3d_add_mesh.argtypes = [c_void_p, c_void_p] nuclear@39: lib.goat3d_add_mesh.restype = None nuclear@33: nuclear@39: lib.goat3d_create_mesh.argtypes = None nuclear@39: lib.goat3d_create_mesh.restype = c_void_p nuclear@38: nuclear@39: lib.goat3d_set_mesh_name.argtypes = [c_void_p, c_char_p] nuclear@39: lib.goat3d_set_mesh_name.restype = None nuclear@38: nuclear@39: lib.goat3d_set_mesh_mtl.argtypes = [c_void_p, c_void_p] nuclear@39: lib.goat3d_set_mesh_mtl.restype = None nuclear@38: nuclear@40: lib.goat3d_add_mesh_attrib3f.argtypes = [c_void_p, c_int, c_float, c_float, c_float] nuclear@40: lib.goat3d_add_mesh_attrib3f.restype = None nuclear@38: nuclear@40: lib.goat3d_add_mesh_attrib4f.argtypes = [c_void_p, c_int, c_float, c_float, c_float, c_float] nuclear@40: lib.goat3d_add_mesh_attrib4f.restype = None nuclear@40: nuclear@40: lib.goat3d_add_mesh_face.argtypes = [c_void_p, c_int, c_int, c_int] nuclear@40: lib.goat3d_add_mesh_face.restype = None nuclear@38: nuclear@39: lib.goat3d_add_node.argtypes = [c_void_p, c_void_p] nuclear@39: lib.goat3d_add_node.restype = None nuclear@38: nuclear@39: lib.goat3d_create_node.argtypes = None nuclear@39: lib.goat3d_create_node.restype = c_void_p nuclear@38: nuclear@39: lib.goat3d_set_node_name.argtypes = [c_void_p, c_char_p] nuclear@39: lib.goat3d_set_node_name.restype = None nuclear@38: nuclear@39: lib.goat3d_set_node_object.argtypes = [c_void_p, c_int, c_void_p] nuclear@39: lib.goat3d_set_node_object.restype = None nuclear@38: nuclear@39: lib.goat3d_add_node_child.argtypes = [c_void_p, c_void_p] nuclear@39: lib.goat3d_add_node_child.restype = None nuclear@38: nuclear@39: lib.goat3d_set_node_position.argtypes = [c_void_p, c_float, c_float, c_float, c_long] nuclear@39: lib.goat3d_set_node_position.restype = None nuclear@38: nuclear@39: lib.goat3d_set_node_rotation.argtypes = [c_void_p, c_float, c_float, c_float, c_float, c_long] nuclear@39: lib.goat3d_set_node_rotation.restype = None nuclear@38: nuclear@39: lib.goat3d_set_node_scaling.argtypes = [c_void_p, c_float, c_float, c_float, c_long] nuclear@39: lib.goat3d_set_node_scaling.restype = None nuclear@38: nuclear@39: lib.goat3d_set_node_pivot.argtypes = [c_void_p, c_float, c_float, c_float] nuclear@39: lib.goat3d_set_node_pivot.restype = None nuclear@38: nuclear@39: lib.goat3d_save.argtypes = [c_void_p, c_char_p] nuclear@39: return lib