void MeshParser::gotSkinWeightsToken(std::string& _str) { //std::cout << "got skin weights keyword" << std::endl; //output << "got skin weights keyword" << std::endl; std::string numSkinWeightsToken = getNextToken(); if(atoi(numSkinWeightsToken.c_str()) != mesh.vertices.size()){ std::cout << "ERROR: num normals must be equal to num positions. Num normals is " << numSkinWeightsToken << " num positions is " << mesh.vertices.size() << std::endl; //output << "ERROR: num normals must be equal to num positions. Num normals is " << numSkinWeightsToken << " num positions is " << model.vertices.size() << std::endl; } openCurly(); std::string numAttachmentsToken; int numAttachments; int index; float weight; for(int i = 0; i < mesh.vertices.size(); i++){ numAttachmentsToken = getNextToken(); numAttachments = atoi(numAttachmentsToken.c_str()); //std::cout << "num attachments " << numAttachments << std::endl; //output << "num attachments " << numAttachments << std::endl; for(int j = 0; j < numAttachments; j++){ index = atoi(getNextToken().c_str()); //std::cout << "got index " << index << std::endl; //output << "got index " << index << std::endl; weight = atof(getNextToken().c_str()); //std::cout << "got weight " << weight << std::endl; //output << "got weight " << weight << std::endl; JointWeight jointWeight = JointWeight(index, weight); mesh.vertices[i].weights.push_back(jointWeight); } checkSkinWeights(mesh.vertices[i].weights); } closeCurly(); }
bool LLModel::loadModel(std::istream& is) { mSculptLevel = -1; // default is an error occured LLSD header; { if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024)) { LL_WARNS() << "Mesh header parse error. Not a valid mesh asset!" << LL_ENDL; return false; } } if (header.has("material_list")) { //load material list names mMaterialList.clear(); for (U32 i = 0; i < (U32)header["material_list"].size(); ++i) { mMaterialList.push_back(header["material_list"][i].asString()); } } mSubmodelID = header.has("submodel_id") ? header["submodel_id"].asInteger() : false; static const std::array<std::string, 5> lod_name = {{ "lowest_lod", "low_lod", "medium_lod", "high_lod", "physics_mesh", }}; const S32 MODEL_LODS = lod_name.size(); S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS); if (header[lod_name[lod]]["offset"].asInteger() == -1 || header[lod_name[lod]]["size"].asInteger() == 0 ) { //cannot load requested LOD LL_WARNS() << "LoD data is invalid!" << LL_ENDL; return false; } bool has_skin = header["skin"]["offset"].asInteger() >=0 && header["skin"]["size"].asInteger() > 0; if ((lod == LLModel::LOD_HIGH) && !mSubmodelID) { //try to load skin info and decomp info std::ios::pos_type cur_pos = is.tellg(); loadSkinInfo(header, is); is.seekg(cur_pos); } if ((lod == LLModel::LOD_HIGH || lod == LLModel::LOD_PHYSICS) && !mSubmodelID) { std::ios::pos_type cur_pos = is.tellg(); loadDecomposition(header, is); is.seekg(cur_pos); } is.seekg(header[lod_name[lod]]["offset"].asInteger(), std::ios_base::cur); if (unpackVolumeFaces(is, header[lod_name[lod]]["size"].asInteger())) { if (has_skin) { //build out mSkinWeight from face info for (S32 i = 0; i < getNumVolumeFaces(); ++i) { const LLVolumeFace& face = getVolumeFace(i); if (face.mWeights) { for (S32 j = 0; j < face.mNumVertices; ++j) { LLVector4a& w = face.mWeights[j]; std::vector<JointWeight> wght; for (S32 k = 0; k < 4; ++k) { S32 idx = (S32) w[k]; F32 f = w[k] - idx; if (f > 0.f) { wght.push_back(JointWeight(idx, f)); } } if (!wght.empty()) { LLVector3 pos(face.mPositions[j].getF32ptr()); mSkinWeights[pos] = wght; } } } } } return true; } else { LL_WARNS() << "unpackVolumeFaces failed!" << LL_ENDL; } return false; }