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))); }
NzVector3f NzAudio::GetListenerDirection() { ALfloat orientation[6]; alGetListenerfv(AL_ORIENTATION, orientation); return NzVector3f(orientation[0], orientation[1], orientation[2]); }
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)); }
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); } }
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()); }
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++; } }
// 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),
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; }