nuclear@19: #include "goat3d_impl.h" nuclear@1: #include "mesh.h" nuclear@19: #include "openctm.h" nuclear@19: #include "log.h" nuclear@1: nuclear@47: using namespace g3dimpl; nuclear@47: nuclear@40: Int4::Int4() nuclear@40: { nuclear@40: x = y = z = w = 0; nuclear@40: } nuclear@40: nuclear@40: Int4::Int4(int x, int y, int z, int w) nuclear@40: { nuclear@40: this->x = x; nuclear@40: this->y = y; nuclear@40: this->z = z; nuclear@40: this->w = w; nuclear@40: } nuclear@40: nuclear@1: Mesh::Mesh() nuclear@1: { nuclear@8: material = 0; nuclear@1: } nuclear@1: nuclear@19: bool Mesh::load(const char *fname) nuclear@19: { nuclear@19: CTMcontext ctm = ctmNewContext(CTM_IMPORT); nuclear@19: nuclear@19: ctmLoad(ctm, fname); nuclear@19: if(ctmGetError(ctm) != CTM_NONE) { nuclear@19: logmsg(LOG_ERROR, "failed to load ctm mesh: %s\n", fname); nuclear@19: ctmFreeContext(ctm); nuclear@19: return false; nuclear@19: } nuclear@19: nuclear@19: int vnum = ctmGetInteger(ctm, CTM_VERTEX_COUNT); nuclear@19: int fnum = ctmGetInteger(ctm, CTM_TRIANGLE_COUNT); nuclear@19: nuclear@19: const CTMfloat *vertices = ctmGetFloatArray(ctm, CTM_VERTICES); nuclear@19: if(!vertices) { nuclear@19: logmsg(LOG_ERROR, "failed to load ctm mesh: %s: no vertices found!\n", fname); nuclear@19: ctmFreeContext(ctm); nuclear@19: return false; nuclear@19: } nuclear@19: nuclear@19: const CTMuint *indices = ctmGetIntegerArray(ctm, CTM_INDICES); nuclear@19: if(!indices) { nuclear@19: logmsg(LOG_ERROR, "failed to load ctm mesh: %s: no faces found!\n", fname); nuclear@19: ctmFreeContext(ctm); nuclear@19: return false; nuclear@19: } nuclear@19: nuclear@19: const CTMfloat *normals = ctmGetFloatArray(ctm, CTM_NORMALS); nuclear@19: const CTMfloat *texcoords = ctmGetFloatArray(ctm, CTM_UV_MAP_1); nuclear@19: nuclear@19: CTMenum tangent_id = ctmGetNamedAttribMap(ctm, "tangent"); nuclear@19: const CTMfloat *tangents = tangent_id ? ctmGetFloatArray(ctm, tangent_id) : 0; nuclear@19: nuclear@19: CTMenum skinweight_id = ctmGetNamedAttribMap(ctm, "skin_weight"); nuclear@19: const CTMfloat *skinweights = skinweight_id ? ctmGetFloatArray(ctm, skinweight_id) : 0; nuclear@19: nuclear@19: CTMenum skinmat_id = ctmGetNamedAttribMap(ctm, "skin_matrix"); nuclear@19: const CTMuint *skinmats = skinmat_id ? ctmGetIntegerArray(ctm, skinmat_id) : 0; nuclear@19: nuclear@19: CTMenum color_id = ctmGetNamedAttribMap(ctm, "color"); nuclear@19: const CTMfloat *colors = color_id ? ctmGetFloatArray(ctm, color_id) : 0; nuclear@19: nuclear@19: // now put everything we found into our vectors nuclear@19: this->vertices = VECDATA(Vector3, vertices, vnum); nuclear@19: nuclear@19: if(texcoords) { nuclear@19: this->texcoords = VECDATA(Vector2, texcoords, vnum); nuclear@19: } nuclear@19: if(normals) { nuclear@19: this->normals = VECDATA(Vector3, normals, vnum); nuclear@19: } nuclear@19: if(skinweights) { nuclear@19: this->skin_weights = VECDATA(Vector4, skinweights, vnum); nuclear@19: } nuclear@19: if(colors) { nuclear@19: this->colors = VECDATA(Vector4, colors, vnum); nuclear@19: } nuclear@19: nuclear@19: // the rest need converting nuclear@19: if(tangents) { nuclear@19: this->tangents.clear(); nuclear@19: this->tangents.resize(vnum); nuclear@19: nuclear@19: for(int i=0; itangents[i][j] = tangents[j]; nuclear@19: } nuclear@19: tangents += 4; nuclear@19: } nuclear@19: } nuclear@19: if(skinmats) { nuclear@19: this->skin_matrices.clear(); nuclear@19: this->skin_matrices.resize(vnum); nuclear@19: nuclear@19: for(int i=0; iskin_matrices[i].x = skinmats[0]; nuclear@19: this->skin_matrices[i].y = skinmats[1]; nuclear@19: this->skin_matrices[i].z = skinmats[2]; nuclear@19: this->skin_matrices[i].w = skinmats[3]; nuclear@19: } nuclear@19: } nuclear@19: nuclear@19: // grab the face data nuclear@19: this->faces.clear(); nuclear@19: this->faces.resize(fnum); nuclear@19: nuclear@19: for(int i=0; ifaces[i].v[j] = indices[j]; nuclear@19: } nuclear@19: indices += 3; nuclear@19: } nuclear@19: nuclear@19: nuclear@19: ctmFreeContext(ctm); nuclear@19: return true; nuclear@19: } nuclear@19: nuclear@19: bool Mesh::save(const char *fname) const nuclear@19: { nuclear@19: int vnum = (int)vertices.size(); nuclear@30: int fnum = (int)faces.size(); nuclear@30: nuclear@30: if(!vnum || !fnum) { nuclear@30: return false; nuclear@30: } nuclear@19: nuclear@19: CTMcontext ctm = ctmNewContext(CTM_EXPORT); nuclear@19: nuclear@19: // vertices, normals, and face-vertex indices nuclear@30: ctmDefineMesh(ctm, &vertices[0].x, vnum, (CTMuint*)faces[0].v, fnum, nuclear@19: normals.empty() ? 0 : &normals[0].x); nuclear@19: nuclear@19: // texture coordinates nuclear@19: if(!texcoords.empty()) { nuclear@19: ctmAddUVMap(ctm, &texcoords[0].x, "texcoord", 0); nuclear@19: } nuclear@19: nuclear@19: // vertex colors nuclear@19: if(!colors.empty()) { nuclear@19: ctmAddAttribMap(ctm, &colors[0].x, "color"); nuclear@19: } nuclear@19: nuclear@19: // skin weights nuclear@19: if(!skin_weights.empty()) { nuclear@19: ctmAddAttribMap(ctm, &skin_weights[0].x, "skin_weight"); nuclear@19: } nuclear@19: nuclear@19: // if either of the non-float4 attributes are present we need to make a tmp array nuclear@19: CTMfloat *attr_array = 0; nuclear@19: if(!tangents.empty() || !skin_matrices.empty()) { nuclear@19: attr_array = new CTMfloat[vnum * 4 * sizeof *attr_array]; nuclear@19: } nuclear@19: nuclear@19: // tangents nuclear@19: if(!tangents.empty()) { nuclear@19: CTMfloat *ptr = attr_array; nuclear@19: nuclear@19: for(int i=0; i