Utility/Mesh: Replace scale by transform matrix

Former-commit-id: b02de61fe0213f5fdd074dfa868db415e9c770c3 [formerly e185f2b410f2a3e04a0f11be28665cf6e8dcb617]
Former-commit-id: d0c7e88fe2b5f8a4aa97640d050751def83f3783
This commit is contained in:
Lynix 2016-06-09 08:46:44 +02:00
parent f9d6cfcf07
commit 63ac80c7ff
7 changed files with 18 additions and 17 deletions

View File

@ -100,8 +100,8 @@ namespace Nz
params->animated = instance.CheckField<bool>("Animated", params->animated); params->animated = instance.CheckField<bool>("Animated", params->animated);
params->center = instance.CheckField<bool>("Center", params->center); params->center = instance.CheckField<bool>("Center", params->center);
params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs); params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs);
//params->matrix = instance.CheckField<Matrix4f>("Matrix", params->matrix);
params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers); params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
params->scale = instance.CheckField<Vector3f>("Scale", params->scale);
return 1; return 1;
} }

View File

@ -29,8 +29,8 @@ namespace Nz
{ {
MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement)
// La mise à l'échelle éventuelle que subira le mesh // La transformation appliquée à tous les sommets du mesh
Vector3f scale = Vector3f::Unit(); Matrix4f matrix = Matrix4f::Identity();
// Si ceci sera le stockage utilisé par les buffers // Si ceci sera le stockage utilisé par les buffers
UInt32 storage = DataStorage_Hardware; UInt32 storage = DataStorage_Hardware;

View File

@ -209,7 +209,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f); aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f);
aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f);
vertex->position = parameters.scale * Vector3f(position.x, position.y, position.z); vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z);
vertex->normal.Set(normal.x, normal.y, normal.z); vertex->normal.Set(normal.x, normal.y, normal.z);
vertex->tangent.Set(tangent.x, tangent.y, tangent.z); vertex->tangent.Set(tangent.x, tangent.y, tangent.z);
vertex->uv.Set(uv.x, uv.y); vertex->uv.Set(uv.x, uv.y);

View File

@ -188,11 +188,10 @@ namespace Nz
SwapBytes(&translate.z, sizeof(float)); SwapBytes(&translate.z, sizeof(float));
#endif #endif
// Un personnage de taille moyenne fait ~50 unités de haut dans Quake 2 constexpr float ScaleAdjust = 1.f / 27.8f; // Make a 50 Quake 2 units character a 1.8 unit long
// Avec Nazara, 1 unité = 1 mètre, nous devons donc adapter l'échelle
Vector3f s(parameters.scale/29.f); // 50/29 = 1.72 (Soit 1.72 mètre, proche de la taille moyenne d'un individu) scale *= ScaleAdjust;
scale *= s; translate *= ScaleAdjust;
translate *= s;
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer()); MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
@ -215,11 +214,13 @@ namespace Nz
/// Chargement des positions /// Chargement des positions
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices // Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f); Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f);
Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale);
matrix *= parameters.matrix;
for (unsigned int v = 0; v < header.num_vertices; ++v) for (unsigned int v = 0; v < header.num_vertices; ++v)
{ {
const MD2_Vertex& vert = vertices[v]; const MD2_Vertex& vert = vertices[v];
Vector3f position = rotationQuat * Vector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z); Vector3f position = matrix * Vector3f(vert.x, vert.y, vert.z);
vertex->position = position; vertex->position = position;
vertex->normal = rotationQuat * md2Normals[vert.n]; vertex->normal = rotationQuat * md2Normals[vert.n];

View File

@ -48,7 +48,8 @@ namespace Nz
// Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres
// Nous réduisons donc la taille générale des fichiers MD5 de 1/40 // Nous réduisons donc la taille générale des fichiers MD5 de 1/40
Vector3f scale(parameters.scale/40.f); Matrix4f matrix = Matrix4f::Transform(Nz::Vector3f::Zero(), rotationQuat, Vector3f(1.f / 40.f));
matrix *= parameters.matrix;
const MD5MeshParser::Joint* joints = parser.GetJoints(); const MD5MeshParser::Joint* joints = parser.GetJoints();
const MD5MeshParser::Mesh* meshes = parser.GetMeshes(); const MD5MeshParser::Mesh* meshes = parser.GetMeshes();
@ -267,7 +268,7 @@ namespace Nz
} }
// On retourne le modèle dans le bon sens // On retourne le modèle dans le bon sens
vertex->position = scale * (rotationQuat * finalPos); vertex->position = matrix * finalPos;
vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé
vertex++; vertex++;
} }

View File

@ -234,8 +234,7 @@ namespace Nz
MeshVertex& vertex = meshVertices[index]; MeshVertex& vertex = meshVertices[index];
const Vector4f& vec = positions[vertexIndices.position]; const Vector4f& vec = positions[vertexIndices.position];
vertex.position.Set(vec.x, vec.y, vec.z); vertex.position = Vector3f(parameters.matrix * vec);
vertex.position *= parameters.scale/vec.w;
if (vertexIndices.normal >= 0) if (vertexIndices.normal >= 0)
vertex.normal = normals[vertexIndices.normal]; vertex.normal = normals[vertexIndices.normal];

View File

@ -39,9 +39,9 @@ namespace Nz
return false; return false;
} }
if (scale == Vector3f::Zero()) if (matrix == Matrix4f::Zero())
{ {
NazaraError("Invalid scale"); NazaraError("Invalid matrix");
return false; return false;
} }
@ -111,7 +111,7 @@ namespace Nz
VertexBufferRef vertexBuffer; VertexBufferRef vertexBuffer;
Matrix4f matrix(primitive.matrix); Matrix4f matrix(primitive.matrix);
matrix.ApplyScale(params.scale); matrix *= params.matrix;
VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent); VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent);