예제 #1
0
void NzVoxelChunkMesh::SetLocation(const NzVector3i& location)
{
    m_location = location;
    m_transformationMatrix.MakeTranslation(NzVector3f(static_cast<float>(location.x * NAZARA_VOXELENGINE_CHUNKSIZE_X),
                                                      static_cast<float>(location.y * NAZARA_VOXELENGINE_CHUNKSIZE_Y),
                                                      static_cast<float>(location.z * NAZARA_VOXELENGINE_CHUNKSIZE_Z)));
}
예제 #2
0
NzVector3f NzAudio::GetListenerDirection()
{
	ALfloat orientation[6];
	alGetListenerfv(AL_ORIENTATION, orientation);

	return NzVector3f(orientation[0], orientation[1], orientation[2]);
}
예제 #3
0
void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset)
{
	// Pour plus de facilité, on va construire notre plan en considérant que la normale est de 0,1,0
	// Et appliquer ensuite une matrice "finissant le travail"

	// Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...)
	unsigned int horizontalFaceCount = (1 << subdivision.x);
	unsigned int verticalFaceCount = (1 << subdivision.y);

	// Et le nombre de sommets est ce nombre ajouté de 1 (2,3,5,9,17,33,...)
	unsigned int horizontalVertexCount = horizontalFaceCount + 1;
	unsigned int verticalVertexCount = verticalFaceCount + 1;

	NzVector3f normal(NzVector3f::UnitY());
	normal = matrix.Transform(normal, 0.f);
	normal.Normalize();

	NzVector3f tangent(1.f, 1.f, 0.f);
	tangent = matrix.Transform(tangent, 0.f);
	tangent.Normalize();

	float halfSizeX = size.x / 2.f;
	float halfSizeY = size.y / 2.f;

	float invHorizontalVertexCount = 1.f/(horizontalVertexCount-1);
	float invVerticalVertexCount = 1.f/(verticalVertexCount-1);
	for (unsigned int x = 0; x < horizontalVertexCount; ++x)
	{
		for (unsigned int y = 0; y < verticalVertexCount; ++y)
		{
			NzVector3f localPos((2.f*x*invHorizontalVertexCount - 1.f) * halfSizeX, 0.f, (2.f*y*invVerticalVertexCount - 1.f) * halfSizeY);
			vertices->position = matrix * localPos;
			vertices->uv.Set(textureCoords.x + x*invHorizontalVertexCount*textureCoords.width, textureCoords.y + y*invVerticalVertexCount*textureCoords.height);
			vertices->normal = normal;
			vertices->tangent = tangent;
			vertices++;

			if (x != horizontalVertexCount-1 && y != verticalVertexCount-1)
			{
				*indices++ = (x+0)*verticalVertexCount + y + 0 + indexOffset;
				*indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset;
				*indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset;

				*indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset;
				*indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset;
				*indices++ = (x+1)*verticalVertexCount + y + 1 + indexOffset;
			}
		}
	}

	if (aabb)
		aabb->Set(matrix.Transform(NzVector3f(-halfSizeX, 0.f, -halfSizeY), 0.f), matrix.Transform(NzVector3f(halfSizeX, 0.f, halfSizeY), 0.f));
}
예제 #4
0
void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset)
{
	constexpr float round = 2.f*static_cast<float>(M_PI);
	float delta = round/subdivision;

	vertices->position = matrix.GetTranslation(); // matrix.Transform(NzVector3f(0.f));
	vertices->normal = matrix.Transform(NzVector3f::Up(), 0.f);
	vertices++;

	for (unsigned int i = 0; i < subdivision; ++i)
	{
		float angle = delta*i;
		vertices->position = matrix.Transform(NzVector3f(radius*std::sin(angle), -length, radius*std::cos(angle)));
		vertices++;

		*indices++ = indexOffset + 0;
		*indices++ = indexOffset + i+1;
		*indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1);

		if (i != 0 && i != subdivision-1)
		{
			*indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1);
			*indices++ = indexOffset + i+1;
			*indices++ = indexOffset + 1;
		}
	}

	if (aabb)
	{
		aabb->MakeZero();

		// On calcule le reste des points
		NzVector3f base(NzVector3f::Down()*length);

		NzVector3f lExtend = NzVector3f::Left()*radius;
		NzVector3f fExtend = NzVector3f::Forward()*radius;

		// Et on ajoute ensuite les quatres extrémités de la pyramide
		aabb->ExtendTo(base + lExtend + fExtend);
		aabb->ExtendTo(base + lExtend - fExtend);
		aabb->ExtendTo(base - lExtend + fExtend);
		aabb->ExtendTo(base - lExtend - fExtend);
		aabb->Transform(matrix, false);
	}
}
예제 #5
0
void NzSkyboxBackground::Draw(const NzScene* scene) const
{
	static NzRenderStates states(BuildRenderStates());

	NzAbstractViewer* viewer = scene->GetViewer();

	NzMatrix4f skyboxMatrix(viewer->GetViewMatrix());
	skyboxMatrix.SetTranslation(NzVector3f::Zero());

	NzRenderer::SetIndexBuffer(m_indexBuffer);
	NzRenderer::SetMatrix(nzMatrixType_View, skyboxMatrix);
	NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Scale(NzVector3f(viewer->GetZNear())));
	NzRenderer::SetRenderStates(states);
	NzRenderer::SetShader(m_shader);
	NzRenderer::SetTexture(0, m_texture);
	NzRenderer::SetTextureSampler(0, m_sampler);
	NzRenderer::SetVertexBuffer(m_vertexBuffer);

	NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, 36);

	NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix());
}
예제 #6
0
void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset)
{
	unsigned int vertexCount;
	NzComputeBoxIndexVertexCount(NzVector3ui(subdivision), nullptr, &vertexCount);

	// On envoie une matrice identité de sorte à ce que la boîte ne subisse aucune transformation (rendant plus facile l'étape suivante)
	NzGenerateBox(NzVector3f(size, size, size), NzVector3ui(subdivision), NzMatrix4f::Identity(), textureCoords, vertices, indices, nullptr, indexOffset);

	if (aabb)
	{
		NzVector3f totalSize = size * matrix.GetScale();
		aabb->Set(-totalSize, totalSize);
	}

	for (unsigned int i = 0; i < vertexCount; ++i)
	{
		vertices->position = matrix.Transform(size * vertices->position.GetNormal());
		vertices->normal = vertices->position.GetNormal();
		//vertices->tangent = ???
		vertices++;
	}
}
예제 #7
0
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
#include <Nazara/Utility/Debug.hpp>

