Merge remote-tracking branch 'origin/master' into Font-Update

Former-commit-id: ae0244334123a3442c7675df80b1a501a6837257
This commit is contained in:
Lynix 2014-12-17 14:00:20 +01:00
commit 528969d0fa
28 changed files with 652 additions and 64 deletions

View File

@ -191,7 +191,7 @@ end
newaction
{
trigger = "unicode",
trigger = "parseunicode",
description = "Parse the Unicode Character Data and put the useful informations into a header",
execute = parseUnicodeData
}

View File

@ -26,7 +26,7 @@ using NzMusicLoader = NzResourceLoader<NzMusic, NzMusicParams>;
struct NzMusicImpl;
class NAZARA_API NzMusic : public NzSoundEmitter
class NAZARA_API NzMusic : public NzSoundEmitter, NzNonCopyable
{
friend NzMusicLoader;

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
@ -235,7 +236,7 @@ inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, f
float c, m, y;
ToCMY(color, &c, &m, &y);
float k = std::min(std::min(std::min(1.f, c), m), y);
float k = std::min({1.f, c, m, y});
if (NzNumberEquals(k, 1.f))
{
@ -260,8 +261,8 @@ inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturati
float g = color.g / 255.f;
float b = color.b / 255.f;
float min = std::min(std::min(r, g), b); // Min. value of RGB
float max = std::max(std::max(r, g), b); // Max. value of RGB
float min = std::min({r, g, b}); // Min. value of RGB
float max = std::max({r, g, b}); // Max. value of RGB
float deltaMax = max - min; //Delta RGB value

View File

@ -21,32 +21,34 @@ class NzSparsePtr
NzSparsePtr();
NzSparsePtr(T* ptr);
NzSparsePtr(VoidPtr ptr, unsigned int stride);
NzSparsePtr(VoidPtr ptr, int stride);
template<typename U> NzSparsePtr(const NzSparsePtr<U>& ptr);
NzSparsePtr(const NzSparsePtr& ptr) = default;
~NzSparsePtr() = default;
VoidPtr GetPtr() const;
unsigned int GetStride() const;
int GetStride() const;
void Reset();
void Reset(T* ptr);
void Reset(VoidPtr ptr, unsigned int stride);
void Reset(VoidPtr ptr, int stride);
void Reset(const NzSparsePtr& ptr);
template<typename U> void Reset(const NzSparsePtr<U>& ptr);
void SetPtr(VoidPtr ptr);
void SetStride(unsigned int stride);
void SetStride(int stride);
operator bool() const;
operator T*() const;
T& operator*() const;
T& operator->() const;
T& operator[](unsigned int index) const;
T& operator[](int index) const;
NzSparsePtr operator+(unsigned int count) const;
NzSparsePtr operator-(unsigned int count) const;
NzSparsePtr operator+(int count) const;
NzSparsePtr operator-(int count) const;
NzSparsePtr& operator+=(unsigned int count);
NzSparsePtr& operator-=(unsigned int count);
NzSparsePtr& operator+=(int count);
NzSparsePtr& operator-=(int count);
NzSparsePtr& operator++();
NzSparsePtr operator++(int);
@ -65,7 +67,7 @@ class NzSparsePtr
private:
BytePtr m_ptr;
unsigned int m_stride;
int m_stride;
};
#include <Nazara/Core/SparsePtr.inl>

View File

@ -17,11 +17,18 @@ NzSparsePtr<T>::NzSparsePtr(T* ptr)
}
template<typename T>
NzSparsePtr<T>::NzSparsePtr(VoidPtr ptr, unsigned int stride)
NzSparsePtr<T>::NzSparsePtr(VoidPtr ptr, int stride)
{
Reset(ptr, stride);
}
template<typename T>
template<typename U>
NzSparsePtr<T>::NzSparsePtr(const NzSparsePtr<U>& ptr)
{
Reset(ptr);
}
template<typename T>
typename NzSparsePtr<T>::VoidPtr NzSparsePtr<T>::GetPtr() const
{
@ -29,7 +36,7 @@ typename NzSparsePtr<T>::VoidPtr NzSparsePtr<T>::GetPtr() const
}
template<typename T>
unsigned int NzSparsePtr<T>::GetStride() const
int NzSparsePtr<T>::GetStride() const
{
return m_stride;
}
@ -49,7 +56,7 @@ void NzSparsePtr<T>::Reset(T* ptr)
}
template<typename T>
void NzSparsePtr<T>::Reset(VoidPtr ptr, unsigned int stride)
void NzSparsePtr<T>::Reset(VoidPtr ptr, int stride)
{
SetPtr(ptr);
SetStride(stride);
@ -62,6 +69,16 @@ void NzSparsePtr<T>::Reset(const NzSparsePtr& ptr)
SetStride(ptr.GetStride());
}
template<typename T>
template<typename U>
void NzSparsePtr<T>::Reset(const NzSparsePtr<U>& ptr)
{
static_assert(std::is_convertible<U*, T*>::value, "Source type pointer cannot be implicitely converted to target type pointer");
SetPtr(static_cast<T*>(ptr.GetPtr()));
SetStride(ptr.GetStride());
}
template<typename T>
void NzSparsePtr<T>::SetPtr(VoidPtr ptr)
{
@ -69,7 +86,7 @@ void NzSparsePtr<T>::SetPtr(VoidPtr ptr)
}
template<typename T>
void NzSparsePtr<T>::SetStride(unsigned int stride)
void NzSparsePtr<T>::SetStride(int stride)
{
m_stride = stride;
}
@ -99,34 +116,36 @@ T& NzSparsePtr<T>::operator->() const
}
template<typename T>
T& NzSparsePtr<T>::operator[](unsigned int index) const
T& NzSparsePtr<T>::operator[](int index) const
{
return *reinterpret_cast<T*>(m_ptr + index*m_stride);
}
template<typename T>
NzSparsePtr<T> NzSparsePtr<T>::operator+(unsigned int count) const
NzSparsePtr<T> NzSparsePtr<T>::operator+(int count) const
{
return NzSparsePtr(m_ptr + count*m_stride, m_stride);
}
template<typename T>
NzSparsePtr<T> NzSparsePtr<T>::operator-(unsigned int count) const
NzSparsePtr<T> NzSparsePtr<T>::operator-(int count) const
{
return NzSparsePtr(m_ptr - count*m_stride, m_stride);
}
template<typename T>
NzSparsePtr<T>& NzSparsePtr<T>::operator+=(unsigned int count)
NzSparsePtr<T>& NzSparsePtr<T>::operator+=(int count)
{
m_ptr += count*m_stride;
return *this;
}
template<typename T>
NzSparsePtr<T>& NzSparsePtr<T>::operator-=(unsigned int count)
NzSparsePtr<T>& NzSparsePtr<T>::operator-=(int count)
{
m_ptr -= count*m_stride;
return *this;
}
@ -134,6 +153,7 @@ template<typename T>
NzSparsePtr<T>& NzSparsePtr<T>::operator++()
{
m_ptr += m_stride;
return *this;
}

