Merge remote-tracking branch 'origin/3D-Engine'
Former-commit-id: 1781615fc780accbe6c11d55fd896038d97ffec9
This commit is contained in:
commit
0a2e19fa22
|
|
@ -0,0 +1,41 @@
|
|||
if (not _OPTIONS["united"]) then
|
||||
project "Nazara3D"
|
||||
end
|
||||
|
||||
files
|
||||
{
|
||||
"../include/Nazara/3D/**.hpp",
|
||||
"../include/Nazara/3D/**.inl",
|
||||
"../src/Nazara/3D/**.hpp",
|
||||
"../src/Nazara/3D/**.cpp"
|
||||
}
|
||||
|
||||
if (os.is("windows")) then
|
||||
excludes { "../src/Nazara/3D/Posix/*.hpp", "../src/Nazara/3D/Posix/*.cpp" }
|
||||
else
|
||||
excludes { "../src/Nazara/3D/Win32/*.hpp", "../src/Nazara/3D/Win32/*.cpp" }
|
||||
end
|
||||
|
||||
if (_OPTIONS["united"]) then
|
||||
excludes "../src/Nazara/3D/Debug/Leaks.cpp"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraCore-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
links "NazaraRenderer-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraCore-s"
|
||||
links "NazaraUtility-s"
|
||||
links "NazaraRenderer-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraCore-d"
|
||||
links "NazaraUtility-d"
|
||||
links "NazaraRenderer-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraCore"
|
||||
links "NazaraUtility"
|
||||
links "NazaraRenderer"
|
||||
end
|
||||
|
|
@ -16,21 +16,25 @@ if (_OPTIONS["united"]) then
|
|||
links "NazaraEngine"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "Nazara3D-s-d"
|
||||
links "NazaraRenderer-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
links "NazaraCore-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "Nazara3D-s"
|
||||
links "NazaraRenderer-s"
|
||||
links "NazaraUtility-s"
|
||||
links "NazaraCore-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "Nazara3D-d"
|
||||
links "NazaraRenderer-d"
|
||||
links "NazaraUtility-d"
|
||||
links "NazaraCore-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "Nazara3D"
|
||||
links "NazaraRenderer"
|
||||
links "NazaraUtility"
|
||||
links "NazaraCore"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - 3D Module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_3D_HPP
|
||||
#define NAZARA_3D_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Initializer.hpp>
|
||||
|
||||
class Nz3D
|
||||
{
|
||||
public:
|
||||
Nz3D() = delete;
|
||||
~Nz3D() = delete;
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
static bool IsInitialized();
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
static unsigned int s_moduleReferenceCounter;
|
||||
};
|
||||
|
||||
#endif // NAZARA_3D_HPP
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Nazara Engine - 3D module
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_3D_HPP
|
||||
#define NAZARA_CONFIG_3D_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#define NAZARA_3D_MEMORYLEAKTRACKER 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_3D_SAFE 1
|
||||
|
||||
#endif // NAZARA_CONFIG_3D_HPP
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - 3D Module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/3D/Config.hpp>
|
||||
#if NAZARA_3D_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
||||
|
||||
#define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete
|
||||
#define new new(__FILE__, __LINE__)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - 3D Module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#if NAZARA_3D_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#undef delete
|
||||
#undef new
|
||||
#endif
|
||||
|
|
@ -50,7 +50,7 @@ class NAZARA_API NzResource
|
|||
void RemoveResourceListener(NzResourceListener* listener) const;
|
||||
void RemoveResourceReference() const;
|
||||
|
||||
void SetPersistent(bool persistent = true);
|
||||
void SetPersistent(bool persistent = true, bool checkReferenceCount = true);
|
||||
|
||||
protected:
|
||||
void NotifyCreated();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzSt
|
|||
NzFile file(path, NzFile::ReadOnly);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
NazaraError("Failed to open \"" + path + '"');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +42,8 @@ bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzSt
|
|||
int cmp = NzString::Compare(loaderExt, ext);
|
||||
if (cmp == 0)
|
||||
{
|
||||
file.SetCursorPos(0);
|
||||
|
||||
if (!std::get<1>(*loader)(file, parameters))
|
||||
continue;
|
||||
|
||||
|
|
@ -52,8 +54,6 @@ bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzSt
|
|||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
|
||||
file.SetCursorPos(0);
|
||||
}
|
||||
else if (cmp < 0) // S'il est encore possible que l'extension se situe après
|
||||
continue;
|
||||
|
|
@ -95,11 +95,13 @@ bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputS
|
|||
nzUInt64 streamPos = stream.GetCursorPos();
|
||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||
{
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Le loader supporte-t-il les données ?
|
||||
if (!std::get<1>(*loader)(stream, parameters))
|
||||
continue;
|
||||
|
||||
// On repositionne le stream au début
|
||||
// On repositionne le stream à son ancienne position
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Chargement de la ressource
|
||||
|
|
@ -107,7 +109,6 @@ bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputS
|
|||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
stream.SetCursorPos(streamPos); // On repositionne au début
|
||||
}
|
||||
|
||||
NazaraError("Failed to load file: no loader");
|
||||
|
|
|
|||
|
|
@ -590,9 +590,9 @@ NzMatrix4<T>& NzMatrix4<T>::MakeZero()
|
|||
|
||||
template<typename T>
|
||||
NzMatrix4<T>& NzMatrix4<T>::Set(T r11, T r12, T r13, T r14,
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44)
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44)
|
||||
{
|
||||
m11 = r11;
|
||||
m12 = r12;
|
||||
|
|
@ -626,9 +626,7 @@ NzMatrix4<T>& NzMatrix4<T>::Set(const T matrix[16])
|
|||
template<typename T>
|
||||
NzMatrix4<T>& NzMatrix4<T>::Set(const NzMatrix4& matrix)
|
||||
{
|
||||
NazaraError("Check 1");
|
||||
std::memcpy(&m11, &matrix.m11, 16*sizeof(T));
|
||||
NazaraError("Check 2");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MATERIAL_HPP
|
||||
#define NAZARA_MATERIAL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
|
||||
struct NAZARA_API NzMaterialParams
|
||||
{
|
||||
bool loadDiffuseMap = true;
|
||||
bool loadSpecularMap = true;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzMaterial;
|
||||
|
||||
using NzMaterialLoader = NzResourceLoader<NzMaterial, NzMaterialParams>;
|
||||
|
||||
class NAZARA_API NzMaterial : public NzResource
|
||||
{
|
||||
friend NzMaterialLoader;
|
||||
|
||||
public:
|
||||
NzMaterial();
|
||||
~NzMaterial();
|
||||
|
||||
void EnableAlphaBlending(bool alphaBlending);
|
||||
void EnableZTest(bool zTest);
|
||||
void EnableZWrite(bool zWrite);
|
||||
|
||||
NzColor GetAmbientColor() const;
|
||||
NzColor GetDiffuseColor() const;
|
||||
const NzTexture* GetDiffuseMap() const;
|
||||
nzBlendFunc GetDstAlpha() const;
|
||||
nzFaceCulling GetFaceCulling() const;
|
||||
nzFaceFilling GetFaceFilling() const;
|
||||
float GetShininess() const;
|
||||
NzColor GetSpecularColor() const;
|
||||
const NzTexture* GetSpecularMap() const;
|
||||
nzBlendFunc GetSrcAlpha() const;
|
||||
nzRendererComparison GetZTestCompare() const;
|
||||
|
||||
bool IsAlphaBlendingEnabled() const;
|
||||
bool IsZTestEnabled() const;
|
||||
bool IsZWriteEnabled() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams());
|
||||
|
||||
void Reset();
|
||||
|
||||
void SetAmbientColor(const NzColor& ambient);
|
||||
void SetDiffuseColor(const NzColor& diffuse);
|
||||
void SetDiffuseMap(const NzTexture* map);
|
||||
void SetDstAlpha(nzBlendFunc func);
|
||||
void SetFaceCulling(nzFaceCulling culling);
|
||||
void SetFaceFilling(nzFaceFilling filling);
|
||||
void SetShininess(float shininess);
|
||||
void SetSpecularColor(const NzColor& specular);
|
||||
void SetSpecularMap(const NzTexture* map);
|
||||
void SetSrcAlpha(nzBlendFunc func);
|
||||
void SetZTestCompare(nzRendererComparison compareFunc);
|
||||
|
||||
static const NzMaterial* GetDefault();
|
||||
|
||||
private:
|
||||
nzBlendFunc m_dstAlpha;
|
||||
nzBlendFunc m_srcAlpha;
|
||||
nzFaceCulling m_faceCulling;
|
||||
nzFaceFilling m_faceFilling;
|
||||
nzRendererComparison m_zTestCompareFunc;
|
||||
NzColor m_ambientColor;
|
||||
NzColor m_diffuseColor;
|
||||
NzColor m_specularColor;
|
||||
const NzTexture* m_diffuseMap;
|
||||
const NzTexture* m_specularMap;
|
||||
bool m_alphaBlendingEnabled;
|
||||
bool m_zTestEnabled;
|
||||
bool m_zWriteEnabled;
|
||||
float m_shininess;
|
||||
|
||||
static NzMaterialLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_MATERIAL_HPP
|
||||
|
|
@ -33,7 +33,7 @@ class NAZARA_API NzKeyframeMesh final : public NzSubMesh
|
|||
bool GetVertex(NzMeshVertex* dest, unsigned int frameIndex, unsigned int vertexIndex, bool queryUV = true) const;
|
||||
const NzVertexBuffer* GetVertexBuffer() const override;
|
||||
|
||||
void Interpolate(unsigned int frameA, unsigned int frameB, float interpolation) const;
|
||||
void Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const;
|
||||
|
||||
bool IsAnimated() const override;
|
||||
bool IsValid();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/AxisAlignedBox.hpp>
|
||||
#include <Nazara/Utility/Skeleton.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
|
|
@ -23,13 +22,13 @@ struct NAZARA_API NzMeshParams
|
|||
{
|
||||
NzMeshParams(); // Vérifie que le storage indiqué un peu plus bas est supporté
|
||||
|
||||
NzAnimationParams animation;
|
||||
nzBufferStorage storage = nzBufferStorage_Hardware;
|
||||
bool animated = true;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzAnimation;
|
||||
class NzMesh;
|
||||
|
||||
typedef NzVertexStruct_XYZ_Normal_UV_Tangent NzMeshVertex;
|
||||
|
|
@ -46,11 +45,10 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
NzMesh() = default;
|
||||
~NzMesh();
|
||||
|
||||
bool AddMaterial(const NzString& matPath, unsigned int* matIndex = nullptr);
|
||||
bool AddSubMesh(NzSubMesh* subMesh);
|
||||
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
|
||||
|
||||
void Animate(unsigned int frameA, unsigned int frameB, float interpolation) const;
|
||||
void Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const;
|
||||
|
||||
bool CreateKeyframe();
|
||||
bool CreateSkeletal(unsigned int jointCount);
|
||||
|
|
@ -58,9 +56,8 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
void Destroy();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
const NzAnimation* GetAnimation() const;
|
||||
NzString GetAnimation() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
unsigned int GetJointCount() const;
|
||||
NzString GetMaterial(unsigned int index) const;
|
||||
unsigned int GetMaterialCount() const;
|
||||
|
|
@ -74,8 +71,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
int GetSubMeshIndex(const NzString& identifier) const;
|
||||
unsigned int GetVertexCount() const;
|
||||
|
||||
bool HasAnimation() const;
|
||||
bool HasMaterial(unsigned int index) const;
|
||||
bool HasSubMesh(const NzString& identifier) const;
|
||||
bool HasSubMesh(unsigned int index = 0) const;
|
||||
|
||||
|
|
@ -88,18 +83,18 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams());
|
||||
|
||||
void RemoveMaterial(unsigned int index);
|
||||
void RemoveSubMesh(const NzString& identifier);
|
||||
void RemoveSubMesh(unsigned int index);
|
||||
|
||||
bool SetAnimation(const NzAnimation* animation);
|
||||
void SetAnimation(const NzString& animationPath);
|
||||
void SetMaterial(unsigned int matIndex, const NzString& materialPath);
|
||||
void SetMaterialCount(unsigned int matCount);
|
||||
|
||||
void Skin(const NzSkeleton* skeleton) const;
|
||||
|
||||
static const NzVertexDeclaration* GetDeclaration();
|
||||
|
||||
private:
|
||||
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
NzMeshImpl* m_impl = nullptr;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class NAZARA_API NzNode
|
|||
NzQuaternionf GetRotation() const;
|
||||
NzVector3f GetScale() const;
|
||||
NzVector3f GetTranslation() const;
|
||||
NzMatrix4f GetTransformMatrix() const;
|
||||
const NzMatrix4f& GetTransformMatrix() const;
|
||||
|
||||
NzNode& Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ class NAZARA_API NzSubMesh : public NzResource
|
|||
virtual const NzAxisAlignedBox& GetAABB() const = 0;
|
||||
virtual nzAnimationType GetAnimationType() const = 0;
|
||||
virtual const NzIndexBuffer* GetIndexBuffer() const = 0;
|
||||
unsigned int GetMaterialIndex() const;
|
||||
const NzMesh* GetParent() const;
|
||||
nzPrimitiveType GetPrimitiveType() const;
|
||||
unsigned int GetSkinIndex() const;
|
||||
virtual const NzVertexBuffer* GetVertexBuffer() const = 0;
|
||||
virtual unsigned int GetVertexCount() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - 3D Module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/3D/3D.hpp>
|
||||
#include <Nazara/3D/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/3D/Debug.hpp>
|
||||
|
||||
bool Nz3D::Initialize()
|
||||
{
|
||||
if (s_moduleReferenceCounter++ != 0)
|
||||
return true; // Déjà initialisé
|
||||
|
||||
// Initialisation des dépendances
|
||||
if (!NzRenderer::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize renderer module");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialisation du module
|
||||
|
||||
NazaraNotice("Initialized: 3D module");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Nz3D::IsInitialized()
|
||||
{
|
||||
return s_moduleReferenceCounter != 0;
|
||||
}
|
||||
|
||||
void Nz3D::Uninitialize()
|
||||
{
|
||||
if (--s_moduleReferenceCounter != 0)
|
||||
return; // Encore utilisé
|
||||
|
||||
// Libération du module
|
||||
|
||||
NazaraNotice("Uninitialized: 3D module");
|
||||
|
||||
// Libération des dépendances
|
||||
NzRenderer::Uninitialize();
|
||||
}
|
||||
|
||||
unsigned int Nz3D::s_moduleReferenceCounter = 0;
|
||||
|
|
@ -20,7 +20,7 @@ void NzError(nzErrorType type, const NzString& error, unsigned int line, const c
|
|||
|
||||
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
|
||||
if (type == nzErrorType_AssertFailed)
|
||||
exit(EXIT_FAILURE);
|
||||
std::exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ NzString NzGetLastSystemError(unsigned int code)
|
|||
|
||||
return error;
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
return strerror(code);
|
||||
return std::strerror(code);
|
||||
#else
|
||||
#error GetLastSystemError is not implemented on this platform
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <typeinfo>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzResource::NzResource(bool persistent) :
|
||||
|
|
@ -111,13 +113,13 @@ void NzResource::RemoveResourceReference() const
|
|||
}
|
||||
}
|
||||
|
||||
void NzResource::SetPersistent(bool persistent)
|
||||
void NzResource::SetPersistent(bool persistent, bool checkReferenceCount)
|
||||
{
|
||||
NazaraMutexLock(m_mutex);
|
||||
|
||||
m_resourcePersistent = persistent;
|
||||
|
||||
if (!persistent && m_resourceReferenceCount == 0)
|
||||
if (checkReferenceCount && !persistent && m_resourceReferenceCount == 0)
|
||||
{
|
||||
NazaraMutexUnlock(m_mutex);
|
||||
delete this;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LOADERS_TEXTURE_HPP
|
||||
#define NAZARA_LOADERS_TEXTURE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
void NzLoaders_Texture_Register();
|
||||
void NzLoaders_Texture_Unregister();
|
||||
|
||||
#endif // NAZARA_LOADERS_TEXTURE_HPP
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool Check(NzInputStream& stream, const NzMaterialParams& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
NazaraUnused(parameters);
|
||||
|
||||
return true; ///FIXME: Pas bon
|
||||
}
|
||||
|
||||
bool Load(NzMaterial* material, NzInputStream& stream, const NzMaterialParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
NzTexture* texture = new NzTexture;
|
||||
if (!texture->LoadFromStream(stream))
|
||||
{
|
||||
NazaraError("Failed to load diffuse map");
|
||||
return false;
|
||||
}
|
||||
|
||||
material->Reset();
|
||||
material->SetDiffuseMap(texture);
|
||||
texture->SetPersistent(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_Texture_Register()
|
||||
{
|
||||
///FIXME: Pas bon
|
||||
NzMaterialLoader::RegisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load);
|
||||
}
|
||||
|
||||
void NzLoaders_Texture_Unregister()
|
||||
{
|
||||
NzMaterialLoader::UnregisterLoader("bmp,gif,hdr,jpg,jpeg,pic,png,psd,tga", Check, Load);
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
|
||||
bool NzMaterialParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NzMaterial::NzMaterial() :
|
||||
m_diffuseMap(nullptr),
|
||||
m_specularMap(nullptr)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
NzMaterial::~NzMaterial()
|
||||
{
|
||||
if (m_diffuseMap)
|
||||
m_diffuseMap->RemoveResourceReference();
|
||||
|
||||
if (m_specularMap)
|
||||
m_specularMap->RemoveResourceReference();
|
||||
}
|
||||
|
||||
void NzMaterial::EnableAlphaBlending(bool alphaBlending)
|
||||
{
|
||||
m_alphaBlendingEnabled = alphaBlending;
|
||||
}
|
||||
|
||||
void NzMaterial::EnableZTest(bool zTest)
|
||||
{
|
||||
m_zTestEnabled = zTest;
|
||||
}
|
||||
|
||||
void NzMaterial::EnableZWrite(bool zWrite)
|
||||
{
|
||||
m_zWriteEnabled = zWrite;
|
||||
}
|
||||
|
||||
NzColor NzMaterial::GetAmbientColor() const
|
||||
{
|
||||
return m_ambientColor;
|
||||
}
|
||||
|
||||
NzColor NzMaterial::GetDiffuseColor() const
|
||||
{
|
||||
return m_diffuseColor;
|
||||
}
|
||||
|
||||
const NzTexture* NzMaterial::GetDiffuseMap() const
|
||||
{
|
||||
return m_diffuseMap;
|
||||
}
|
||||
|
||||
nzBlendFunc NzMaterial::GetDstAlpha() const
|
||||
{
|
||||
return m_dstAlpha;
|
||||
}
|
||||
|
||||
nzFaceCulling NzMaterial::GetFaceCulling() const
|
||||
{
|
||||
return m_faceCulling;
|
||||
}
|
||||
|
||||
nzFaceFilling NzMaterial::GetFaceFilling() const
|
||||
{
|
||||
return m_faceFilling;
|
||||
}
|
||||
|
||||
float NzMaterial::GetShininess() const
|
||||
{
|
||||
return m_shininess;
|
||||
}
|
||||
|
||||
NzColor NzMaterial::GetSpecularColor() const
|
||||
{
|
||||
return m_specularColor;
|
||||
}
|
||||
|
||||
const NzTexture* NzMaterial::GetSpecularMap() const
|
||||
{
|
||||
return m_specularMap;
|
||||
}
|
||||
|
||||
nzBlendFunc NzMaterial::GetSrcAlpha() const
|
||||
{
|
||||
return m_srcAlpha;
|
||||
}
|
||||
|
||||
nzRendererComparison NzMaterial::GetZTestCompare() const
|
||||
{
|
||||
return m_zTestCompareFunc;
|
||||
}
|
||||
|
||||
bool NzMaterial::IsAlphaBlendingEnabled() const
|
||||
{
|
||||
return m_alphaBlendingEnabled;
|
||||
}
|
||||
|
||||
bool NzMaterial::IsZTestEnabled() const
|
||||
{
|
||||
return m_zTestEnabled;
|
||||
}
|
||||
|
||||
bool NzMaterial::IsZWriteEnabled() const
|
||||
{
|
||||
return m_zWriteEnabled;
|
||||
}
|
||||
|
||||
bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params)
|
||||
{
|
||||
return NzMaterialLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params)
|
||||
{
|
||||
return NzMaterialLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params)
|
||||
{
|
||||
return NzMaterialLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzMaterial::Reset()
|
||||
{
|
||||
if (m_diffuseMap)
|
||||
{
|
||||
m_diffuseMap->RemoveResourceReference();
|
||||
m_diffuseMap = nullptr;
|
||||
}
|
||||
|
||||
if (m_specularMap)
|
||||
{
|
||||
m_specularMap->RemoveResourceReference();
|
||||
m_specularMap = nullptr;
|
||||
}
|
||||
|
||||
m_alphaBlendingEnabled = false;
|
||||
m_ambientColor = NzColor::Black;
|
||||
m_diffuseColor = NzColor::White;
|
||||
m_dstAlpha = nzBlendFunc_Zero;
|
||||
m_faceCulling = nzFaceCulling_Back;
|
||||
m_faceFilling = nzFaceFilling_Fill;
|
||||
m_shininess = 0;
|
||||
m_specularColor = NzColor::White;
|
||||
m_srcAlpha = nzBlendFunc_One;
|
||||
m_zTestCompareFunc = nzRendererComparison_LessOrEqual;
|
||||
m_zTestEnabled = true;
|
||||
m_zWriteEnabled = true;
|
||||
}
|
||||
|
||||
void NzMaterial::SetAmbientColor(const NzColor& ambient)
|
||||
{
|
||||
m_ambientColor = ambient;
|
||||
}
|
||||
|
||||
void NzMaterial::SetDiffuseColor(const NzColor& diffuse)
|
||||
{
|
||||
m_diffuseColor = diffuse;
|
||||
}
|
||||
|
||||
void NzMaterial::SetDiffuseMap(const NzTexture* map)
|
||||
{
|
||||
if (m_diffuseMap)
|
||||
m_diffuseMap->RemoveResourceReference();
|
||||
|
||||
m_diffuseMap = map;
|
||||
if (m_diffuseMap)
|
||||
m_diffuseMap->AddResourceReference();
|
||||
}
|
||||
|
||||
void NzMaterial::SetDstAlpha(nzBlendFunc func)
|
||||
{
|
||||
m_dstAlpha = func;
|
||||
}
|
||||
|
||||
void NzMaterial::SetFaceCulling(nzFaceCulling culling)
|
||||
{
|
||||
m_faceCulling = culling;
|
||||
}
|
||||
|
||||
void NzMaterial::SetFaceFilling(nzFaceFilling filling)
|
||||
{
|
||||
m_faceFilling = filling;
|
||||
}
|
||||
|
||||
void NzMaterial::SetShininess(float shininess)
|
||||
{
|
||||
m_shininess = shininess;
|
||||
}
|
||||
|
||||
void NzMaterial::SetSpecularColor(const NzColor& specular)
|
||||
{
|
||||
m_specularColor = specular;
|
||||
}
|
||||
|
||||
void NzMaterial::SetSpecularMap(const NzTexture* map)
|
||||
{
|
||||
if (m_specularMap)
|
||||
m_specularMap->RemoveResourceReference();
|
||||
|
||||
m_specularMap = map;
|
||||
if (m_specularMap)
|
||||
m_specularMap->AddResourceReference();
|
||||
}
|
||||
|
||||
void NzMaterial::SetSrcAlpha(nzBlendFunc func)
|
||||
{
|
||||
m_srcAlpha = func;
|
||||
}
|
||||
|
||||
void NzMaterial::SetZTestCompare(nzRendererComparison compareFunc)
|
||||
{
|
||||
m_zTestEnabled = compareFunc;
|
||||
}
|
||||
|
||||
const NzMaterial* NzMaterial::GetDefault()
|
||||
{
|
||||
static NzMaterial defaultMaterial;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
defaultMaterial.SetFaceCulling(nzFaceCulling_FrontAndBack);
|
||||
defaultMaterial.SetFaceFilling(nzFaceFilling_Line);
|
||||
defaultMaterial.SetDiffuseColor(NzColor::White);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return &defaultMaterial;
|
||||
}
|
||||
|
||||
NzMaterialLoader::LoaderList NzMaterial::s_loaders;
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
|
|
@ -449,6 +450,9 @@ bool NzRenderer::Initialize()
|
|||
NazaraWarning("Failed to initialize debug drawer");
|
||||
#endif
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Texture_Register();
|
||||
|
||||
NazaraNotice("Initialized: Renderer module");
|
||||
|
||||
return true;
|
||||
|
|
@ -903,6 +907,9 @@ void NzRenderer::Uninitialize()
|
|||
if (--s_moduleReferenceCounter != 0)
|
||||
return; // Encore utilisé
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Texture_Unregister();
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
NzDebugDrawer::Uninitialize();
|
||||
#endif
|
||||
|
|
@ -1065,11 +1072,11 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
|
||||
glEnableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
glVertexAttribPointer(NzOpenGL::AttributeIndex[i],
|
||||
NzVertexDeclaration::GetElementCount(element->type),
|
||||
NzOpenGL::ElementType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
NzVertexDeclaration::GetElementCount(element->type),
|
||||
NzOpenGL::ElementType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
}
|
||||
else
|
||||
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Utility/KeyframeMesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <vector>
|
||||
|
|
@ -222,16 +223,22 @@ const NzVertexBuffer* NzKeyframeMesh::GetVertexBuffer() const
|
|||
return m_impl->vertexBuffer;
|
||||
}
|
||||
|
||||
void NzKeyframeMesh::Interpolate(unsigned int frameA, unsigned int frameB, float interpolation) const
|
||||
void NzKeyframeMesh::Interpolate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_parent->HasAnimation())
|
||||
if (!animation || !animation->IsValid())
|
||||
{
|
||||
NazaraError("Parent mesh has no animation");
|
||||
NazaraError("Animation must be valid");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = m_parent->GetFrameCount();
|
||||
if (animation->GetType() != nzAnimationType_Keyframe)
|
||||
{
|
||||
NazaraError("Animation must be of keyframe type");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = animation->GetFrameCount();
|
||||
if (frameA >= frameCount)
|
||||
{
|
||||
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Math/Quaternion.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/KeyframeMesh.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
|
|
@ -18,7 +19,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
bool Check(NzInputStream& stream, const NzMeshParams& parameters)
|
||||
/// Loader de mesh
|
||||
bool CheckMesh(NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ namespace
|
|||
return magic[0] == md2Ident && magic[1] == 8;
|
||||
}
|
||||
|
||||
bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
bool LoadMesh(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
md2_header header;
|
||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||
|
|
@ -69,11 +71,8 @@ namespace
|
|||
|
||||
/// Création du mesh
|
||||
// Animé ou statique, c'est la question
|
||||
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||
|
||||
bool animated = (parameters.animated && startFrame != endFrame);
|
||||
if (animated)
|
||||
///FIXME: Le loader ne traite pas correctement le cas d'un mesh statique
|
||||
if (parameters.animated)
|
||||
mesh->CreateKeyframe();
|
||||
else
|
||||
mesh->CreateStatic();
|
||||
|
|
@ -84,9 +83,12 @@ namespace
|
|||
return false;
|
||||
}
|
||||
|
||||
mesh->SetAnimation(stream.GetPath()); // Même fichier
|
||||
|
||||
/// Chargement des skins
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
mesh->SetMaterialCount(header.num_skins);
|
||||
stream.SetCursorPos(header.offset_skins);
|
||||
{
|
||||
NzString baseDir = stream.GetDirectory();
|
||||
|
|
@ -94,90 +96,19 @@ namespace
|
|||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
stream.Read(skin, 68*sizeof(char));
|
||||
mesh->AddMaterial(baseDir + skin);
|
||||
mesh->SetMaterial(i, baseDir + skin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des animations
|
||||
if (animated)
|
||||
{
|
||||
NzAnimation* animation = new NzAnimation;
|
||||
if (animation->CreateKeyframe(endFrame-startFrame+1))
|
||||
{
|
||||
// Décodage des séquences
|
||||
///TODO: Optimiser le calcul
|
||||
char last[16];
|
||||
|
||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + 2*sizeof(NzVector3f));
|
||||
stream.Read(last, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(last)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(last[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
last[pos+1] = '\0';
|
||||
|
||||
NzSequence sequence;
|
||||
sequence.firstFrame = startFrame;
|
||||
sequence.frameCount = 0;
|
||||
sequence.frameRate = 10; // Par défaut pour les animations MD2
|
||||
sequence.name = last;
|
||||
|
||||
char name[16];
|
||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + 2*sizeof(NzVector3f));
|
||||
stream.Read(name, 16*sizeof(char));
|
||||
|
||||
pos = std::strlen(name)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(name[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
name[pos+1] = '\0';
|
||||
|
||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||
{
|
||||
std::strcpy(last, name);
|
||||
|
||||
// Alors on enregistre la séquence actuelle
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
// Et on initialise la séquence suivante
|
||||
sequence.firstFrame = i;
|
||||
sequence.frameCount = 0;
|
||||
sequence.name = last;
|
||||
}
|
||||
|
||||
sequence.frameCount++;
|
||||
}
|
||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
mesh->SetAnimation(animation);
|
||||
animation->SetPersistent(false);
|
||||
}
|
||||
else
|
||||
NazaraInternalError("Failed to create animaton");
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
// TODO: Utiliser les commandes OpenGL pour créer des indices et accélérer le rendu
|
||||
unsigned int frameCount = endFrame - startFrame + 1;
|
||||
unsigned int vertexCount = header.num_tris * 3;
|
||||
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, parameters.storage, nzBufferUsage_Dynamic));
|
||||
std::unique_ptr<NzKeyframeMesh> subMesh(new NzKeyframeMesh(mesh));
|
||||
if (!subMesh->Create(vertexBuffer.get(), frameCount))
|
||||
if (!subMesh->Create(vertexBuffer.get(), header.num_frames))
|
||||
{
|
||||
NazaraError("Failed to create SubMesh");
|
||||
return false;
|
||||
|
|
@ -222,13 +153,13 @@ namespace
|
|||
#endif
|
||||
|
||||
/// Chargement des frames
|
||||
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
||||
stream.SetCursorPos(header.offset_frames);
|
||||
|
||||
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
|
||||
NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f);
|
||||
|
||||
md2_vertex* vertices = new md2_vertex[header.num_vertices];
|
||||
for (unsigned int f = 0; f < frameCount; ++f)
|
||||
for (unsigned int f = 0; f < header.num_frames; ++f)
|
||||
{
|
||||
NzVector3f scale, translate;
|
||||
|
||||
|
|
@ -286,14 +217,125 @@ namespace
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Loader d'animations
|
||||
bool CheckAnim(NzInputStream& stream, const NzAnimationParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt32 magic[2];
|
||||
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
||||
return false;
|
||||
|
||||
#ifdef NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
||||
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
return magic[0] == md2Ident && magic[1] == 8;
|
||||
}
|
||||
|
||||
bool LoadAnim(NzAnimation* animation, NzInputStream& stream, const NzAnimationParams& parameters)
|
||||
{
|
||||
md2_header header;
|
||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_BIG_ENDIAN
|
||||
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (stream.GetSize() < header.offset_end)
|
||||
{
|
||||
NazaraError("Incomplete MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int startFrame = std::min(parameters.startFrame, static_cast<unsigned int>(header.num_frames-1));
|
||||
unsigned int endFrame = std::min(parameters.endFrame, static_cast<unsigned int>(header.num_frames-1));
|
||||
|
||||
unsigned int frameCount = endFrame - startFrame + 1;
|
||||
if (!animation->CreateKeyframe(frameCount))
|
||||
{
|
||||
NazaraInternalError("Failed to create animaton");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Décodage des séquences
|
||||
///TODO: Optimiser le calcul
|
||||
char last[16];
|
||||
|
||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + 2*sizeof(NzVector3f));
|
||||
stream.Read(last, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(last)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(last[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
last[pos+1] = '\0';
|
||||
|
||||
NzSequence sequence;
|
||||
sequence.firstFrame = startFrame;
|
||||
sequence.frameCount = 0;
|
||||
sequence.frameRate = 10; // Par défaut pour les animations MD2
|
||||
sequence.name = last;
|
||||
|
||||
char name[16];
|
||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + 2*sizeof(NzVector3f));
|
||||
stream.Read(name, 16*sizeof(char));
|
||||
|
||||
pos = std::strlen(name)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(name[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
name[pos+1] = '\0';
|
||||
|
||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||
{
|
||||
std::strcpy(last, name);
|
||||
|
||||
// Alors on enregistre la séquence actuelle
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
// Et on initialise la séquence suivante
|
||||
sequence.firstFrame = i;
|
||||
sequence.frameCount = 0;
|
||||
sequence.name = last;
|
||||
}
|
||||
|
||||
sequence.frameCount++;
|
||||
}
|
||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_MD2_Register()
|
||||
{
|
||||
NzMeshLoader::RegisterLoader("md2", Check, Load);
|
||||
NzAnimationLoader::RegisterLoader("md2", CheckAnim, LoadAnim);
|
||||
NzMeshLoader::RegisterLoader("md2", CheckMesh, LoadMesh);
|
||||
}
|
||||
|
||||
void NzLoaders_MD2_Unregister()
|
||||
{
|
||||
NzMeshLoader::UnregisterLoader("md2", Check, Load);
|
||||
NzAnimationLoader::UnregisterLoader("md2", CheckAnim, LoadAnim);
|
||||
NzMeshLoader::UnregisterLoader("md2", CheckMesh, LoadMesh);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,8 +175,11 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
joint->SetInverseBindMatrix(bindMatrix.InverseAffine());
|
||||
}
|
||||
|
||||
for (const Mesh& md5Mesh : m_meshes)
|
||||
mesh->SetMaterialCount(m_meshes.size());
|
||||
for (unsigned int i = 0; i < m_meshes.size(); ++i)
|
||||
{
|
||||
const Mesh& md5Mesh = m_meshes[i];
|
||||
|
||||
void* ptr;
|
||||
unsigned int indexCount = md5Mesh.triangles.size()*3;
|
||||
unsigned int vertexCount = md5Mesh.vertices.size();
|
||||
|
|
@ -270,10 +273,10 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
vertexBuffer.release();
|
||||
|
||||
NzWeight* weights = subMesh->GetWeight();
|
||||
for (unsigned int i = 0; i < weightCount; ++i)
|
||||
for (unsigned int j = 0; j < weightCount; ++j)
|
||||
{
|
||||
weights->jointIndex = md5Mesh.weights[i].joint;
|
||||
weights->weight = md5Mesh.weights[i].bias;
|
||||
weights->jointIndex = md5Mesh.weights[j].joint;
|
||||
weights->weight = md5Mesh.weights[j].bias;
|
||||
weights++;
|
||||
}
|
||||
|
||||
|
|
@ -301,14 +304,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
}
|
||||
|
||||
// Material
|
||||
if (!md5Mesh.shader.IsEmpty())
|
||||
{
|
||||
unsigned int skinIndex;
|
||||
if (mesh->AddMaterial(baseDir + md5Mesh.shader, &skinIndex))
|
||||
subMesh->SetMaterialIndex(skinIndex);
|
||||
else
|
||||
NazaraWarning("Failed to add mesh shader");
|
||||
}
|
||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
||||
subMesh->SetMaterialIndex(i);
|
||||
|
||||
if (!mesh->AddSubMesh(subMesh.get()))
|
||||
{
|
||||
|
|
@ -320,18 +317,12 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
|
||||
// Animation
|
||||
// Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle.
|
||||
NzString animationPath = m_stream.GetPath();
|
||||
if (!animationPath.IsEmpty())
|
||||
NzString path = m_stream.GetPath();
|
||||
if (!path.IsEmpty())
|
||||
{
|
||||
animationPath.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive);
|
||||
if (NzFile::Exists(animationPath))
|
||||
{
|
||||
std::unique_ptr<NzAnimation> animation(new NzAnimation);
|
||||
if (animation->LoadFromFile(animationPath) && mesh->SetAnimation(animation.get()))
|
||||
animation.release();
|
||||
else
|
||||
NazaraWarning("Failed to load mesh's animation");
|
||||
}
|
||||
path.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive);
|
||||
if (NzFile::Exists(path))
|
||||
mesh->SetAnimation(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -343,8 +334,9 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
return false;
|
||||
}
|
||||
|
||||
for (const Mesh& md5Mesh : m_meshes)
|
||||
for (unsigned int i = 0; i < m_meshes.size(); ++i)
|
||||
{
|
||||
const Mesh& md5Mesh = m_meshes[i];
|
||||
void* ptr;
|
||||
unsigned int indexCount = md5Mesh.triangles.size()*3;
|
||||
unsigned int vertexCount = md5Mesh.vertices.size();
|
||||
|
|
@ -479,14 +471,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
indexBuffer.release();
|
||||
|
||||
// Material
|
||||
if (!md5Mesh.shader.IsEmpty())
|
||||
{
|
||||
unsigned int skinIndex;
|
||||
if (mesh->AddMaterial(baseDir + md5Mesh.shader, &skinIndex))
|
||||
subMesh->SetMaterialIndex(skinIndex);
|
||||
else
|
||||
NazaraWarning("Failed to add mesh shader");
|
||||
}
|
||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
||||
subMesh->SetMaterialIndex(i);
|
||||
|
||||
if (!mesh->AddSubMesh(subMesh.get()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/KeyframeMesh.hpp>
|
||||
|
|
@ -23,12 +24,6 @@ NzMeshParams::NzMeshParams()
|
|||
|
||||
bool NzMeshParams::IsValid() const
|
||||
{
|
||||
if (!animation.IsValid())
|
||||
{
|
||||
NazaraError("Invalid animation parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NzBuffer::IsSupported(storage))
|
||||
{
|
||||
NazaraError("Storage not supported");
|
||||
|
|
@ -46,7 +41,7 @@ struct NzMeshImpl
|
|||
nzAnimationType animationType;
|
||||
NzAxisAlignedBox aabb;
|
||||
NzSkeleton skeleton; // Uniquement pour les animations squelettiques
|
||||
const NzAnimation* animation = nullptr;
|
||||
NzString animationPath;
|
||||
unsigned int jointCount; // Uniquement pour les animations squelettiques
|
||||
};
|
||||
|
||||
|
|
@ -55,45 +50,6 @@ NzMesh::~NzMesh()
|
|||
Destroy();
|
||||
}
|
||||
|
||||
bool NzMesh::AddMaterial(const NzString& matPath, unsigned int* matIndex)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matPath.IsEmpty())
|
||||
{
|
||||
NazaraError("Material path is empty");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzString path = NzFile::NormalizeSeparators(matPath);
|
||||
|
||||
for (unsigned int i = 0; i < m_impl->materials.size(); ++i)
|
||||
{
|
||||
if (m_impl->materials[i] == path) // Ce skin est-il déjà présent ?
|
||||
{
|
||||
if (matIndex)
|
||||
*matIndex = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sinon on l'ajoute
|
||||
|
||||
if (matIndex)
|
||||
*matIndex = m_impl->materials.size();
|
||||
|
||||
m_impl->materials.push_back(matPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzMesh::AddSubMesh(NzSubMesh* subMesh)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
|
|
@ -111,7 +67,7 @@ bool NzMesh::AddSubMesh(NzSubMesh* subMesh)
|
|||
|
||||
if (subMesh->GetAnimationType() != m_impl->animationType)
|
||||
{
|
||||
NazaraError("Submesh's animation type must match mesh animation type");
|
||||
NazaraError("Submesh animation type must match mesh animation type");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -154,7 +110,7 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
|
|||
|
||||
if (m_impl->animationType != subMesh->GetAnimationType())
|
||||
{
|
||||
NazaraError("Submesh's animation type must match mesh animation type");
|
||||
NazaraError("Submesh animation type must match mesh animation type");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -170,7 +126,7 @@ bool NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
|
|||
return true;
|
||||
}
|
||||
|
||||
void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolation) const
|
||||
void NzMesh::Animate(const NzAnimation* animation, unsigned int frameA, unsigned int frameB, float interpolation) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
|
|
@ -179,13 +135,19 @@ void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolati
|
|||
return;
|
||||
}
|
||||
|
||||
if (!m_impl->animation)
|
||||
if (!animation || !animation->IsValid())
|
||||
{
|
||||
NazaraError("Mesh has no animation");
|
||||
NazaraError("Animation must be valid");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = m_impl->animation->GetFrameCount();
|
||||
if (animation->GetType() != m_impl->animationType)
|
||||
{
|
||||
NazaraError("Animation type must match mesh animation type");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int frameCount = animation->GetFrameCount();
|
||||
if (frameA >= frameCount)
|
||||
{
|
||||
NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(frameCount) + ')');
|
||||
|
|
@ -213,12 +175,12 @@ void NzMesh::Animate(unsigned int frameA, unsigned int frameB, float interpolati
|
|||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
NzKeyframeMesh* keyframeMesh = static_cast<NzKeyframeMesh*>(subMesh);
|
||||
keyframeMesh->Interpolate(frameA, frameB, interpolation);
|
||||
keyframeMesh->InterpolateImpl(frameA, frameB, interpolation);
|
||||
}
|
||||
break;
|
||||
|
||||
case nzAnimationType_Skeletal:
|
||||
m_impl->animation->AnimateSkeleton(&m_impl->skeleton, frameA, frameB, interpolation);
|
||||
animation->AnimateSkeleton(&m_impl->skeleton, frameA, frameB, interpolation);
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
NzSkeletalMesh* skeletalMesh = static_cast<NzSkeletalMesh*>(subMesh);
|
||||
|
|
@ -282,9 +244,6 @@ void NzMesh::Destroy()
|
|||
{
|
||||
NotifyDestroy();
|
||||
|
||||
if (m_impl->animation)
|
||||
m_impl->animation->RemoveResourceListener(this);
|
||||
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
subMesh->RemoveResourceListener(this);
|
||||
|
||||
|
|
@ -312,17 +271,17 @@ const NzAxisAlignedBox& NzMesh::GetAABB() const
|
|||
return m_impl->aabb;
|
||||
}
|
||||
|
||||
const NzAnimation* NzMesh::GetAnimation() const
|
||||
NzString NzMesh::GetAnimation() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return nullptr;
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation;
|
||||
return m_impl->animationPath;
|
||||
}
|
||||
|
||||
nzAnimationType NzMesh::GetAnimationType() const
|
||||
|
|
@ -338,25 +297,6 @@ nzAnimationType NzMesh::GetAnimationType() const
|
|||
return m_impl->animationType;
|
||||
}
|
||||
|
||||
unsigned int NzMesh::GetFrameCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_impl->animation)
|
||||
{
|
||||
NazaraError("Mesh has no animation");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation->GetFrameCount();
|
||||
}
|
||||
|
||||
unsigned int NzMesh::GetJointCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
|
|
@ -596,32 +536,6 @@ void NzMesh::InvalidateAABB() const
|
|||
m_impl->aabb.SetNull();
|
||||
}
|
||||
|
||||
bool NzMesh::HasAnimation() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->animation != nullptr;
|
||||
}
|
||||
|
||||
bool NzMesh::HasMaterial(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return index < m_impl->materials.size();
|
||||
}
|
||||
|
||||
bool NzMesh::HasSubMesh(const NzString& identifier) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
|
|
@ -681,29 +595,6 @@ bool NzMesh::LoadFromStream(NzInputStream& stream, const NzMeshParams& params)
|
|||
return NzMeshLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzMesh::RemoveMaterial(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= m_impl->materials.size())
|
||||
{
|
||||
NazaraError("Material index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->materials.size()) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// On accède à l'itérateur correspondant à l'entrée #index
|
||||
auto it = m_impl->materials.begin();
|
||||
std::advance(it, index);
|
||||
|
||||
m_impl->materials.erase(it);
|
||||
}
|
||||
|
||||
void NzMesh::RemoveSubMesh(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
|
|
@ -763,46 +654,58 @@ void NzMesh::RemoveSubMesh(unsigned int index)
|
|||
m_impl->aabb.SetNull(); // On invalide l'AABB
|
||||
}
|
||||
|
||||
bool NzMesh::SetAnimation(const NzAnimation* animation)
|
||||
void NzMesh::SetAnimation(const NzString& animationPath)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_impl->animationType == nzAnimationType_Static)
|
||||
{
|
||||
NazaraError("Static meshes cannot have animation");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (animation == m_impl->animation)
|
||||
return true;
|
||||
m_impl->animationPath = animationPath;
|
||||
}
|
||||
|
||||
if (m_impl->animation)
|
||||
m_impl->animation->RemoveResourceListener(this);
|
||||
|
||||
if (animation)
|
||||
void NzMesh::SetMaterial(unsigned int matIndex, const NzString& materialPath)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (animation->GetType() != m_impl->animationType)
|
||||
{
|
||||
NazaraError("Animation's type must match mesh animation type");
|
||||
m_impl->animation = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
animation->AddResourceListener(this);
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
|
||||
m_impl->animation = animation;
|
||||
if (matIndex >= m_impl->materials.size())
|
||||
{
|
||||
NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_impl->materials.size()));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
m_impl->materials[matIndex] = materialPath;
|
||||
}
|
||||
|
||||
void NzMesh::SetMaterialCount(unsigned int matCount)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Mesh not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->materials.resize(matCount);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
for (NzSubMesh* subMesh : m_impl->subMeshes)
|
||||
{
|
||||
unsigned int matIndex = subMesh->GetMaterialIndex();
|
||||
if (matIndex >= matCount)
|
||||
NazaraWarning("SubMesh " + NzString::Pointer(subMesh) + " material index is over mesh new material count (" + NzString::Number(matIndex) + " >= " + NzString::Number(matCount));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzMesh::Skin(const NzSkeleton* skeleton) const
|
||||
|
|
@ -858,30 +761,11 @@ const NzVertexDeclaration* NzMesh::GetDeclaration()
|
|||
return &declaration;
|
||||
}
|
||||
|
||||
void NzMesh::OnResourceCreated(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(index);
|
||||
|
||||
if (resource == m_impl->animation)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (m_impl->animation->GetType() != m_impl->animationType)
|
||||
{
|
||||
NazaraError("Animation's type must match mesh animation type");
|
||||
|
||||
m_impl->animation->RemoveResourceListener(this);
|
||||
m_impl->animation = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void NzMesh::OnResourceReleased(const NzResource* resource, int index)
|
||||
{
|
||||
if (resource == m_impl->animation)
|
||||
SetAnimation(nullptr);
|
||||
else
|
||||
RemoveSubMesh(index);
|
||||
NazaraUnused(resource);
|
||||
|
||||
RemoveSubMesh(index);
|
||||
}
|
||||
|
||||
NzMeshLoader::LoaderList NzMesh::s_loaders;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ NzVector3f NzNode::GetTranslation() const
|
|||
return m_translation;
|
||||
}
|
||||
|
||||
NzMatrix4f NzNode::GetTransformMatrix() const
|
||||
const NzMatrix4f& NzNode::GetTransformMatrix() const
|
||||
{
|
||||
if (!m_matrixUpdated)
|
||||
UpdateMatrix();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ nzPrimitiveType NzSubMesh::GetPrimitiveType() const
|
|||
return m_primitiveType;
|
||||
}
|
||||
|
||||
unsigned int NzSubMesh::GetSkinIndex() const
|
||||
unsigned int NzSubMesh::GetMaterialIndex() const
|
||||
{
|
||||
return m_matIndex;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue