コード例 #1
0
ファイル: SdfParser.cpp プロジェクト: sehoonha/dart
//==============================================================================
dynamics::SkeletonPtr readSkeleton(
    const common::Uri& fileUri,
    const common::ResourceRetrieverPtr& nullOrRetriever)
{
  const auto retriever = getRetriever(nullOrRetriever);

  //--------------------------------------------------------------------------
  // Load xml and create Document
  tinyxml2::XMLDocument _dartFile;
  try
  {
    openXMLFile(_dartFile, fileUri, retriever);
  }
  catch(std::exception const& e)
  {
    dtwarn << "[SdfParser::readSkeleton] Loading file [" << fileUri.toString()
           << "] failed: " << e.what() << "\n";
    return nullptr;
  }

  //--------------------------------------------------------------------------
  // Load sdf
  tinyxml2::XMLElement* sdfElement = nullptr;
  sdfElement = _dartFile.FirstChildElement("sdf");
  if (sdfElement == nullptr)
    return nullptr;

  //--------------------------------------------------------------------------
  // version attribute
  std::string version = getAttributeString(sdfElement, "version");
  // TODO: We need version aware SDF parser (see #264)
  // We support 1.4 only for now.
  if (version != "1.4" && version != "1.5")
  {
    dtwarn << "[SdfParser::readSdfFile] The file format of ["
           << fileUri.toString() << "] was found to be [" << version
           << "], but we only support SDF 1.4 and 1.5!\n";
    return nullptr;
  }
  //--------------------------------------------------------------------------
  // Load skeleton
  tinyxml2::XMLElement* skelElement = nullptr;
  skelElement = sdfElement->FirstChildElement("model");
  if (skelElement == nullptr)
    return nullptr;

  std::string fileName = fileUri.getFilesystemPath();  // Uri's path is unix-style path
  std::string skelPath = fileName.substr(0, fileName.rfind("/") + 1);

  dynamics::SkeletonPtr newSkeleton = readSkeleton(skelElement, skelPath,
                                                   retriever);

  return newSkeleton;
}
コード例 #2
0
ファイル: geometry.cpp プロジェクト: auuhja/Game
static void readSkeleton(const aiNode* node, std::map<std::string, bone_idx>& boneNames, std::vector<bone_info>& boneInfos, bone_idx parentID)
{
	mat4 nodeTransform = readMatrix(node->mTransformation);

	std::string nodeName = node->mName.C_Str();

	bone_idx boneID = NO_PARENT;
	
	if (boneNames.find(nodeName) != boneNames.end()) {
		boneID = boneNames[nodeName];
		bone_info& info = boneInfos[boneID];
		info.jointMatrix = nodeTransform;
		info.parentID = parentID;
	}

	for (uint32 i = 0; i < node->mNumChildren; i++) {
		readSkeleton(node->mChildren[i], boneNames, boneInfos, boneID);
	}
}
コード例 #3
0
ファイル: geometry.cpp プロジェクト: auuhja/Game
void processMesh(std::string filename)
{
	Assimp::Importer Importer;
	const aiScene* scene = Importer.ReadFile(filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals 
		| aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality);

	if (!scene) {
		std::cout << "File " << filename << " not found." << std::endl;
		return;
	}

	for (uint32 meshID = 0; meshID < scene->mNumMeshes; ++meshID)
	{
		const aiMesh* mesh = scene->mMeshes[meshID];

		mesh_header meshHeader = { 0 };
		meshHeader.magicNumber = MESH_MAGIC_NUMBER;

		skeleton_header skelHeader = { 0 };
		skelHeader.magicNumber = SKELETON_MAGIC_NUMBER;

		std::vector<vec3> positions;
		std::vector<vec2> texCoords;
		std::vector<vec3> normals;
		std::vector<vertex_weight> weights;
		std::vector<uint16> indices;

		positions.reserve(mesh->mNumVertices);
		texCoords.reserve(mesh->mNumVertices);
		normals.reserve(mesh->mNumVertices);
		weights.reserve(mesh->mNumVertices);
		indices.reserve(mesh->mNumFaces);

		meshHeader.vertexCount = mesh->mNumVertices;
		meshHeader.indexCount = mesh->mNumFaces * 3;

		for (uint32 i = 0; i < mesh->mNumVertices; i++) {

			if (mesh->HasPositions()) 
			{
				meshHeader.hasPositions = true;
				const aiVector3D& pos = mesh->mVertices[i];
				positions.push_back(vec3(pos.x, pos.y, pos.z));
			}

			if (mesh->HasNormals())
			{
				meshHeader.hasNormals = true;
				const aiVector3D& nor = mesh->mNormals[i];
				normals.push_back(vec3(nor.x, nor.y, nor.z));
			}
			
			if (mesh->HasTextureCoords(0))
			{
				meshHeader.hasTexCoords = true;
				const aiVector3D& tex = mesh->mTextureCoords[0][i];
				texCoords.push_back(vec2(tex.x, tex.y));
			}
		}

		for (uint32 i = 0; i < mesh->mNumFaces; i++) {
			const aiFace &face = mesh->mFaces[i];
			assert(face.mNumIndices == 3);
			indices.push_back((uint16)face.mIndices[0]);
			indices.push_back((uint16)face.mIndices[1]);
			indices.push_back((uint16)face.mIndices[2]);
		}

		if (mesh->HasBones())
		{
			meshHeader.hasSkeleton = true;

			vertex_weight defaultWeight = { 0 };
			weights.resize(mesh->mNumVertices, defaultWeight);

			std::map<std::string, bone_idx> boneNames;
			std::vector<bone_info> boneInfos;

			uint32 numberOfBones = mesh->mNumBones;
			for (bone_idx boneID = 0; boneID < (bone_idx)numberOfBones; ++boneID)
			{
				const aiBone* bone = mesh->mBones[boneID];
				std::string boneName = bone->mName.C_Str();

				boneNames[boneName] = boneID;
				bone_info boneInfo;
				boneInfo.invBindMatrix = readMatrix(bone->mOffsetMatrix);
				boneInfo.name = boneName;
				boneInfos.push_back(boneInfo);

				for (uint32 weightID = 0; weightID < bone->mNumWeights; ++weightID)
				{
					uint32 vertexID = bone->mWeights[weightID].mVertexId;
					float weight = bone->mWeights[weightID].mWeight;

					vertex_weight& vWeight = weights[vertexID];
					// search first unused
					for (uint32 i = 0; i < 4; ++i)
					{
						if (vWeight.weights[i] == 0.f)
						{
							vWeight.joints[i] = boneID;
							vWeight.weights[i] = weight;
							break;
						}
					}
				}
			}

			// normalize weights -> sum up to 1
			for (vertex_weight& vWeight : weights)
			{
				vec4 tmp(vWeight.weights[0], vWeight.weights[1], vWeight.weights[2], vWeight.weights[3]);
				normalize(tmp);
				vWeight.weights[0] = tmp.x; vWeight.weights[1] = tmp.y; vWeight.weights[2] = tmp.z; vWeight.weights[3] = tmp.w;
			}

			readSkeleton(scene->mRootNode, boneNames, boneInfos, NO_PARENT);
			skelHeader.jointCount = (bone_idx)boneInfos.size();

			
			if (scene->HasAnimations())
			{
				for (uint32 animationID = 0; animationID < scene->mNumAnimations; ++animationID)
				{
					std::vector<anim_channel> animChannels;

					const aiAnimation* animation = scene->mAnimations[animationID];
					float ticksPerSecond = (float)animation->mTicksPerSecond;
					float normalizingFactor = (ticksPerSecond == 0.f) ? 1.f : 1.f / ticksPerSecond;

					bone_idx numberOfAnimatedBones = animation->mNumChannels;

					for (bone_idx channelID = 0; channelID < numberOfAnimatedBones; ++channelID)
					{
						const aiNodeAnim* channel = animation->mChannels[channelID];
						std::string boneName = channel->mNodeName.C_Str();

						if (boneNames.find(boneName) != boneNames.end()) {
							bone_idx boneID = boneNames[boneName];
							
							anim_channel animChannel;
							animChannel.boneID = boneID;

							// for now
							assert(channel->mNumPositionKeys == channel->mNumRotationKeys && channel->mNumPositionKeys == channel->mNumScalingKeys);

							for (uint32 keyID = 0; keyID < channel->mNumPositionKeys; ++keyID)
							{
								key_frame keyframe;
								keyframe.time = (float)channel->mPositionKeys[keyID].mTime * normalizingFactor;
								keyframe.sqt.position = readVector(channel->mPositionKeys[keyID]);
								keyframe.sqt.rotation = readQuaternion(channel->mRotationKeys[keyID]);
								keyframe.sqt.scale = readVector(channel->mScalingKeys[keyID]).x;
								animChannel.keyframes.push_back(keyframe);
							}

							animChannels.push_back(animChannel);
						}
					}

					animation_header animHeader;
					animHeader.magicNumber = ANIMATION_MAGIC_NUMBER;
					animHeader.jointCount = (bone_idx)animChannels.size();
					animHeader.length = (float)animation->mDuration * normalizingFactor;
					animHeader.looping = true;
					animHeader.skeleton = 0;

					std::sort(animChannels.begin(), animChannels.end(), [](const anim_channel& a, const anim_channel& b)
					{
						return a.boneID < b.boneID;
					});

					// output animations
					std::string animationFileName;
					if (animation->mName.length == 0)
					{
						animationFileName = std::string("../Game/assets/animations/") + getFileName(filename) + ".anim";
					}
					else
					{
						animationFileName = std::string("../Game/assets/animations/") + getAnimationFileName(animation->mName.C_Str()) + ".anim";
					}

					outputAnimation(animationFileName, animHeader, animChannels);
				}
			}

			std::string skeletonFileName = std::string("../Game/assets/skeletons/") + getFileName(filename) + ".skeleton";
			outputSkeleton(skeletonFileName, skelHeader, boneInfos);
		}

		std::string meshFileName = std::string("../Game/assets/models/") + getFileName(filename) + ".mesh";
		outputMesh(meshFileName, meshHeader, positions, texCoords, normals, weights, indices);
	}

	
}