View File

@ -0,0 +1,88 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SKELETALMODEL_HPP
#define NAZARA_SKELETALMODEL_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Core/Updatable.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Utility/Animation.hpp>
#include <Nazara/Utility/Buffer.hpp>
#include <Nazara/Utility/VertexBuffer.hpp>
#include <vector>
struct NAZARA_API NzSkeletalModelParameters : public NzModelParameters
{
bool loadAnimation = true;
NzAnimationParams animation;
bool IsValid() const;
};
class NzSkeletalModel;
using NzSkeletalModelLoader = NzResourceLoader<NzSkeletalModel, NzSkeletalModelParameters>;
class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable
{
friend NzSkeletalModelLoader;
//friend class NzScene;
public:
NzSkeletalModel();
NzSkeletalModel(const NzSkeletalModel& model);
NzSkeletalModel(NzSkeletalModel&& model);
~NzSkeletalModel();
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
void AdvanceAnimation(float elapsedTime);
void EnableAnimation(bool animation);
NzAnimation* GetAnimation() const;
NzSkeleton* GetSkeleton();
const NzSkeleton* GetSkeleton() const;
bool HasAnimation() const;
bool IsAnimated() const;
bool IsAnimationEnabled() const;
bool IsDrawable() const;
bool LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params = NzSkeletalModelParameters());
bool LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params = NzSkeletalModelParameters());
bool LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params = NzSkeletalModelParameters());
void Reset();
bool SetAnimation(NzAnimation* animation);
void SetMesh(NzMesh* mesh) override;
bool SetSequence(const NzString& sequenceName);
void SetSequence(unsigned int sequenceIndex);
NzSkeletalModel& operator=(const NzSkeletalModel& node);
NzSkeletalModel& operator=(NzSkeletalModel&& node);
private:
void Register() override;
void Unregister() override;
void Update() override;
void UpdateBoundingVolume() const;
NzAnimationRef m_animation;
NzSkeleton m_skeleton;
const NzSequence* m_currentSequence;
bool m_animationEnabled;
float m_interpolation;
unsigned int m_currentFrame;
unsigned int m_nextFrame;
static NzSkeletalModelLoader::LoaderList s_loaders;
};
#endif // NAZARA_SKELETALMODEL_HPP

View File

@ -32,6 +32,7 @@ class NAZARA_API NzSprite : public NzSceneNode
void SetMaterial(NzMaterial* material, bool resizeSprite = true);
void SetSize(const NzVector2f& size);
void SetSize(float sizeX, float sizeY);
void SetTexture(NzTexture* texture, bool resizeSprite = true);
void SetTextureCoords(const NzRectf& coords);
void SetTextureRect(const NzRectui& rect);

View File

@ -20,6 +20,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
{
public:
NzView();
NzView(const NzVector2f& size);
~NzView();
void EnsureFrustumUpdate() const;
@ -32,6 +33,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
NzVector3f GetForward() const;
const NzFrustumf& GetFrustum() const;
const NzMatrix4f& GetProjectionMatrix() const;
const NzVector2f& GetSize() const;
const NzRenderTarget* GetTarget() const;
const NzRectf& GetTargetRegion() const;
const NzMatrix4f& GetViewMatrix() const;
@ -39,6 +41,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
float GetZFar() const;
float GetZNear() const;
void SetSize(const NzVector2f& size);
void SetTarget(const NzRenderTarget* renderTarget);
void SetTarget(const NzRenderTarget& renderTarget);
void SetTargetRegion(const NzRectf& region);
@ -63,6 +66,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
mutable NzMatrix4f m_viewMatrix;
NzRectf m_targetRegion;
mutable NzRecti m_viewport;
NzVector2f m_size;
const NzRenderTarget* m_target;
mutable bool m_frustumUpdated;
mutable bool m_projectionMatrixUpdated;

View File

@ -562,9 +562,9 @@ template<typename T>
bool NzMatrix4<T>::IsIdentity() const
{
return (NzNumberEquals(m11, F(1.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(1.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(1.0)) && NzNumberEquals(m14, F(0.0)) &&
NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(1.0)));
NzNumberEquals(m21, F(0.0)) && NzNumberEquals(m22, F(1.0)) && NzNumberEquals(m23, F(0.0)) && NzNumberEquals(m24, F(0.0)) &&
NzNumberEquals(m31, F(0.0)) && NzNumberEquals(m32, F(0.0)) && NzNumberEquals(m33, F(1.0)) && NzNumberEquals(m34, F(0.0)) &&
NzNumberEquals(m41, F(0.0)) && NzNumberEquals(m42, F(0.0)) && NzNumberEquals(m43, F(0.0)) && NzNumberEquals(m44, F(1.0)));
}
template<typename T>

View File

@ -61,7 +61,7 @@ class NAZARA_API NzRenderTarget
private:
mutable std::unordered_map<Listener*, void*> m_listeners;
bool m_listenersLocked;
bool m_listenersLocked;
};
#endif // NAZARA_RENDERTARGET_HPP

View File

@ -32,6 +32,7 @@ NAZARA_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, u
NAZARA_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount);
template<typename T> NzBoxf NzComputeVerticesAABB(const T* vertices, unsigned int vertexCount);
///TODO: Remplacer le pointeur vertices par une structure composée de plusieurs SparsePtr
NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0);
NAZARA_API void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0);
NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0);

View File

@ -50,13 +50,13 @@ class NAZARA_API NzNode
NzNode& Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation, nzCoordSys coordSys = nzCoordSys_Global);
NzNode& Move(const NzVector3f& movement, nzCoordSys coordSys = nzCoordSys_Local);
NzNode& Move(float movementX, float movementY, float movementZ, nzCoordSys coordSys = nzCoordSys_Local);
NzNode& Move(float movementX, float movementY, float movementZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local);
NzNode& Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys = nzCoordSys_Local);
NzNode& Scale(const NzVector3f& scale);
NzNode& Scale(float scale);
NzNode& Scale(float scaleX, float scaleY, float scaleZ);
NzNode& Scale(float scaleX, float scaleY, float scaleZ = 1.f);
void SetInheritRotation(bool inheritRotation);
void SetInheritScale(bool inheritScale);
@ -64,18 +64,18 @@ class NAZARA_API NzNode
void SetInitialRotation(const NzQuaternionf& quat);
void SetInitialScale(const NzVector3f& scale);
void SetInitialScale(float scale);
void SetInitialScale(float scaleX, float scaleY, float scaleZ);
void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f);
void SetInitialPosition(const NzVector3f& translation);
void SetInitialPosition(float translationX, float translationXY, float translationZ);
void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f);
void SetName(const NzString& name);
void SetParent(const NzNode* node = nullptr, bool keepDerived = false);
void SetParent(const NzNode& node, bool keepDerived = false);
void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local);
void SetPosition(float translationX, float translationXY, float translationZ, nzCoordSys coordSys = nzCoordSys_Local);
void SetPosition(float translationX, float translationY, float translationZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local);
void SetRotation(const NzQuaternionf& quat, nzCoordSys coordSys = nzCoordSys_Local);
void SetScale(const NzVector3f& scale, nzCoordSys coordSys = nzCoordSys_Local);
void SetScale(float scale, nzCoordSys coordSys = nzCoordSys_Local);
void SetScale(float scaleX, float scaleY, float scaleZ, nzCoordSys coordSys = nzCoordSys_Local);
void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, nzCoordSys coordSys = nzCoordSys_Local);
void SetTransformMatrix(const NzMatrix4f& matrix);
// Local -> global

View File

@ -116,6 +116,7 @@ nzUInt32 NzMusic::GetPlayingOffset() const
}
#endif
///TODO
return 0;
}
@ -131,6 +132,7 @@ nzSoundStatus NzMusic::GetStatus() const
nzSoundStatus status = GetInternalStatus();
// Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread)
if (m_impl->streaming && status == nzSoundStatus_Stopped)
status = nzSoundStatus_Playing;
@ -180,14 +182,17 @@ void NzMusic::Play()
}
#endif
// Nous sommes déjà en train de jouer
if (m_impl->streaming)
{
// Peut-être sommes-nous en pause
if (GetStatus() != nzSoundStatus_Playing)
alSourcePlay(m_source);
return;
}
// Lancement du thread de streaming
m_impl->stream->Seek(0);
m_impl->streaming = true;
m_impl->thread = NzThread(&NzMusic::MusicThread, this);
@ -195,6 +200,19 @@ void NzMusic::Play()
return;
}
void NzMusic::SetPlayingOffset(nzUInt32 offset)
{
#if NAZARA_AUDIO_SAFE
if (!m_impl)
{
NazaraError("Music not created");
return;
}
#endif
///TODO
}
void NzMusic::Stop()
{
#if NAZARA_AUDIO_SAFE
@ -217,39 +235,44 @@ bool NzMusic::FillAndQueueBuffer(unsigned int buffer)
unsigned int sampleCount = m_impl->chunkSamples.size();
unsigned int sampleRead = 0;
// Lecture depuis le stream pour remplir le buffer
for (;;)
{
sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead);
if (sampleRead < sampleCount && m_impl->loop)
m_impl->stream->Seek(0);
else
break;
if (sampleRead < sampleCount && !m_impl->loop)
break; // Fin du stream (On ne boucle pas)
m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau
}
// Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente
if (sampleRead > 0)
{
alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate);
alSourceQueueBuffers(m_source, 1, &buffer);
}
return sampleRead != sampleCount; // Fin du fichier (N'arrive pas en cas de loop)
return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop)
}
void NzMusic::MusicThread()
{
// Allocation des buffers de streaming
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
{
if (FillAndQueueBuffer(buffers[i])) // Fin du fichier ?
break; // Nous avons atteint la fin du fichier, inutile de rajouter des buffers
if (FillAndQueueBuffer(buffers[i]))
break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers
}
alSourcePlay(m_source);
// Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure)
while (m_impl->streaming)
{
// La lecture s'est arrêtée, nous avons atteint la fin du stream
nzSoundStatus status = GetInternalStatus();
if (status == nzSoundStatus_Stopped)
{
@ -257,6 +280,7 @@ void NzMusic::MusicThread()
break;
}
// On traite les buffers lus
ALint processedCount = 0;
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
@ -268,11 +292,14 @@ void NzMusic::MusicThread()
break;
}
// On retourne dormir un peu
NzThread::Sleep(50);
}
// Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait)
alSourceStop(m_source);
// On supprime les buffers du stream
ALint queuedBufferCount;
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);

