예제 #1
0
	bool MD5AnimParser::Parse()
	{
		while (Advance(false))
		{
			switch (m_currentLine[0])
			{
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				case 'M': // MD5Version
					if (m_currentLine.GetWord(0) != "MD5Version")
						UnrecognizedLine();
					break;
				#endif

				case 'b': // baseframe/bounds
					if (m_currentLine.StartsWith("baseframe {"))
					{
						if (!ParseBaseframe())
						{
							Error("Failed to parse baseframe");
							return false;
						}
					}
					else if (m_currentLine.StartsWith("bounds {"))
					{
						if (!ParseBounds())
						{
							Error("Failed to parse bounds");
							return false;
						}
					}
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
					break;

				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				case 'c': // commandline
					if (m_currentLine.GetWord(0) != "commandline")
						UnrecognizedLine();
					break;
				#endif

				case 'f':
				{
					unsigned int index;
					if (std::sscanf(&m_currentLine[0], "frame %u {", &index) == 1)
					{
						if (m_frameIndex != index)
						{
							Error("Unexpected frame index (expected " + String::Number(m_frameIndex) + ", got " + String::Number(index) + ')');
							return false;
						}

						if (!ParseFrame())
						{
							Error("Failed to parse frame");
							return false;
						}

						m_frameIndex++;
					}
					else if (std::sscanf(&m_currentLine[0], "frameRate %u", &m_frameRate) != 1)
					{
						#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
						UnrecognizedLine();
						#endif
					}
					break;
				}

				case 'h': // hierarchy
					if (m_currentLine.StartsWith("hierarchy {"))
					{
						if (!ParseHierarchy())
						{
							Error("Failed to parse hierarchy");
							return false;
						}
					}
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
					break;

				case 'n': // num[Frames/Joints]
				{
					unsigned int count;
					if (std::sscanf(&m_currentLine[0], "numAnimatedComponents %u", &count) == 1)
					{
						#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
						if (!m_animatedComponents.empty())
							Warning("Animated components count is already defined");
						#endif

						m_animatedComponents.resize(count);
					}
					else if (std::sscanf(&m_currentLine[0], "numFrames %u", &count) == 1)
					{
						#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
						if (!m_frames.empty())
							Warning("Frame count is already defined");
						#endif

						m_frames.resize(count);
					}
					else if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1)
					{
						#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
						if (!m_joints.empty())
							Warning("Joint count is already defined");
						#endif

						m_joints.resize(count);
					}
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
					break;
				}

				default:
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
			}
		}

		unsigned int frameCount = m_frames.size();
		if (frameCount == 0)
		{
			NazaraError("Frame count is invalid or missing");
			return false;
		}

		unsigned int jointCount = m_joints.size();
		if (jointCount == 0)
		{
			NazaraError("Joint count is invalid or missing");
			return false;
		}

		if (m_frameIndex != frameCount)
		{
			NazaraError("Missing frame infos: [" + String::Number(m_frameIndex) + ',' + String::Number(frameCount) + ']');
			return false;
		}

		if (m_frameRate == 0)
		{
			NazaraWarning("Framerate is either invalid or missing, assuming a default value of 24");
			m_frameRate = 24;
		}

		return true;
	}