const nzUInt32 md2Ident = 'I' + ('D'<<8) + ('P'<<16) + ('2'<<24);

const NzVector3f md2Normals[162] =
{
	NzVector3f(-0.525731f, 0.000000f, 0.850651f),
	NzVector3f(-0.442863f, 0.238856f, 0.864188f),
	NzVector3f(-0.295242f, 0.000000f, 0.955423f),
	NzVector3f(-0.309017f, 0.500000f, 0.809017f),
	NzVector3f(-0.162460f, 0.262866f, 0.951056f),
	NzVector3f(0.000000f, 0.000000f, 1.000000f),
	NzVector3f(0.000000f, 0.850651f, 0.525731f),
	NzVector3f(-0.147621f, 0.716567f, 0.681718f),
	NzVector3f(0.147621f, 0.716567f, 0.681718f),
	NzVector3f(0.000000f, 0.525731f, 0.850651f),
	NzVector3f(0.309017f, 0.500000f, 0.809017f),
	NzVector3f(0.525731f, 0.000000f, 0.850651f),
	NzVector3f(0.295242f, 0.000000f, 0.955423f),
	NzVector3f(0.442863f, 0.238856f, 0.864188f),
	NzVector3f(0.162460f, 0.262866f, 0.951056f),
	NzVector3f(-0.681718f, 0.147621f, 0.716567f),
	NzVector3f(-0.809017f, 0.309017f, 0.500000f),
	NzVector3f(-0.587785f, 0.425325f, 0.688191f),
	NzVector3f(-0.850651f, 0.525731f, 0.000000f),
	NzVector3f(-0.864188f, 0.442863f, 0.238856f),
예제 #8
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;
}