View File

@ -10,9 +10,9 @@
NzDeferredBloomPass::NzDeferredBloomPass() :
m_uniformUpdated(false),
m_brightLuminance(0.8),
m_brightMiddleGrey(0.5),
m_brightThreshold(0.8),
m_brightLuminance(0.8f),
m_brightMiddleGrey(0.5f),
m_brightThreshold(0.8f),
m_blurPassCount(5)
{
m_bilinearSampler.SetAnisotropyLevel(1);

View File

@ -228,7 +228,7 @@ bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions)
}
catch (const std::exception& e)
{
NazaraError("Failed to create G-Buffer RTT");
NazaraError("Failed to create G-Buffer RTT: " + NzString(e.what()));
return false;
}
}

View File

@ -421,19 +421,19 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const
NzVector3f center = sprite->GetPosition();
NzQuaternionf rotation = sprite->GetRotation();
vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f);
vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f);
vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height);
vertices++;
vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f);
vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f);
vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height);
vertices++;
vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f);
vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f);
vertices->uv.Set(textureCoords.x, textureCoords.y);
vertices++;
vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f);
vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f);
vertices->uv.Set(textureCoords.width, textureCoords.y);
vertices++;
}

View File

@ -5,6 +5,7 @@
#include <Nazara/Graphics/Loaders/Mesh.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Graphics/SkeletalModel.hpp>
#include <Nazara/Utility/Mesh.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
@ -32,11 +33,71 @@ namespace
}
if (mesh->IsAnimable())
{
NazaraError("Can't load animated mesh into static model");
return false;
}
// Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe
NzMesh* meshPtr = mesh.get();
model->Reset();
model->SetMesh(meshPtr);
mesh.release();
if (parameters.loadMaterials)
{
unsigned int matCount = model->GetMaterialCount();
for (unsigned int i = 0; i < matCount; ++i)
{
NzString mat = meshPtr->GetMaterial(i);
if (!mat.IsEmpty())
{
std::unique_ptr<NzMaterial> material(new NzMaterial);
material->SetPersistent(false);
if (material->LoadFromFile(mat, parameters.material))
{
model->SetMaterial(i, material.get());
material.release();
}
else
NazaraWarning("Failed to load material #" + NzString::Number(i));
}
}
}
return true;
}
nzTernary CheckAnimated(NzInputStream& stream, const NzSkeletalModelParameters& parameters)
{
NazaraUnused(stream);
NazaraUnused(parameters);
return nzTernary_Unknown;
}
bool LoadAnimated(NzSkeletalModel* model, NzInputStream& stream, const NzSkeletalModelParameters& parameters)
{
NazaraUnused(parameters);
std::unique_ptr<NzMesh> mesh(new NzMesh);
mesh->SetPersistent(false);
if (!mesh->LoadFromStream(stream, parameters.mesh))
{
NazaraError("Failed to load model mesh");
return false;
}
if (!mesh->IsAnimable())
{
NazaraError("Can't load static mesh into animated model");
return false;
}
// Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe
NzMesh* meshPtr = mesh.get();
@ -74,9 +135,11 @@ namespace
void NzLoaders_Mesh_Register()
{
NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic);
NzSkeletalModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated);
}
void NzLoaders_Mesh_Unregister()
{
NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic);
NzSkeletalModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated);
}

View File

@ -690,8 +690,8 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const
m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid());
list.SetParameter("TRANSFORM", m_transformEnabled);
list.SetParameter("FLAG_DEFERRED", static_cast<bool>(flags & nzShaderFlags_Deferred));
list.SetParameter("FLAG_INSTANCING", static_cast<bool>(flags & nzShaderFlags_Instancing));
list.SetParameter("FLAG_DEFERRED", static_cast<bool>((flags & nzShaderFlags_Deferred) != 0));
list.SetParameter("FLAG_INSTANCING", static_cast<bool>((flags & nzShaderFlags_Instancing) != 0));
ShaderInstance& instance = m_shaders[flags];
instance.uberInstance = m_uberShader->Get(list);

View File

@ -0,0 +1,357 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/SkeletalModel.hpp>
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
#include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/SkinningManager.hpp>
#include <Nazara/Utility/BufferMapper.hpp>
#include <Nazara/Utility/MeshData.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
bool NzSkeletalModelParameters::IsValid() const
{
if (!NzModelParameters::IsValid())
return false;
if (loadAnimation && !animation.IsValid())
return false;
return true;
}
NzSkeletalModel::NzSkeletalModel() :
m_currentSequence(nullptr),
m_animationEnabled(true)
{
}
NzSkeletalModel::NzSkeletalModel(const NzSkeletalModel& model) :
NzModel(model),
m_skeleton(model.m_skeleton),
m_currentSequence(model.m_currentSequence),
m_animationEnabled(model.m_animationEnabled),
m_interpolation(model.m_interpolation),
m_currentFrame(model.m_currentFrame),
m_nextFrame(model.m_nextFrame)
{
}
NzSkeletalModel::~NzSkeletalModel()
{
Reset();
}
void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
{
const NzMatrix4f& transformMatrix = GetTransformMatrix();
unsigned int submeshCount = m_mesh->GetSubMeshCount();
for (unsigned int i = 0; i < submeshCount; ++i)
{
const NzSkeletalMesh* mesh = static_cast<const NzSkeletalMesh*>(m_mesh->GetSubMesh(i));
const NzMaterial* material = m_materials[mesh->GetMaterialIndex()];
NzMeshData meshData;
meshData.indexBuffer = mesh->GetIndexBuffer();
meshData.primitiveMode = mesh->GetPrimitiveMode();
meshData.vertexBuffer = NzSkinningManager::GetBuffer(mesh, &m_skeleton);
renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), transformMatrix);
}
}
void NzSkeletalModel::AdvanceAnimation(float elapsedTime)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
m_interpolation += m_currentSequence->frameRate * elapsedTime;
while (m_interpolation > 1.f)
{
m_interpolation -= 1.f;
unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1;
if (m_nextFrame+1 > lastFrame)
{
if (m_animation->IsLoopPointInterpolationEnabled())
{
m_currentFrame = m_nextFrame;
m_nextFrame = m_currentSequence->firstFrame;
}
else
{
m_currentFrame = m_currentSequence->firstFrame;
m_nextFrame = m_currentFrame+1;
}
}
else
{
m_currentFrame = m_nextFrame;
m_nextFrame++;
}
}
m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation);
InvalidateBoundingVolume();
}
void NzSkeletalModel::EnableAnimation(bool animation)
{
m_animationEnabled = animation;
}
NzAnimation* NzSkeletalModel::GetAnimation() const
{
return m_animation;
}
NzSkeleton* NzSkeletalModel::GetSkeleton()
{
InvalidateBoundingVolume();
return &m_skeleton;
}
const NzSkeleton* NzSkeletalModel::GetSkeleton() const
{
return &m_skeleton;
}
bool NzSkeletalModel::HasAnimation() const
{
return m_animation != nullptr;
}
bool NzSkeletalModel::IsAnimated() const
{
return true;
}
bool NzSkeletalModel::IsAnimationEnabled() const
{
return m_animationEnabled;
}
bool NzSkeletalModel::IsDrawable() const
{
return m_mesh != nullptr && m_mesh->GetSubMeshCount() >= 1;
}
bool NzSkeletalModel::LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params)
{
return NzSkeletalModelLoader::LoadFromFile(this, filePath, params);
}
bool NzSkeletalModel::LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params)
{
return NzSkeletalModelLoader::LoadFromMemory(this, data, size, params);
}
bool NzSkeletalModel::LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params)
{
return NzSkeletalModelLoader::LoadFromStream(this, stream, params);
}
void NzSkeletalModel::Reset()
{
NzModel::Reset();
m_skeleton.Destroy();
if (m_scene)
m_scene->UnregisterForUpdate(this);
}
bool NzSkeletalModel::SetAnimation(NzAnimation* animation)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_mesh)
{
NazaraError("Model has no mesh");
return false;
}
if (animation)
{
if (!animation->IsValid())
{
NazaraError("Invalid animation");
return false;
}
if (animation->GetType() != m_mesh->GetAnimationType())
{
NazaraError("Animation type must match mesh animation type");
return false;
}
if (animation->GetJointCount() != m_mesh->GetJointCount())
{
NazaraError("Animation joint count must match mesh joint count");
return false;
}
}
#endif
m_animation = animation;
if (m_animation)
{
m_currentFrame = 0;
m_interpolation = 0.f;
SetSequence(0);
if (m_scene)
m_scene->RegisterForUpdate(this);
}
else if (m_scene)
m_scene->UnregisterForUpdate(this);
return true;
}
void NzSkeletalModel::SetMesh(NzMesh* mesh)
{
#if NAZARA_GRAPHICS_SAFE
if (mesh && mesh->GetAnimationType() != nzAnimationType_Skeletal)
{
NazaraError("Mesh animation type must be skeletal");
return;
}
#endif
NzModel::SetMesh(mesh);
if (m_mesh)
{
if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount())
{
NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation...");
SetAnimation(nullptr);
}
m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template
}
}
bool NzSkeletalModel::SetSequence(const NzString& sequenceName)
{
///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log)
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return false;
}
#endif
const NzSequence* currentSequence = m_animation->GetSequence(sequenceName);
if (!currentSequence)
{
NazaraError("Sequence not found");
return false;
}
m_currentSequence = currentSequence;
m_nextFrame = m_currentSequence->firstFrame;
return true;
}
void NzSkeletalModel::SetSequence(unsigned int sequenceIndex)
{
#if NAZARA_GRAPHICS_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
const NzSequence* currentSequence = m_animation->GetSequence(sequenceIndex);
#if NAZARA_GRAPHICS_SAFE
if (!currentSequence)
{
NazaraError("Sequence not found");
return;
}
#endif
m_currentSequence = currentSequence;
m_nextFrame = m_currentSequence->firstFrame;
}
NzSkeletalModel& NzSkeletalModel::operator=(const NzSkeletalModel& node)
{
NzSkeletalModel::operator=(node);
m_animation = node.m_animation;
m_animationEnabled = node.m_animationEnabled;
m_currentFrame = node.m_currentFrame;
m_currentSequence = node.m_currentSequence;
m_interpolation = node.m_interpolation;
m_nextFrame = node.m_nextFrame;
m_skeleton = node.m_skeleton;
return *this;
}
NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node)
{
NzModel::operator=(node);
// Ressources
m_animation = std::move(node.m_animation);
m_skeleton = std::move(node.m_skeleton);
// Paramètres
m_animationEnabled = node.m_animationEnabled;
m_currentFrame = node.m_currentFrame;
m_currentSequence = node.m_currentSequence;
m_interpolation = node.m_interpolation;
m_nextFrame = node.m_nextFrame;
return *this;
}
void NzSkeletalModel::Register()
{
if (m_animation)
m_scene->RegisterForUpdate(this);
}
void NzSkeletalModel::Unregister()
{
m_scene->UnregisterForUpdate(this);
}
void NzSkeletalModel::Update()
{
if (m_animationEnabled && m_animation)
AdvanceAnimation(m_scene->GetUpdateTime());
}
void NzSkeletalModel::UpdateBoundingVolume() const
{
if (m_boundingVolume.IsNull())
m_boundingVolume.Set(m_skeleton.GetAABB());
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();
m_boundingVolume.Update(m_transformMatrix);
m_boundingVolumeUpdated = true;
}
NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders;

