示例#1
0
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();

}
示例#2
0
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;

}