//----------------------------------------------------------------------- void PixelUtil::packColour(const uint8 r, const uint8 g, const uint8 b, const uint8 a, const PixelFormat pf, void* dest) { const PixelFormatDescription &des = getDescriptionFor(pf); if(des.flags & PFF_NATIVEENDIAN) { // Shortcut for integer formats packing unsigned int value = ((Bitwise::fixedToFixed(r, 8, des.rbits)<<des.rshift) & des.rmask) | ((Bitwise::fixedToFixed(g, 8, des.gbits)<<des.gshift) & des.gmask) | ((Bitwise::fixedToFixed(b, 8, des.bbits)<<des.bshift) & des.bmask) | ((Bitwise::fixedToFixed(a, 8, des.abits)<<des.ashift) & des.amask); // And write to memory Bitwise::intWrite(dest, des.elemBytes, value); } else { // Convert to float packColour((float)r/255.0f,(float)g/255.0f,(float)b/255.0f,(float)a/255.0f, pf, dest); } }
/************************************************************************* * Pixel packing/unpacking utilities */ void PixelUtil::packColour(const ColourValue &colour, const PixelFormat pf, void* dest) { packColour(colour.r, colour.g, colour.b, colour.a, pf, dest); }
void akMeshLoader::convert(bool sortByMat, bool openglVertexColor) { Blender::MFace* mface = m_bmesh->mface; Blender::MVert* mvert = m_bmesh->mvert; Blender::MCol* mcol = 0; Blender::MTFace* mtface[8] = {0, 0, 0, 0, 0, 0, 0, 0}; if (!mface || !mvert) return; Blender::MVert vpak[4]; unsigned int cpak[4]; unsigned int ipak[4]; int totlayer; akSubMesh* curSubMesh = 0; utArray<akSubMeshPair*> meshtable; utArray<utString> vgroups; utArray<utString> shapekeys; utArray<btAlignedObjectArray<akVector3> > shapekeysnormals; utArray<utArray<UTuint32> > smoothfacesarray; akMeshLoaderUtils_getLayers(m_bmesh, mtface, &mcol, totlayer); akMeshLoaderUtils_getVertexGroups(m_bmesh, m_bobj, vgroups); akMeshLoaderUtils_getShapeKeys(m_bmesh, shapekeys); if(shapekeys.size()>0) { akMeshLoaderUtils_getShapeKeysNormals(m_bmesh, shapekeys.size(), shapekeysnormals); akMeshLoaderUtils_getSmoothFaces(m_bmesh, smoothfacesarray); } for (int fi = 0; fi < m_bmesh->totface; fi++) { const Blender::MFace& curface = mface[fi]; // skip if face is not a triangle || quad if (!curface.v3) continue; const bool isQuad = curface.v4 != 0; TempFace t[2]; PackedFace f; f.totlay = totlayer; if (isQuad) { vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; vpak[3] = mvert[curface.v4]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; ipak[3] = curface.v4; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); cpak[3] = packColour(mcol[3], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { VEC2CPY(f.uvLayers[i][0], mtface[i][fi].uv[0]); VEC2CPY(f.uvLayers[i][1], mtface[i][fi].uv[1]); VEC2CPY(f.uvLayers[i][2], mtface[i][fi].uv[2]); VEC2CPY(f.uvLayers[i][3], mtface[i][fi].uv[3]); } } f.verts = vpak; f.index = ipak; f.colors = cpak; akVector3 e0, e1; akVector3 v0,v1,v2,v3; VEC3CPY(v0, mvert[curface.v1].co); VEC3CPY(v1, mvert[curface.v2].co); VEC3CPY(v2, mvert[curface.v3].co); VEC3CPY(v3, mvert[curface.v4].co); e0 = v0 - v2; e1 = v1 - v3; if (lengthSqr(e0) <lengthSqr(e1)) { convertIndexedTriangle(&t[0], 0, 1, 2, f); convertIndexedTriangle(&t[1], 2, 3, 0, f); } else { convertIndexedTriangle(&t[0], 0, 1, 3, f); convertIndexedTriangle(&t[1], 3, 1, 2, f); } } else { for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { VEC2CPY(f.uvLayers[i][0], mtface[i][fi].uv[0]); VEC2CPY(f.uvLayers[i][1], mtface[i][fi].uv[1]); VEC2CPY(f.uvLayers[i][2], mtface[i][fi].uv[2]); } } vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; f.verts = vpak; f.index = ipak; f.colors = cpak; convertIndexedTriangle(&t[0], 0, 1, 2, f); } akSubMeshHashKey test; if (sortByMat) { int mode = 0; if (mtface[0]) mode = mtface[0][fi].mode; test = akSubMeshHashKey(curface.mat_nr, mode); } else { Blender::Image* ima[8] = {0, 0, 0, 0, 0, 0, 0, 0}; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) ima[i] = mtface[i][fi].tpage; } int mode = 0, alpha = 0; if (mtface[0]) { mode = mtface[0][fi].mode; alpha = mtface[0][fi].transp; } test = akSubMeshHashKey(mode, alpha, ima); } // find submesh UTsize arpos = 0; akSubMeshPair* curSubMeshPair = 0; for(arpos=0; arpos<meshtable.size(); arpos++) { if(meshtable[arpos]->test == test) break; } if (arpos >= meshtable.size()) { curSubMesh = new akSubMesh(akSubMesh::ME_TRIANGLES, true, true, totlayer); m_gmesh->addSubMesh(curSubMesh); curSubMeshPair = new akSubMeshPair(curSubMesh, m_bmesh, &smoothfacesarray, &shapekeysnormals); curSubMeshPair->test = test; for(int i=0; i<vgroups.size(); i++) { akVertexGroup* vg = new akVertexGroup(); vg->setName(vgroups[i]); curSubMesh->addVertexGroup(vg); } for(int i=0; i<shapekeys.size(); i++) { akMorphTarget* mt = new akMorphTarget(true); mt->setName(shapekeys[i]); curSubMesh->addMorphTarget(mt); } meshtable.push_back(curSubMeshPair); } else { curSubMeshPair = meshtable.at(arpos); curSubMesh = curSubMeshPair->item; } if (curSubMesh == 0 || curSubMeshPair == 0) continue; if (!(curface.flag & ME_SMOOTH)) { // face normal calcNormal(&t[0]); if (isQuad) { calcNormal(&t[1]); akVector3 n = normalize(t[0].v0.no + t[1].v0.no); t[0].v0.no = t[0].v1.no = t[0].v2.no = t[1].v0.no = t[1].v1.no = t[1].v2.no = n; } } addTriangle(curSubMeshPair, fi, t[0].v0, t[0].i0, t[0].v1, t[0].i1, t[0].v2, t[0].i2); if (isQuad) { addTriangle(curSubMeshPair, fi, t[1].v0, t[1].i0, t[1].v1, t[1].i1, t[1].v2, t[1].i2); } if (mcol) mcol += 4; } utArrayIterator<utArray<akSubMeshPair*> > iter(meshtable); while (iter.hasMoreElements()) { akSubMeshPair* subpair = iter.peekNext(); if(subpair->test.m_blenderMat) { Blender::Material* bmat = akMeshLoaderUtils_getMaterial(m_bobj, subpair->test.m_matnr); if (bmat) convertMaterial(bmat, subpair); } else convertTextureFace(subpair); delete subpair; iter.getNext(); } meshtable.clear(); for(int i=0; i<vgroups.size(); i++) { vgroups[i].clear(); } vgroups.clear(); for(int i=0; i<shapekeys.size(); i++) { shapekeys[i].clear(); } shapekeys.clear(); for(int i=0; i<smoothfacesarray.size(); i++) { smoothfacesarray[i].clear(); } smoothfacesarray.clear(); for(int i=0; i<shapekeysnormals.size(); i++) { shapekeysnormals[i].clear(); } shapekeysnormals.clear(); }
void gkBlenderMeshConverter::convert(void) { Blender::MFace* mface = m_bmesh->mface; Blender::MVert* mvert = m_bmesh->mvert; Blender::MCol* mcol = 0; Blender::MTFace* mtface[8] = {0, 0, 0, 0, 0, 0, 0, 0}; if (!mface || !mvert) return; Blender::MVert vpak[4]; unsigned int cpak[4]; unsigned int ipak[4]; int totlayer; gkSubMesh* curSubMesh = 0; utArray<gkMeshPair> meshtable; gkLoaderUtils_getLayers(m_bmesh, mtface, &mcol, totlayer); bool sortByMat = gkEngine::getSingleton().getUserDefs().blendermat; bool openglVertexColor = gkEngine::getSingleton().getUserDefs().rendersystem == OGRE_RS_GL; AssignmentListMap assignMap; bool canAssign = m_bmesh->dvert && m_bobj->parent && m_bobj->parent->type == OB_ARMATURE; if (canAssign) { int dgi = 0; for (Blender::bDeformGroup* dg = (Blender::bDeformGroup*)m_bobj->defbase.first; dg; dg = dg->next, ++dgi) { m_gmesh->createVertexGroup(dg->name); convertBoneAssignments(dgi, assignMap); } } for (int fi = 0; fi < m_bmesh->totface; fi++) { const Blender::MFace& curface = mface[fi]; // skip if face is not a triangle || quad if (!curface.v3) continue; const bool isQuad = curface.v4 != 0; TempFace t[2]; PackedFace f; f.totlay = totlayer; if (isQuad) { vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; vpak[3] = mvert[curface.v4]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; ipak[3] = curface.v4; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); cpak[3] = packColour(mcol[3], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { f.uvLayers[i][0] = gkVector2((float*)mtface[i][fi].uv[0]); f.uvLayers[i][1] = gkVector2((float*)mtface[i][fi].uv[1]); f.uvLayers[i][2] = gkVector2((float*)mtface[i][fi].uv[2]); f.uvLayers[i][3] = gkVector2((float*)mtface[i][fi].uv[3]); } } f.verts = vpak; f.index = ipak; f.colors = cpak; gkVector3 e0, e1; e0 = (gkVector3(mvert[curface.v1].co) - gkVector3(mvert[curface.v2].co)); e1 = (gkVector3(mvert[curface.v3].co) - gkVector3(mvert[curface.v4].co)); if (e0.squaredLength() < e1.squaredLength()) { convertIndexedTriangle(&t[0], 0, 1, 2, f); convertIndexedTriangle(&t[1], 2, 3, 0, f); } else { convertIndexedTriangle(&t[0], 0, 1, 3, f); convertIndexedTriangle(&t[1], 3, 1, 2, f); } } else { for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { f.uvLayers[i][0] = gkVector2((float*)mtface[i][fi].uv[0]); f.uvLayers[i][1] = gkVector2((float*)mtface[i][fi].uv[1]); f.uvLayers[i][2] = gkVector2((float*)mtface[i][fi].uv[2]); } } vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; f.verts = vpak; f.index = ipak; f.colors = cpak; convertIndexedTriangle(&t[0], 0, 1, 2, f); } gkMeshPair tester(curSubMesh); if (sortByMat) { int mode = 0; if (mtface[0]) mode = mtface[0][fi].mode; tester.test = gkMeshHashKey(curface.mat_nr, mode); } else { Blender::Image* ima[8] = {0, 0, 0, 0, 0, 0, 0, 0}; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) ima[i] = mtface[i][fi].tpage; } int mode = 0, alpha = 0; if (mtface[0]) { mode = mtface[0][fi].mode; alpha = mtface[0][fi].transp; } tester.test = gkMeshHashKey(mode, alpha, ima); } // find submesh UTsize arpos = 0; if ((arpos = meshtable.find(tester)) == UT_NPOS) { curSubMesh = new gkSubMesh(); curSubMesh->setTotalLayers(totlayer); curSubMesh->setVertexColors(mcol != 0); m_gmesh->addSubMesh(curSubMesh); tester.item = curSubMesh; meshtable.push_back(tester); } else curSubMesh = meshtable.at(arpos).item; if (curSubMesh == 0) continue; if (!(curface.flag & ME_SMOOTH)) { // face normal calcNormal(&t[0]); if (isQuad) t[1].v0.no = t[1].v1.no = t[1].v2.no = t[0].v0.no; } int triflag = 0; if (mtface[0]) { if (mtface[0][fi].mode & TF_DYNAMIC) triflag |= gkTriangle::TRI_COLLIDER; if (mtface[0][fi].mode & TF_INVISIBLE) triflag |= gkTriangle::TRI_INVISIBLE; } else triflag = gkTriangle::TRI_COLLIDER; curSubMesh->addTriangle(t[0].v0, t[0].i0, t[0].v1, t[0].i1, t[0].v2, t[0].i2, triflag); if (isQuad) { curSubMesh->addTriangle(t[1].v0, t[1].i0, t[1].v1, t[1].i1, t[1].v2, t[1].i2, triflag); } if (mcol) mcol += 4; } // build materials utArrayIterator<utArray<gkMeshPair> > iter(meshtable); while (iter.hasMoreElements()) { gkMeshHashKey& key = iter.peekNext().test; gkSubMesh* val = iter.peekNext().item; Blender::Material* bmat = BlenderMaterial(m_bobj, key.m_matnr); if (key.m_blenderMat) { if (bmat) convertMaterial(bmat, val->getMaterial(), key); } else convertTextureFace(val->getMaterial(), key, (Blender::Image**)key.m_images); if (canAssign) { // build def groups assignBoneAssignments(val, assignMap); } iter.getNext(); } }