예제 #2
0
bool NzMD5AnimParser::Parse(NzAnimation* animation)
{
	while (Advance(false))
	{
		switch (m_currentLine[0])
		{
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			case 'M': // MD5Version
				if (m_currentLine.GetWord(0) != "MD5Version")
					UnrecognizedLine();
				break;
			#endif

			case 'b': // baseframe/bounds
				if (m_currentLine.StartsWith("baseframe {"))
				{
					if (!ParseBaseframe())
					{
						Error("Failed to parse baseframe");
						return false;
					}
				}
				else if (m_currentLine.StartsWith("bounds {"))
				{
					if (!ParseBounds())
					{
						Error("Failed to parse bounds");
						return false;
					}
				}
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				else
					UnrecognizedLine();
				#endif
				break;

			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			case 'c': // commandline
				if (m_currentLine.GetWord(0) != "commandline")
					UnrecognizedLine();
				break;
			#endif

			case 'f':
			{
				unsigned int index;
				if (std::sscanf(&m_currentLine[0], "frame %u {", &index) == 1)
				{
					if (m_frameIndex != index)
					{
						Error("Unexpected frame index (expected " + NzString::Number(m_frameIndex) + ", got " + NzString::Number(index) + ')');
						return false;
					}

					if (!ParseFrame())
					{
						Error("Failed to parse frame");
						return false;
					}

					m_frameIndex++;
				}
				else if (std::sscanf(&m_currentLine[0], "frameRate %u", &m_frameRate) != 1)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
				}
				break;
			}

			case 'h': // hierarchy
				if (m_currentLine.StartsWith("hierarchy {"))
				{
					if (!ParseHierarchy())
					{
						Error("Failed to parse hierarchy");
						return false;
					}
				}
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				else
					UnrecognizedLine();
				#endif
				break;

			case 'n': // num[Frames/Joints]
			{
				unsigned int count;
				if (std::sscanf(&m_currentLine[0], "numAnimatedComponents %u", &count) == 1)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					if (!m_animatedComponents.empty())
						Warning("Animated components count is already defined");
					#endif

					m_animatedComponents.resize(count);
				}
				else if (std::sscanf(&m_currentLine[0], "numFrames %u", &count) == 1)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					if (!m_frames.empty())
						Warning("Frame count is already defined");
					#endif

					m_frames.resize(count);
				}
				else if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					if (!m_joints.empty())
						Warning("Joint count is already defined");
					#endif

					m_joints.resize(count);
				}
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				else
					UnrecognizedLine();
				#endif
				break;
			}

			default:
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				UnrecognizedLine();
				#endif
				break;
		}
	}

	unsigned int frameCount = m_frames.size();
	if (frameCount == 0)
	{
		NazaraError("Frame count is invalid or missing");
		return false;
	}

	unsigned int jointCount = m_joints.size();
	if (jointCount == 0)
	{
		NazaraError("Joint count is invalid or missing");
		return false;
	}

	if (m_frameIndex != frameCount)
	{
		NazaraError("Missing frame infos: [" + NzString::Number(m_frameIndex) + ',' + NzString::Number(frameCount) + ']');
		return false;
	}

	if (m_frameRate == 0)
	{
		NazaraWarning("Framerate is either invalid or missing, assuming a default value of 24");
		m_frameRate = 24;
	}

	// À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation
	if (!animation->CreateSkeletal(frameCount, jointCount))
	{
		NazaraError("Failed to create animation");
		return false;
	}

	NzSequence sequence;
	sequence.firstFrame = 0;
	sequence.frameCount = m_frames.size();
	sequence.frameRate = m_frameRate;
	sequence.name = m_stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
	if (!animation->AddSequence(sequence))
		NazaraWarning("Failed to add sequence");

	NzSequenceJoint* sequenceJoints = animation->GetSequenceJoints();

	// Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette
	NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f);
	for (unsigned int i = 0; i < jointCount; ++i)
	{
		int parent = m_joints[i].parent;
		for (unsigned int j = 0; j < frameCount; ++j)
		{
			NzSequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i];

			if (parent >= 0)
			{
				sequenceJoint.position = m_frames[j].joints[i].pos;
				sequenceJoint.rotation = m_frames[j].joints[i].orient;
			}
			else
			{
				sequenceJoint.position = rotationQuat * m_frames[j].joints[i].pos;
				sequenceJoint.rotation = rotationQuat * m_frames[j].joints[i].orient;
			}

			sequenceJoint.scale = NzVector3f(1.f, 1.f, 1.f);
		}
	}

	return true;
}