View File

@ -109,10 +109,17 @@ void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite)
void NzSprite::SetSize(const NzVector2f& size)
{
m_size = size;
// On invalide la bounding box
m_boundingVolume.MakeNull();
m_boundingVolumeUpdated = false;
}
void NzSprite::SetSize(float sizeX, float sizeY)
{
SetSize(NzVector2f(sizeX, sizeY));
}
void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite)
{
std::unique_ptr<NzMaterial> material(new NzMaterial);

View File

@ -10,6 +10,7 @@
NzView::NzView() :
m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_size(0.f),
m_target(nullptr),
m_frustumUpdated(false),
m_projectionMatrixUpdated(false),
@ -20,6 +21,12 @@ m_zNear(-1.f)
{
}
NzView::NzView(const NzVector2f& size) :
NzView() // On délègue
{
m_size = size;
}
NzView::~NzView()
{
if (m_target)
@ -256,10 +263,16 @@ void NzView::UpdateFrustum() const
void NzView::UpdateProjectionMatrix() const
{
if (!m_viewportUpdated)
UpdateViewport();
if (m_size.x <= 0.f || m_size.y <= 0.f) // Si la taille est nulle, on prendra la taille du viewport
{
if (!m_viewportUpdated)
UpdateViewport();
m_projectionMatrix.MakeOrtho(0.f, m_viewport.width, 0.f, m_viewport.height, m_zNear, m_zFar);
}
else
m_projectionMatrix.MakeOrtho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar);
m_projectionMatrix.MakeOrtho(m_viewport.x, m_viewport.x + m_viewport.width, m_viewport.y, m_viewport.y + m_viewport.height, m_zNear, m_zFar);
m_projectionMatrixUpdated = true;
}

View File

@ -320,4 +320,3 @@ void NzRenderWindow::OnWindowResized()
{
NotifySizeChange();
}

View File

@ -1856,7 +1856,7 @@ bool NzRenderer::EnsureStateUpdate()
default:
{
NazaraInternalError("Unsupported component type");
NazaraInternalError("Unsupported component type (0x" + NzString::Number(type, 16) + ')');
break;
}
}

View File

@ -11,12 +11,16 @@
#include <Nazara/Utility/Debug.hpp>
///TODO: Rajouter des warnings (Formats compressés avec les méthodes Copy/Update, tests taille dans Copy)
///TODO: Rendre les méthodes exception-safe
///TODO: Rendre les méthodes exception-safe (Virer toute cette merde de calcul de pointeurs, faire usage du RAII)
///FIXME: Gérer correctement les formats utilisant moins d'un octet par pixel
namespace
{
inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level)
{
if (size == 0) // Possible dans le cas d'une image invalide
return 0;
return std::max(size >> level, 1U);
}
@ -28,7 +32,7 @@ namespace
bool NzImageParams::IsValid() const
{
return true;
return true; // Rien à vérifier
}
NzImage::NzImage() :
@ -195,7 +199,7 @@ void NzImage::Copy(const NzImage& source, const NzBoxui& srcBox, const NzVector3
bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount)
{
ReleaseImage();
Destroy();
#if NAZARA_UTILITY_SAFE
if (!NzPixelFormat::IsValid(format))

View File

@ -5,6 +5,7 @@
#include <Nazara/Utility/VideoMode.hpp>
#include <Nazara/Utility/VideoModeImpl.hpp>
#include <algorithm>
#include <functional>
#include <Nazara/Utility/Debug.hpp>
NzVideoMode::NzVideoMode() :

View File

@ -222,7 +222,7 @@ NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo)
}
else
{
NazaraError("Window's handle is invalid");
NazaraError("Invalid window handle");
// Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test
return NzVector2i(-1, -1);
@ -289,5 +289,5 @@ void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo)
SetCursorPos(pos.x, pos.y);
}
else
NazaraError("Window's handle is invalid");
NazaraError("Invalid window handle");
}

View File

@ -79,7 +79,7 @@ m_scrolling(0)
{
}
bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 style)
bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style)
{
bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0;
DWORD win32Style, win32StyleEx;
@ -183,7 +183,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl
GetWindowRect(m_handle, &windowRect);
m_position.Set(windowRect.left, windowRect.top);
m_size.Set(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top);
m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
return true;
}

View File

@ -34,7 +34,7 @@ class NzWindowImpl : NzNonCopyable
NzWindowImpl(NzWindow* parent);
~NzWindowImpl() = default;
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style);
bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style);
bool Create(NzWindowHandle handle);
void Destroy();