168 lines
6.6 KiB
C++
168 lines
6.6 KiB
C++
//----------------------------------------------------------------------------//
|
|
// //
|
|
// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation //
|
|
// and distributed under the MIT License (MIT). //
|
|
// //
|
|
// Copyright (c) Guillaume Blanc //
|
|
// //
|
|
// 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. //
|
|
// //
|
|
//----------------------------------------------------------------------------//
|
|
|
|
#ifndef OZZ_SAMPLES_FRAMEWORK_MESH_H_
|
|
#define OZZ_SAMPLES_FRAMEWORK_MESH_H_
|
|
|
|
#include "ozz/base/containers/vector.h"
|
|
#include "ozz/base/io/archive_traits.h"
|
|
#include "ozz/base/maths/simd_math.h"
|
|
#include "ozz/base/maths/vec_float.h"
|
|
#include "ozz/base/platform.h"
|
|
|
|
namespace ozz {
|
|
namespace sample {
|
|
|
|
// Defines a mesh with skinning information (joint indices and weights).
|
|
// The mesh is subdivided into parts that group vertices according to their
|
|
// number of influencing joints. Triangle indices are shared across mesh parts.
|
|
struct Mesh {
|
|
// Number of triangle indices for the mesh.
|
|
int triangle_index_count() const {
|
|
return static_cast<int>(triangle_indices.size());
|
|
}
|
|
|
|
// Number of vertices for all mesh parts.
|
|
int vertex_count() const {
|
|
int vertex_count = 0;
|
|
for (size_t i = 0; i < parts.size(); ++i) {
|
|
vertex_count += parts[i].vertex_count();
|
|
}
|
|
return vertex_count;
|
|
}
|
|
|
|
// Maximum number of joints influences for all mesh parts.
|
|
int max_influences_count() const {
|
|
int max_influences_count = 0;
|
|
for (size_t i = 0; i < parts.size(); ++i) {
|
|
const int influences_count = parts[i].influences_count();
|
|
max_influences_count = influences_count > max_influences_count
|
|
? influences_count
|
|
: max_influences_count;
|
|
}
|
|
return max_influences_count;
|
|
}
|
|
|
|
// Test if the mesh has skinning informations.
|
|
bool skinned() const {
|
|
return !inverse_bind_poses.empty();
|
|
}
|
|
|
|
// Returns the number of joints used to skin the mesh.
|
|
int num_joints() const { return static_cast<int>(inverse_bind_poses.size()); }
|
|
|
|
// Returns the highest joint number used in the skeleton.
|
|
int highest_joint_index() const {
|
|
// Takes advantage that joint_remaps is sorted.
|
|
return joint_remaps.size() != 0 ? static_cast<int>(joint_remaps.back()) : 0;
|
|
}
|
|
|
|
// Defines a portion of the mesh. A mesh is subdivided in sets of vertices
|
|
// with the same number of joint influences.
|
|
struct Part {
|
|
int vertex_count() const { return static_cast<int>(positions.size()) / 3; }
|
|
|
|
int influences_count() const {
|
|
const int _vertex_count = vertex_count();
|
|
if (_vertex_count == 0) {
|
|
return 0;
|
|
}
|
|
return static_cast<int>(joint_indices.size()) / _vertex_count;
|
|
}
|
|
|
|
typedef ozz::vector<float> Positions;
|
|
Positions positions;
|
|
enum { kPositionsCpnts = 3 }; // x, y, z components
|
|
|
|
typedef ozz::vector<float> Normals;
|
|
Normals normals;
|
|
enum { kNormalsCpnts = 3 }; // x, y, z components
|
|
|
|
typedef ozz::vector<float> Tangents;
|
|
Tangents tangents;
|
|
enum { kTangentsCpnts = 4 }; // x, y, z, right or left handed.
|
|
|
|
typedef ozz::vector<float> UVs;
|
|
UVs uvs; // u, v components
|
|
enum { kUVsCpnts = 2 };
|
|
|
|
typedef ozz::vector<uint8_t> Colors;
|
|
Colors colors;
|
|
enum { kColorsCpnts = 4 }; // r, g, b, a components
|
|
|
|
typedef ozz::vector<uint16_t> JointIndices;
|
|
JointIndices joint_indices; // Stride equals influences_count
|
|
|
|
typedef ozz::vector<float> JointWeights;
|
|
JointWeights joint_weights; // Stride equals influences_count - 1
|
|
};
|
|
typedef ozz::vector<Part> Parts;
|
|
Parts parts;
|
|
|
|
// Triangles indices. Indices are shared across all parts.
|
|
typedef ozz::vector<uint16_t> TriangleIndices;
|
|
TriangleIndices triangle_indices;
|
|
|
|
// Joints remapping indices. As a skin might be influenced by a part of the
|
|
// skeleton only, joint indices and inverse bind pose matrices are reordered
|
|
// to contain only used ones. Note that this array is sorted.
|
|
typedef ozz::vector<uint16_t> JointRemaps;
|
|
JointRemaps joint_remaps;
|
|
|
|
// Inverse bind-pose matrices. These are only available for skinned meshes.
|
|
typedef ozz::vector<ozz::math::Float4x4> InversBindPoses;
|
|
InversBindPoses inverse_bind_poses;
|
|
};
|
|
} // namespace sample
|
|
|
|
namespace io {
|
|
|
|
OZZ_IO_TYPE_TAG("ozz-sample-Mesh-Part", sample::Mesh::Part)
|
|
OZZ_IO_TYPE_VERSION(1, sample::Mesh::Part)
|
|
|
|
template <>
|
|
struct Extern<sample::Mesh::Part> {
|
|
static void Save(OArchive& _archive, const sample::Mesh::Part* _parts,
|
|
size_t _count);
|
|
static void Load(IArchive& _archive, sample::Mesh::Part* _parts,
|
|
size_t _count, uint32_t _version);
|
|
};
|
|
|
|
OZZ_IO_TYPE_TAG("ozz-sample-Mesh", sample::Mesh)
|
|
OZZ_IO_TYPE_VERSION(1, sample::Mesh)
|
|
|
|
template <>
|
|
struct Extern<sample::Mesh> {
|
|
static void Save(OArchive& _archive, const sample::Mesh* _meshes,
|
|
size_t _count);
|
|
static void Load(IArchive& _archive, sample::Mesh* _meshes, size_t _count,
|
|
uint32_t _version);
|
|
};
|
|
} // namespace io
|
|
} // namespace ozz
|
|
#endif // OZZ_SAMPLES_FRAMEWORK_MESH_H_
|