# HG changeset patch # User John Tsiombikas # Date 1381648459 -10800 # Node ID a5c5cec3cb88c17b1e2711d92187fdcc9ee57050 # Parent 0e48907847addb28a2e7757e5f20e24cf6115763 - added mesh attribute and face append functions - added Int4 constructor - continued the blender exporter - fixed a bug in clean_filename which made it produce unterminated strings - renamed clean_filename to goat3d_clean_filename and made it extern - added call to goat3d_clean_filename in the mesh XML export code to cleanup ctm filenames diff -r 0e48907847ad -r a5c5cec3cb88 exporters/blendgoat/src/export_goat.py --- a/exporters/blendgoat/src/export_goat.py Wed Oct 09 16:40:59 2013 +0300 +++ b/exporters/blendgoat/src/export_goat.py Sun Oct 13 10:14:19 2013 +0300 @@ -1,9 +1,28 @@ # Goat3D Blender >2.63 exporter -import bpy; +import bpy import ctypes from ctypes import * from ctypes.util import find_library +GOAT3D_MAT_ATTR_DIFFUSE = "diffuse".encode('utf-8') +GOAT3D_MAT_ATTR_SPECULAR = "specular".encode('utf-8') +GOAT3D_MAT_ATTR_SHININESS = "shininess".encode('utf-8') +GOAT3D_MAT_ATTR_NORMAL = "normal".encode('utf-8') +GOAT3D_MAT_ATTR_BUMP = "bump".encode('utf-8') +GOAT3D_MAT_ATTR_REFLECTION = "reflection".encode('utf-8') +GOAT3D_MAT_ATTR_TRANSMISSION = "transmission".encode('utf-8') +GOAT3D_MAT_ATTR_IOR = "ior".encode('utf-8') +GOAT3D_MAT_ATTR_ALPHA = "alpha".encode('utf-8') + +# these must match the goat3d_vertex_attr enumeration values in goat3d.h +GOAT3D_MESH_ATTR_VERTEX = 0 +GOAT3D_MESH_ATTR_NORMAL = 1 +GOAT3D_MESH_ATTR_TANGENT = 2 +GOAT3D_MESH_ATTR_TEXCOORD = 3 +GOAT3D_MESH_ATTR_SKIN_WEIGHT = 4 +GOAT3D_MESH_ATTR_SKIN_MATRIX = 5 +GOAT3D_MESH_ATTR_COLOR = 6 + def export(oper, ctx, fname): print("Exporting goat3d file: " + fname) @@ -21,7 +40,6 @@ lib.goat3d_set_name(goat, fname.encode('utf-8')) export_env(ctx, goat, lib) - export_materials(ctx, goat, lib) export_meshes(ctx, goat, lib) export_nodes(ctx, goat, lib) @@ -32,8 +50,60 @@ def export_env(ctx, goat, lib): return False -def export_materials(ctx, goat, lib): - return False +def export_material(bmtl, goat, lib): + name = bmtl.name.encode("utf-8") + + mtl = lib.goat3d_create_mtl() + lib.goat3d_set_mtl_name(mtl, name) + + s = bmtl.diffuse_intensity + col = bmtl.diffuse_color + 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) + + s = bmtl.specular_intensity + col = bmtl.specular_color + 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) + lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, c_float(bmtl.specular_hardness)) + lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_ALPHA, c_float(bmtl.alpha)) + + if bmtl.raytrace_mirror.use: + lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_REFLECTION, c_float(bmtl.raytrace_mirror.reflect_factor)) + if bmtl.use_transparency and bmtl.transparency_method == 'RAYTRACE': + lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_IOR, c_float(bmtl.raytrace_transparency.ior)) + lib.goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, 1.0) + + # grab all the textures and apply them to the correct attributes + for texslot in bmtl.texture_slots: + if not texslot: + continue + + tex = texslot.texture + if tex.type != 'IMAGE': + print("ignoring texture " + tex.name + ": not an image!") + continue + + fname = tex.image.filepath.encode('ascii') + + attr = "" + if texslot.use_map_color_diffuse or texslot.use_map_diffuse: + attr = GOAT3D_MAT_ATTR_DIFFUSE + elif texslot.use_map_color_spec or texslot.use_map_specular: + attr = GOAT3D_MAT_ATTR_SPECULAR + elif texslot.use_map_color_reflection or texslot.use_map_reflect: + attr = GOAT3D_MAT_ATTR_REFLECTION + elif texslot.use_map_hardness: + attr = GOAT3D_MAT_ATTR_SHININESS + elif texslot.use_map_alpha: + attr = GOAT3D_MAT_ATTR_ALPHA + elif texslot.use_map_normal: + attr = GOAT3D_MAT_ATTR_NORMAL + + if attr != "": + lib.goat3d_set_mtl_attrib_map(mtl, attr, fname) + + lib.goat3d_add_mtl(goat, mtl) + return mtl + def export_meshes(ctx, goat, lib): print("exporting " + str(len(ctx.scene.objects)) + " objects") @@ -41,20 +111,31 @@ if obj.type != 'MESH': continue - mesh = obj.data + bmesh = obj.data # make sure we get a tesselated mesh - mesh.update(calc_tessface = True) + bmesh.update(calc_tessface = True) - triangles = [] - for idx, face in enumerate(mesh.tessfaces): + # create goat3d mesh and set the data + mesh = lib.goat3d_create_mesh() + lib.goat3d_set_mesh_name(mesh, bmesh.name.encode("utf-8")) + + # get the material, add it to the scene and apply it to this mesh + for bmtl in bmesh.materials: + mtl = export_material(bmtl, goat, lib) + lib.goat3d_set_mesh_mtl(mesh, mtl) + break # we only care about one material + + for vert in bmesh.vertices: + v = vert.co + n = vert.normal + lib.goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_VERTEX, v[0], v[1], v[2]) + lib.goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_NORMAL, n[0], n[1], n[2]) + + for face in bmesh.tessfaces: fverts = face.vertices - triangles.append(fverts[0]) - triangles.append(fverts[1]) - triangles.append(fverts[2]) + lib.goat3d_add_mesh_face(mesh, fverts[0], fverts[1], fverts[2]) - print("creating native array of " + str(len(triangles)) + " triangles") - IndexArrayType = c_int * len(triangles) - indices = IndexArrayType(triangles) + lib.goat3d_add_mesh(goat, mesh) return False @@ -93,6 +174,9 @@ lib.goat3d_set_mtl_name.argtypes = [c_void_p, c_char_p] lib.goat3d_set_mtl_name.restype = None + lib.goat3d_set_mtl_attrib1f.argtypes = [c_void_p, c_char_p, c_float] + lib.goat3d_set_mtl_attrib1f.restype = None + lib.goat3d_set_mtl_attrib4f.argtypes = [c_void_p, c_char_p, c_float, c_float, c_float, c_float] lib.goat3d_set_mtl_attrib4f.restype = None @@ -111,11 +195,14 @@ lib.goat3d_set_mesh_mtl.argtypes = [c_void_p, c_void_p] lib.goat3d_set_mesh_mtl.restype = None - lib.goat3d_set_mesh_attribs.argtypes = [c_void_p, c_int, c_void_p, c_int] - lib.goat3d_set_mesh_attribs.restype = None + lib.goat3d_add_mesh_attrib3f.argtypes = [c_void_p, c_int, c_float, c_float, c_float] + lib.goat3d_add_mesh_attrib3f.restype = None - lib.goat3d_set_mesh_faces.argtypes = [c_void_p, c_void_p, c_int] - lib.goat3d_set_mesh_faces.restype = None + lib.goat3d_add_mesh_attrib4f.argtypes = [c_void_p, c_int, c_float, c_float, c_float, c_float] + lib.goat3d_add_mesh_attrib4f.restype = None + + lib.goat3d_add_mesh_face.argtypes = [c_void_p, c_int, c_int, c_int] + lib.goat3d_add_mesh_face.restype = None lib.goat3d_add_node.argtypes = [c_void_p, c_void_p] lib.goat3d_add_node.restype = None diff -r 0e48907847ad -r a5c5cec3cb88 src/goat3d.cc --- a/src/goat3d.cc Wed Oct 09 16:40:59 2013 +0300 +++ b/src/goat3d.cc Sun Oct 13 10:14:19 2013 +0300 @@ -29,8 +29,6 @@ static long write_file(const void *buf, size_t bytes, void *uptr); static long seek_file(long offs, int whence, void *uptr); -static std::string clean_filename(const char *str); - extern "C" { struct goat3d *goat3d_create(void) @@ -228,7 +226,7 @@ void goat3d_set_mtl_attrib_map(struct goat3d_material *mtl, const char *attrib, const char *mapname) { - (*mtl)[attrib].map = clean_filename(mapname); + (*mtl)[attrib].map = goat3d_clean_filename(mapname); } const char *goat3d_get_mtl_attrib_map(struct goat3d_material *mtl, const char *attrib) @@ -333,6 +331,47 @@ } } +void goat3d_add_mesh_attrib1f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float val) +{ + goat3d_add_mesh_attrib4f(mesh, attrib, val, 0, 0, 1); +} + +void goat3d_add_mesh_attrib3f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y, float z) +{ + goat3d_add_mesh_attrib4f(mesh, attrib, x, y, z, 1); +} + +void goat3d_add_mesh_attrib4f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y, float z, float w) +{ + switch(attrib) { + case GOAT3D_MESH_ATTR_VERTEX: + mesh->vertices.push_back(Vector3(x, y, z)); + break; + case GOAT3D_MESH_ATTR_NORMAL: + mesh->normals.push_back(Vector3(x, y, z)); + break; + case GOAT3D_MESH_ATTR_TANGENT: + mesh->tangents.push_back(Vector3(x, y, z)); + break; + case GOAT3D_MESH_ATTR_TEXCOORD: + mesh->texcoords.push_back(Vector2(x, y)); + break; + case GOAT3D_MESH_ATTR_SKIN_WEIGHT: + mesh->skin_weights.push_back(Vector4(x, y, z, w)); + break; + case GOAT3D_MESH_ATTR_SKIN_MATRIX: + mesh->skin_matrices.push_back(Int4(x, y, z, w)); + break; + case GOAT3D_MESH_ATTR_COLOR: + mesh->colors.push_back(Vector4(x, y, z, w)); + default: + break; + } +} + void *goat3d_get_mesh_attribs(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib) { return goat3d_get_mesh_attrib(mesh, attrib, 0); @@ -367,6 +406,15 @@ mesh->faces = VECDATA(Face, data, num); } +void goat3d_add_mesh_face(struct goat3d_mesh *mesh, int a, int b, int c) +{ + Face face; + face.v[0] = a; + face.v[1] = b; + face.v[2] = c; + mesh->faces.push_back(face); +} + int *goat3d_get_mesh_faces(struct goat3d_mesh *mesh) { return goat3d_get_mesh_face(mesh, 0); @@ -738,7 +786,7 @@ return ftell((FILE*)uptr); } -static std::string clean_filename(const char *str) +std::string goat3d_clean_filename(const char *str) { const char *last_slash = strrchr(str, '/'); if(!last_slash) { @@ -755,5 +803,6 @@ char c = *str++; *dest++ = tolower(c); } + *dest = 0; return buf; } diff -r 0e48907847ad -r a5c5cec3cb88 src/goat3d.h --- a/src/goat3d.h Wed Oct 09 16:40:59 2013 +0300 +++ b/src/goat3d.h Sun Oct 13 10:14:19 2013 +0300 @@ -12,6 +12,7 @@ #define GOAT3D_MAT_ATTR_REFLECTION "reflection" #define GOAT3D_MAT_ATTR_TRANSMISSION "transmission" #define GOAT3D_MAT_ATTR_IOR "ior" +#define GOAT3D_MAT_ATTR_ALPHA "alpha" enum goat3d_mesh_attrib { GOAT3D_MESH_ATTR_VERTEX, @@ -136,7 +137,13 @@ * - GOAT3D_MESH_ATTR_SKIN_MATRIX - 4 ints per vertex * - GOAT3D_MESH_ATTR_COLOR - 4 floats per vertex */ -void goat3d_set_mesh_attribs(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, const void *data, int vnum); +void goat3d_set_mesh_attribs(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + const void *data, int vnum); +void goat3d_add_mesh_attrib1f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, float val); +void goat3d_add_mesh_attrib3f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y, float z); +void goat3d_add_mesh_attrib4f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y, float z, float w); /* returns a pointer to the beginning of the requested mesh attribute array */ void *goat3d_get_mesh_attribs(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib); /* returns a pointer to the requested mesh attribute */ @@ -144,6 +151,7 @@ /* sets all the faces in one go. data is an array of 3 int vertex indices per face */ void goat3d_set_mesh_faces(struct goat3d_mesh *mesh, const int *data, int fnum); +void goat3d_add_mesh_face(struct goat3d_mesh *mesh, int a, int b, int c); /* returns a pointer to the beginning of the face index array */ int *goat3d_get_mesh_faces(struct goat3d_mesh *mesh); /* returns a pointer to a face index */ diff -r 0e48907847ad -r a5c5cec3cb88 src/goat3d_impl.h --- a/src/goat3d_impl.h Wed Oct 09 16:40:59 2013 +0300 +++ b/src/goat3d_impl.h Sun Oct 13 10:14:19 2013 +0300 @@ -21,6 +21,8 @@ #define VECDATA(type, data, num) \ MOVE(std::vector((type*)(data), (type*)(data) + (num))) +std::string goat3d_clean_filename(const char *str); + class Scene { private: diff -r 0e48907847ad -r a5c5cec3cb88 src/goat3d_writexml.cc --- a/src/goat3d_writexml.cc Wed Oct 09 16:40:59 2013 +0300 +++ b/src/goat3d_writexml.cc Sun Oct 13 10:14:19 2013 +0300 @@ -80,7 +80,7 @@ if(mesh->material) { xmlout(io, level + 1, "\n", mesh->material->name.c_str()); } - xmlout(io, level + 1, "\n", mesh_filename); + xmlout(io, level + 1, "\n", goat3d_clean_filename(mesh_filename).c_str()); xmlout(io, level, "\n\n"); return true; } diff -r 0e48907847ad -r a5c5cec3cb88 src/mesh.cc --- a/src/mesh.cc Wed Oct 09 16:40:59 2013 +0300 +++ b/src/mesh.cc Sun Oct 13 10:14:19 2013 +0300 @@ -3,6 +3,19 @@ #include "openctm.h" #include "log.h" +Int4::Int4() +{ + x = y = z = w = 0; +} + +Int4::Int4(int x, int y, int z, int w) +{ + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + Mesh::Mesh() { material = 0; diff -r 0e48907847ad -r a5c5cec3cb88 src/mesh.h --- a/src/mesh.h Wed Oct 09 16:40:59 2013 +0300 +++ b/src/mesh.h Sun Oct 13 10:14:19 2013 +0300 @@ -13,6 +13,9 @@ struct Int4 { int x, y, z, w; + + Int4(); + Int4(int x, int y, int z, int w); }; class Mesh : public Object {