Merge branch 'master' into explicitly-default-dtors
commit
f527e56f22
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -48,19 +47,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <fstream>
|
||||
#include "MMDCpp14.h"
|
||||
|
||||
namespace pmd
|
||||
{
|
||||
class PmdHeader
|
||||
{
|
||||
public:
|
||||
namespace pmd {
|
||||
|
||||
struct PmdHeader {
|
||||
std::string name;
|
||||
std::string name_english;
|
||||
std::string comment;
|
||||
std::string comment_english;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
char buffer[256];
|
||||
PmdHeader() = default;
|
||||
~PmdHeader() = default;
|
||||
|
||||
bool Read(std::ifstream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return false;
|
||||
}
|
||||
char buffer[256] = {};
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
stream->read(buffer, 256);
|
||||
|
@ -68,34 +70,39 @@ namespace pmd
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ReadExtension(std::ifstream* stream)
|
||||
{
|
||||
char buffer[256];
|
||||
bool ReadExtension(std::ifstream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[256] = {};
|
||||
stream->read(buffer, 20);
|
||||
name_english = std::string(buffer);
|
||||
stream->read(buffer, 256);
|
||||
comment_english = std::string(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PmdVertex
|
||||
{
|
||||
public:
|
||||
struct PmdVertex {
|
||||
float position[3];
|
||||
|
||||
float normal[3];
|
||||
|
||||
float uv[2];
|
||||
|
||||
uint16_t bone_index[2];
|
||||
|
||||
uint8_t bone_weight;
|
||||
|
||||
bool edge_invisible;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
PmdVertex() :
|
||||
position{ 0.0f }, normal{ 0.0f }, uv{ 0.0f }, bone_index{ 0 }, bone_weight(0), edge_invisible(false) {}
|
||||
|
||||
~PmdVertex() = default;
|
||||
|
||||
bool Read(std::ifstream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stream->read((char *)position, sizeof(float) * 3);
|
||||
stream->read((char *)normal, sizeof(float) * 3);
|
||||
stream->read((char *)uv, sizeof(float) * 2);
|
||||
|
@ -106,9 +113,7 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
class PmdMaterial
|
||||
{
|
||||
public:
|
||||
struct PmdMaterial {
|
||||
float diffuse[4];
|
||||
float power;
|
||||
float specular[3];
|
||||
|
@ -119,9 +124,18 @@ namespace pmd
|
|||
std::string texture_filename;
|
||||
std::string sphere_filename;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
{
|
||||
char buffer[20];
|
||||
PmdMaterial() :
|
||||
diffuse{ 0.0f }, power(0.0f), specular{ 0.0f }, ambient{ 0.0f }, toon_index(0), edge_flag(0), index_count(0), texture_filename(), sphere_filename() {}
|
||||
|
||||
~PmdMaterial() = default;
|
||||
|
||||
bool Read(std::ifstream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return false;
|
||||
}
|
||||
constexpr size_t BufferSize = 20;
|
||||
|
||||
char buffer[BufferSize] = {};
|
||||
stream->read((char *)&diffuse, sizeof(float) * 4);
|
||||
stream->read((char *)&power, sizeof(float));
|
||||
stream->read((char *)&specular, sizeof(float) * 3);
|
||||
|
@ -129,24 +143,22 @@ namespace pmd
|
|||
stream->read((char *)&toon_index, sizeof(uint8_t));
|
||||
stream->read((char *)&edge_flag, sizeof(uint8_t));
|
||||
stream->read((char *)&index_count, sizeof(uint32_t));
|
||||
stream->read((char*) &buffer, sizeof(char) * 20);
|
||||
stream->read((char *)&buffer, sizeof(char) * BufferSize);
|
||||
char *pstar = strchr(buffer, '*');
|
||||
if (nullptr == pstar)
|
||||
{
|
||||
if (nullptr == pstar) {
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename.clear();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*pstar = 0;
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename = std::string(pstar + 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
enum class BoneType : uint8_t
|
||||
{
|
||||
enum class BoneType : uint8_t {
|
||||
Rotation,
|
||||
RotationAndMove,
|
||||
IkEffector,
|
||||
|
@ -157,11 +169,10 @@ namespace pmd
|
|||
Invisible,
|
||||
Twist,
|
||||
RotationMovement
|
||||
|
||||
};
|
||||
|
||||
class PmdBone
|
||||
{
|
||||
public:
|
||||
struct PmdBone {
|
||||
std::string name;
|
||||
std::string name_english;
|
||||
uint16_t parent_bone_index;
|
||||
|
@ -170,10 +181,18 @@ namespace pmd
|
|||
uint16_t ik_parent_bone_index;
|
||||
float bone_head_pos[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
PmdBone() :
|
||||
name(), name_english(), parent_bone_index(0), tail_pos_bone_index(0), bone_type(BoneType::Unknown), ik_parent_bone_index(0), bone_head_pos{ 0.0f } {}
|
||||
|
||||
~PmdBone() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
constexpr size_t BufferSize = 20;
|
||||
char buffer[BufferSize] = {};
|
||||
stream->read(buffer, BufferSize);
|
||||
name = std::string(buffer);
|
||||
stream->read((char *)&parent_bone_index, sizeof(uint16_t));
|
||||
stream->read((char *)&tail_pos_bone_index, sizeof(uint16_t));
|
||||
|
@ -182,25 +201,33 @@ namespace pmd
|
|||
stream->read((char *)&bone_head_pos, sizeof(float) * 3);
|
||||
}
|
||||
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
void ReadExpantion(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
constexpr size_t BufferSize = 20;
|
||||
char buffer[BufferSize] = {};
|
||||
stream->read(buffer, BufferSize);
|
||||
name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
class PmdIk
|
||||
{
|
||||
public:
|
||||
struct PmdIk {
|
||||
uint16_t ik_bone_index;
|
||||
uint16_t target_bone_index;
|
||||
uint16_t iterations;
|
||||
float angle_limit;
|
||||
std::vector<uint16_t> ik_child_bone_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdIk() : ik_bone_index(0), target_bone_index(0), iterations(0), angle_limit(0.0f) {}
|
||||
|
||||
~PmdIk() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
stream->read((char *)&ik_bone_index, sizeof(uint16_t));
|
||||
stream->read((char *)&target_bone_index, sizeof(uint16_t));
|
||||
uint8_t ik_chain_length;
|
||||
|
@ -208,28 +235,31 @@ namespace pmd
|
|||
stream->read((char *)&iterations, sizeof(uint16_t));
|
||||
stream->read((char *)&angle_limit, sizeof(float));
|
||||
ik_child_bone_index.resize(ik_chain_length);
|
||||
for (int i = 0; i < ik_chain_length; i++)
|
||||
{
|
||||
for (int i = 0; i < ik_chain_length; i++) {
|
||||
stream->read((char *)&ik_child_bone_index[i], sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PmdFaceVertex
|
||||
{
|
||||
public:
|
||||
struct PmdFaceVertex {
|
||||
int vertex_index;
|
||||
float position[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdFaceVertex() :
|
||||
vertex_index(0), position{ 0.0f } {}
|
||||
|
||||
~PmdFaceVertex() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
stream->read((char *)&vertex_index, sizeof(int));
|
||||
stream->read((char *)position, sizeof(float) * 3);
|
||||
}
|
||||
};
|
||||
|
||||
enum class FaceCategory : uint8_t
|
||||
{
|
||||
enum class FaceCategory : uint8_t {
|
||||
Base,
|
||||
Eyebrow,
|
||||
Eye,
|
||||
|
@ -237,88 +267,105 @@ namespace pmd
|
|||
Other
|
||||
};
|
||||
|
||||
class PmdFace
|
||||
{
|
||||
public:
|
||||
struct PmdFace {
|
||||
std::string name;
|
||||
FaceCategory type;
|
||||
std::vector<PmdFaceVertex> vertices;
|
||||
std::string name_english;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
PmdFace() :
|
||||
name(), type(FaceCategory::Other), vertices(), name_english() {}
|
||||
|
||||
~PmdFace() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
constexpr size_t BufferSize = 20;
|
||||
char buffer[BufferSize];
|
||||
stream->read(buffer, BufferSize);
|
||||
name = std::string(buffer);
|
||||
int vertex_count;
|
||||
stream->read((char *)&vertex_count, sizeof(int));
|
||||
stream->read((char *)&type, sizeof(uint8_t));
|
||||
vertices.resize(vertex_count);
|
||||
for (int i = 0; i < vertex_count; i++)
|
||||
{
|
||||
for (int i = 0; i < vertex_count; i++) {
|
||||
vertices[i].Read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
void ReadExpantion(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
class PmdBoneDispName
|
||||
{
|
||||
public:
|
||||
struct PmdBoneDispName {
|
||||
std::string bone_disp_name;
|
||||
std::string bone_disp_name_english;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdBoneDispName() = default;
|
||||
|
||||
~PmdBoneDispName() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
char buffer[50];
|
||||
stream->read(buffer, 50);
|
||||
bone_disp_name = std::string(buffer);
|
||||
bone_disp_name_english.clear();
|
||||
}
|
||||
void ReadExpantion(std::istream *stream)
|
||||
{
|
||||
|
||||
void ReadExpantion(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
char buffer[50];
|
||||
stream->read(buffer, 50);
|
||||
bone_disp_name_english = std::string(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
class PmdBoneDisp
|
||||
{
|
||||
public:
|
||||
struct PmdBoneDisp {
|
||||
uint16_t bone_index;
|
||||
uint8_t bone_disp_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdBoneDisp() :
|
||||
bone_index(0), bone_disp_index(0) {}
|
||||
|
||||
~PmdBoneDisp() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
stream->read((char *)&bone_index, sizeof(uint16_t));
|
||||
stream->read((char *)&bone_disp_index, sizeof(uint8_t));
|
||||
}
|
||||
};
|
||||
|
||||
enum class RigidBodyShape : uint8_t
|
||||
{
|
||||
enum class RigidBodyShape : uint8_t {
|
||||
Sphere = 0,
|
||||
Box = 1,
|
||||
Cpusel = 2
|
||||
};
|
||||
|
||||
enum class RigidBodyType : uint8_t
|
||||
{
|
||||
enum class RigidBodyType : uint8_t {
|
||||
BoneConnected = 0,
|
||||
Physics = 1,
|
||||
ConnectedPhysics = 2
|
||||
};
|
||||
|
||||
class PmdRigidBody
|
||||
{
|
||||
public:
|
||||
struct PmdRigidBody {
|
||||
std::string name;
|
||||
uint16_t related_bone_index;
|
||||
uint8_t group_index;
|
||||
|
@ -334,8 +381,16 @@ namespace pmd
|
|||
float friction;
|
||||
RigidBodyType rigid_type;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdRigidBody() :
|
||||
name(), related_bone_index(0), group_index(0), mask(0), shape(RigidBodyShape::Box), size{ 0.0f }, position{ 0.0f }, weight(0.0f), linear_damping(0.0f), anglar_damping(0.0f), restitution(0.0f), friction(0.0f), rigid_type(RigidBodyType::BoneConnected) {}
|
||||
|
||||
~PmdRigidBody() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[20];
|
||||
stream->read(buffer, sizeof(char) * 20);
|
||||
name = (std::string(buffer));
|
||||
|
@ -355,9 +410,7 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
class PmdConstraint
|
||||
{
|
||||
public:
|
||||
struct PmdConstraint {
|
||||
std::string name;
|
||||
uint32_t rigid_body_index_a;
|
||||
uint32_t rigid_body_index_b;
|
||||
|
@ -370,8 +423,16 @@ namespace pmd
|
|||
float linear_stiffness[3];
|
||||
float angular_stiffness[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
{
|
||||
PmdConstraint() :
|
||||
name(), rigid_body_index_a(0), rigid_body_index_b(0), position{ 0.0f }, orientation{ 0.0f }, linear_lower_limit{ 0.0f }, linear_upper_limit{ 0.0f }, angular_lower_limit{ 0.0f }, angular_upper_limit{ 0.0f }, linear_stiffness{ 0.0f }, angular_stiffness{ 0.0f } {}
|
||||
|
||||
~PmdConstraint() = default;
|
||||
|
||||
void Read(std::istream *stream) {
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[20];
|
||||
stream->read(buffer, 20);
|
||||
name = std::string(buffer);
|
||||
|
@ -388,9 +449,7 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
class PmdModel
|
||||
{
|
||||
public:
|
||||
struct PmdModel {
|
||||
float version;
|
||||
PmdHeader header;
|
||||
std::vector<PmdVertex> vertices;
|
||||
|
@ -406,11 +465,18 @@ namespace pmd
|
|||
std::vector<PmdRigidBody> rigid_bodies;
|
||||
std::vector<PmdConstraint> constraints;
|
||||
|
||||
static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
|
||||
{
|
||||
PmdModel() :
|
||||
version(0.0f) {}
|
||||
|
||||
~PmdModel() = default;
|
||||
|
||||
static std::unique_ptr<PmdModel> LoadFromFile(const char *filename) {
|
||||
if (filename == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::ifstream stream(filename, std::ios::binary);
|
||||
if (stream.fail())
|
||||
{
|
||||
if (stream.fail()) {
|
||||
std::cerr << "could not open \"" << filename << "\"" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -419,24 +485,21 @@ namespace pmd
|
|||
return result;
|
||||
}
|
||||
|
||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
||||
{
|
||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream) {
|
||||
auto result = mmd::make_unique<PmdModel>();
|
||||
char buffer[100];
|
||||
|
||||
// magic
|
||||
char magic[3];
|
||||
stream->read(magic, 3);
|
||||
if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
|
||||
{
|
||||
if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd') {
|
||||
std::cerr << "invalid file" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// version
|
||||
stream->read((char *)&(result->version), sizeof(float));
|
||||
if (result ->version != 1.0f)
|
||||
{
|
||||
if (result->version != 1.0f) {
|
||||
std::cerr << "invalid version" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -448,8 +511,7 @@ namespace pmd
|
|||
uint32_t vertex_num;
|
||||
stream->read((char *)&vertex_num, sizeof(uint32_t));
|
||||
result->vertices.resize(vertex_num);
|
||||
for (uint32_t i = 0; i < vertex_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < vertex_num; i++) {
|
||||
result->vertices[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -457,8 +519,7 @@ namespace pmd
|
|||
uint32_t index_num;
|
||||
stream->read((char *)&index_num, sizeof(uint32_t));
|
||||
result->indices.resize(index_num);
|
||||
for (uint32_t i = 0; i < index_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < index_num; i++) {
|
||||
stream->read((char *)&result->indices[i], sizeof(uint16_t));
|
||||
}
|
||||
|
||||
|
@ -466,8 +527,7 @@ namespace pmd
|
|||
uint32_t material_num;
|
||||
stream->read((char *)&material_num, sizeof(uint32_t));
|
||||
result->materials.resize(material_num);
|
||||
for (uint32_t i = 0; i < material_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < material_num; i++) {
|
||||
result->materials[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -475,8 +535,7 @@ namespace pmd
|
|||
uint16_t bone_num;
|
||||
stream->read((char *)&bone_num, sizeof(uint16_t));
|
||||
result->bones.resize(bone_num);
|
||||
for (uint32_t i = 0; i < bone_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < bone_num; i++) {
|
||||
result->bones[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -484,8 +543,7 @@ namespace pmd
|
|||
uint16_t ik_num;
|
||||
stream->read((char *)&ik_num, sizeof(uint16_t));
|
||||
result->iks.resize(ik_num);
|
||||
for (uint32_t i = 0; i < ik_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < ik_num; i++) {
|
||||
result->iks[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -493,8 +551,7 @@ namespace pmd
|
|||
uint16_t face_num;
|
||||
stream->read((char *)&face_num, sizeof(uint16_t));
|
||||
result->faces.resize(face_num);
|
||||
for (uint32_t i = 0; i < face_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < face_num; i++) {
|
||||
result->faces[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -502,8 +559,7 @@ namespace pmd
|
|||
uint8_t face_frame_num;
|
||||
stream->read((char *)&face_frame_num, sizeof(uint8_t));
|
||||
result->faces_indices.resize(face_frame_num);
|
||||
for (uint32_t i = 0; i < face_frame_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < face_frame_num; i++) {
|
||||
stream->read((char *)&result->faces_indices[i], sizeof(uint16_t));
|
||||
}
|
||||
|
||||
|
@ -511,8 +567,7 @@ namespace pmd
|
|||
uint8_t bone_disp_num;
|
||||
stream->read((char *)&bone_disp_num, sizeof(uint8_t));
|
||||
result->bone_disp_name.resize(bone_disp_num);
|
||||
for (uint32_t i = 0; i < bone_disp_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < bone_disp_num; i++) {
|
||||
result->bone_disp_name[i].Read(stream);
|
||||
}
|
||||
|
||||
|
@ -520,78 +575,66 @@ namespace pmd
|
|||
uint32_t bone_frame_num;
|
||||
stream->read((char *)&bone_frame_num, sizeof(uint32_t));
|
||||
result->bone_disp.resize(bone_frame_num);
|
||||
for (uint32_t i = 0; i < bone_frame_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < bone_frame_num; i++) {
|
||||
result->bone_disp[i].Read(stream);
|
||||
}
|
||||
|
||||
// english name
|
||||
bool english;
|
||||
stream->read((char *)&english, sizeof(char));
|
||||
if (english)
|
||||
{
|
||||
if (english) {
|
||||
result->header.ReadExtension(stream);
|
||||
for (uint32_t i = 0; i < bone_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < bone_num; i++) {
|
||||
result->bones[i].ReadExpantion(stream);
|
||||
}
|
||||
for (uint32_t i = 0; i < face_num; i++)
|
||||
{
|
||||
if (result->faces[i].type == pmd::FaceCategory::Base)
|
||||
{
|
||||
for (uint32_t i = 0; i < face_num; i++) {
|
||||
if (result->faces[i].type == pmd::FaceCategory::Base) {
|
||||
continue;
|
||||
}
|
||||
result->faces[i].ReadExpantion(stream);
|
||||
}
|
||||
for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < result->bone_disp_name.size(); i++) {
|
||||
result->bone_disp_name[i].ReadExpantion(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// toon textures
|
||||
if (stream->peek() == std::ios::traits_type::eof())
|
||||
{
|
||||
if (stream->peek() == std::ios::traits_type::eof()) {
|
||||
result->toon_filenames.clear();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
result->toon_filenames.resize(10);
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
stream->read(buffer, 100);
|
||||
result->toon_filenames[i] = std::string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// physics
|
||||
if (stream->peek() == std::ios::traits_type::eof())
|
||||
{
|
||||
if (stream->peek() == std::ios::traits_type::eof()) {
|
||||
result->rigid_bodies.clear();
|
||||
result->constraints.clear();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint32_t rigid_body_num;
|
||||
stream->read((char *)&rigid_body_num, sizeof(uint32_t));
|
||||
result->rigid_bodies.resize(rigid_body_num);
|
||||
for (uint32_t i = 0; i < rigid_body_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < rigid_body_num; i++) {
|
||||
result->rigid_bodies[i].Read(stream);
|
||||
}
|
||||
uint32_t constraint_num;
|
||||
stream->read((char *)&constraint_num, sizeof(uint32_t));
|
||||
result->constraints.resize(constraint_num);
|
||||
for (uint32_t i = 0; i < constraint_num; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < constraint_num; i++) {
|
||||
result->constraints[i].Read(stream);
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->peek() != std::ios::traits_type::eof())
|
||||
{
|
||||
if (stream->peek() != std::ios::traits_type::eof()) {
|
||||
std::cerr << "there is unknown data" << std::endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace pmd
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -50,23 +48,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
void Assimp::defaultAiAssertHandler(const char* failedExpression, const char* file, int line)
|
||||
{
|
||||
void Assimp::defaultAiAssertHandler(const char* failedExpression, const char* file, int line) {
|
||||
std::cerr << "ai_assert failure in " << file << "(" << line << "): " << failedExpression << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace {
|
||||
Assimp::AiAssertHandler s_handler = Assimp::defaultAiAssertHandler;
|
||||
}
|
||||
|
||||
void Assimp::setAiAssertHandler(AiAssertHandler handler)
|
||||
{
|
||||
void Assimp::setAiAssertHandler(AiAssertHandler handler) {
|
||||
if (handler != nullptr) {
|
||||
s_handler = handler;
|
||||
} else {
|
||||
s_handler = Assimp::defaultAiAssertHandler;
|
||||
}
|
||||
}
|
||||
|
||||
void Assimp::aiAssertViolation(const char* failedExpression, const char* file, int line)
|
||||
{
|
||||
void Assimp::aiAssertViolation(const char* failedExpression, const char* file, int line) {
|
||||
s_handler(failedExpression, file, line);
|
||||
}
|
||||
|
|
|
@ -47,29 +47,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/defs.h>
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Signature of functions which handle assert violations.
|
||||
/**
|
||||
* @brief Signature of functions which handle assert violations.
|
||||
*/
|
||||
using AiAssertHandler = void (*)(const char* failedExpression, const char* file, int line);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Set the assert handler.
|
||||
/**
|
||||
* @brief Set the assert handler.
|
||||
*/
|
||||
ASSIMP_API void setAiAssertHandler(AiAssertHandler handler);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The assert handler which is set by default.
|
||||
*
|
||||
* This issues a message to stderr and calls abort.
|
||||
* @brief This issues a message to stderr and calls abort.
|
||||
*/
|
||||
ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Dispatches an assert violation to the assert handler.
|
||||
/**
|
||||
* @brief Dispatches an assert violation to the assert handler.
|
||||
*/
|
||||
ASSIMP_API void aiAssertViolation(const char* failedExpression, const char* file, int line);
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // INCLUDED_AI_ASSERTHANDLER_H
|
|
@ -46,7 +46,7 @@ namespace Assimp {
|
|||
|
||||
namespace Base64 {
|
||||
|
||||
static const uint8_t tableDecodeBase64[128] = {
|
||||
static constexpr uint8_t tableDecodeBase64[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
|
@ -57,7 +57,7 @@ static const uint8_t tableDecodeBase64[128] = {
|
|||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char *tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
static constexpr char tableEncodeBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
|
||||
static inline char EncodeChar(uint8_t b) {
|
||||
return tableEncodeBase64[size_t(b)];
|
||||
|
@ -71,6 +71,11 @@ inline uint8_t DecodeChar(char c) {
|
|||
}
|
||||
|
||||
void Encode(const uint8_t *in, size_t inLength, std::string &out) {
|
||||
if (in == nullptr || inLength==0) {
|
||||
out.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t outLength = ((inLength + 2) / 3) * 4;
|
||||
|
||||
size_t j = out.size();
|
||||
|
@ -115,8 +120,14 @@ std::string Encode(const std::vector<uint8_t> &in) {
|
|||
}
|
||||
|
||||
size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
|
||||
if (in == nullptr) {
|
||||
out = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inLength % 4 != 0) {
|
||||
throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)), "\", length:", inLength);
|
||||
throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)),
|
||||
"\", length:", inLength);
|
||||
}
|
||||
|
||||
if (inLength < 4) {
|
||||
|
|
|
@ -232,19 +232,23 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
|||
std::string::size_type pos = pFile.find_last_of('.');
|
||||
|
||||
// no file extension - can't read
|
||||
if (pos == std::string::npos)
|
||||
if (pos == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *ext_real = &pFile[pos + 1];
|
||||
if (!ASSIMP_stricmp(ext_real, ext0))
|
||||
if (!ASSIMP_stricmp(ext_real, ext0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for other, optional, file extensions
|
||||
if (ext1 && !ASSIMP_stricmp(ext_real, ext1))
|
||||
if (ext1 && !ASSIMP_stricmp(ext_real, ext1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ext2 && !ASSIMP_stricmp(ext_real, ext2))
|
||||
if (ext2 && !ASSIMP_stricmp(ext_real, ext2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -66,17 +66,26 @@ BaseProcess::~BaseProcess() {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void BaseProcess::ExecuteOnScene(Importer *pImp) {
|
||||
ai_assert( nullptr != pImp );
|
||||
if (pImp == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ai_assert(nullptr != pImp->Pimpl()->mScene);
|
||||
if (pImp->Pimpl()->mScene == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
progress = pImp->GetProgressHandler();
|
||||
ai_assert(nullptr != progress);
|
||||
if (progress == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetupProperties(pImp);
|
||||
|
||||
// catch exceptions thrown inside the PostProcess-Step
|
||||
try {
|
||||
Execute(pImp->Pimpl()->mScene);
|
||||
|
||||
} catch (const std::exception &err) {
|
||||
|
||||
// extract error description
|
||||
|
|
|
@ -175,18 +175,19 @@ private:
|
|||
* should be executed. If the function returns true, the class' Execute()
|
||||
* function is called subsequently.
|
||||
*/
|
||||
class ASSIMP_API_WINONLY BaseProcess {
|
||||
class ASSIMP_API BaseProcess {
|
||||
friend class Importer;
|
||||
|
||||
public:
|
||||
/** Constructor to be privately used by Importer */
|
||||
/** @brief onstructor to be privately used by Importer */
|
||||
BaseProcess() AI_NO_EXCEPT;
|
||||
|
||||
/** Destructor, private as well */
|
||||
/** @brief Destructor, private as well */
|
||||
virtual ~BaseProcess();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag.
|
||||
/**
|
||||
* @brief Returns whether the processing step is present in the given flag.
|
||||
* @param pFlags The processing flags the importer was called with. A
|
||||
* bitwise combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields,
|
||||
|
@ -200,22 +201,25 @@ public:
|
|||
virtual bool RequireVerboseFormat() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* The function deletes the scene if the postprocess step fails (
|
||||
/**
|
||||
* @brief Executes the post processing step on the given imported data.
|
||||
* The function deletes the scene if the post-process step fails (
|
||||
* the object pointer will be set to nullptr).
|
||||
* @param pImp Importer instance (pImp->mScene must be valid)
|
||||
*/
|
||||
void ExecuteOnScene(Importer *pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called prior to ExecuteOnScene().
|
||||
/**
|
||||
* @brief Called prior to ExecuteOnScene().
|
||||
* The function is a request to the process to update its configuration
|
||||
* basing on the Importer's configuration property list.
|
||||
*/
|
||||
virtual void SetupProperties(const Importer *pImp);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
/**
|
||||
* @brief Executes the post processing step on the given imported data.
|
||||
* A process should throw an ImportErrorException* if it fails.
|
||||
* This method must be implemented by deriving classes.
|
||||
* @param pScene The imported data to work at.
|
||||
|
@ -224,7 +228,7 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
/** Assign a new SharedPostProcessInfo to the step. This object
|
||||
* allows multiple postprocess steps to share data.
|
||||
* allows multiple post-process steps to share data.
|
||||
* @param sh May be nullptr
|
||||
*/
|
||||
inline void SetSharedData(SharedPostProcessInfo *sh) {
|
||||
|
|
|
@ -341,8 +341,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
|
|||
uniqueVertices.push_back(v);
|
||||
if (hasAnimMeshes) {
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
uniqueAnimatedVertices[animMeshIndex].push_back(v);
|
||||
uniqueAnimatedVertices[animMeshIndex].emplace_back(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
}
|
||||
}
|
||||
} else{
|
||||
|
|
|
@ -50,16 +50,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace Base64 {
|
||||
|
||||
/// @brief Will encode the given
|
||||
/// @param in
|
||||
/// @param inLength
|
||||
/// @param out
|
||||
/// @brief Will encode the given character buffer from UTF64 to ASCII
|
||||
/// @param in The UTF-64 buffer.
|
||||
/// @param inLength The size of the buffer
|
||||
/// @param out The encoded ASCII string.
|
||||
void Encode(const uint8_t *in, size_t inLength, std::string &out);
|
||||
|
||||
/// @brief Will encode the given character buffer from UTF64 to ASCII.
|
||||
/// @param in A vector, which contains the buffer for encoding.
|
||||
/// @param out The encoded ASCII string.
|
||||
void Encode(const std::vector<uint8_t>& in, std::string &out);
|
||||
|
||||
/// @brief Will encode the given character buffer from UTF64 to ASCII.
|
||||
/// @param in A vector, which contains the buffer for encoding.
|
||||
/// @return The encoded ASCII string.
|
||||
std::string Encode(const std::vector<uint8_t>& in);
|
||||
|
||||
/// @brief Will decode the given character buffer from ASCII to UTF64.
|
||||
/// @param in The ASCII buffer to decode.
|
||||
/// @param inLength The size of the buffer.
|
||||
/// @param out The decoded buffer.
|
||||
/// @return The new buffer size.
|
||||
size_t Decode(const char *in, size_t inLength, uint8_t *&out);
|
||||
|
||||
/// @brief Will decode the given character buffer from ASCII to UTF64.
|
||||
/// @param in The ASCII buffer to decode as a std::string.
|
||||
/// @param out The decoded buffer.
|
||||
/// @return The new buffer size.
|
||||
size_t Decode(const std::string& in, std::vector<uint8_t>& out);
|
||||
|
||||
/// @brief Will decode the given character buffer from ASCII to UTF64.
|
||||
/// @param in The ASCII string.
|
||||
/// @return The decoded buffer in a vector.
|
||||
std::vector<uint8_t> Decode(const std::string& in);
|
||||
|
||||
} // namespace Base64
|
||||
|
|
|
@ -71,7 +71,6 @@ SET( COMMON
|
|||
unit/AssimpAPITest_aiQuaternion.cpp
|
||||
unit/AssimpAPITest_aiVector2D.cpp
|
||||
unit/AssimpAPITest_aiVector3D.cpp
|
||||
unit/Common/utHash.cpp
|
||||
unit/MathTest.cpp
|
||||
unit/MathTest.h
|
||||
unit/RandomNumberGeneration.h
|
||||
|
@ -98,6 +97,8 @@ SET( COMMON
|
|||
unit/Common/utAssertHandler.cpp
|
||||
unit/Common/utXmlParser.cpp
|
||||
unit/Common/utBase64.cpp
|
||||
unit/Common/utHash.cpp
|
||||
unit/Common/utBaseProcess.cpp
|
||||
)
|
||||
|
||||
SET( IMPORTERS
|
||||
|
|
|
@ -47,14 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace std;
|
||||
using namespace Assimp;
|
||||
|
||||
class Base64Test : public ::testing::Test {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
}
|
||||
};
|
||||
class Base64Test : public ::testing::Test {};
|
||||
|
||||
static const std::vector<uint8_t> assimpStringBinary = { 97, 115, 115, 105, 109, 112 };
|
||||
static const std::string assimpStringEncoded = "YXNzaW1w";
|
||||
|
@ -65,8 +58,24 @@ TEST_F( Base64Test, encodeTest ) {
|
|||
EXPECT_EQ( assimpStringEncoded, Base64::Encode(assimpStringBinary) );
|
||||
}
|
||||
|
||||
TEST_F( Base64Test, encodeTestWithNullptr ) {
|
||||
std::string out;
|
||||
Base64::Encode(nullptr, 100u, out);
|
||||
EXPECT_TRUE(out.empty());
|
||||
|
||||
Base64::Encode(&assimpStringBinary[0], 0u, out);
|
||||
EXPECT_TRUE(out.empty());
|
||||
}
|
||||
|
||||
TEST_F( Base64Test, decodeTest) {
|
||||
EXPECT_EQ( std::vector<uint8_t> {}, Base64::Decode("") );
|
||||
EXPECT_EQ( std::vector<uint8_t> { 86 }, Base64::Decode("Vg==") );
|
||||
EXPECT_EQ( assimpStringBinary, Base64::Decode(assimpStringEncoded) );
|
||||
}
|
||||
|
||||
TEST_F(Base64Test, decodeTestWithNullptr) {
|
||||
uint8_t *out = nullptr;
|
||||
size_t size = Base64::Decode(nullptr, 100u, out);
|
||||
EXPECT_EQ(nullptr, out);
|
||||
EXPECT_EQ(0u, size);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "TestIOSystem.h"
|
||||
#include "UnitTestPCH.h"
|
||||
|
||||
#include "Common/BaseProcess.h"
|
||||
#include "Common/AssertHandler.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
class BaseProcessTest : public ::testing::Test {
|
||||
public:
|
||||
static void test_handler( const char*, const char*, int ) {
|
||||
HandlerWasCalled = true;
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
HandlerWasCalled = false;
|
||||
setAiAssertHandler(test_handler);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
setAiAssertHandler(nullptr);
|
||||
}
|
||||
|
||||
static bool handlerWasCalled() {
|
||||
return HandlerWasCalled;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool HandlerWasCalled;
|
||||
};
|
||||
|
||||
bool BaseProcessTest::HandlerWasCalled = false;
|
||||
|
||||
class TestingBaseProcess : public BaseProcess {
|
||||
public:
|
||||
TestingBaseProcess() : BaseProcess() {
|
||||
// empty
|
||||
}
|
||||
|
||||
~TestingBaseProcess() override = default;
|
||||
|
||||
bool IsActive( unsigned int ) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Execute(aiScene*) override {
|
||||
|
||||
}
|
||||
};
|
||||
TEST_F( BaseProcessTest, constructTest ) {
|
||||
bool ok = true;
|
||||
try {
|
||||
TestingBaseProcess process;
|
||||
} catch (...) {
|
||||
ok = false;
|
||||
}
|
||||
EXPECT_TRUE(ok);
|
||||
}
|
||||
|
||||
TEST_F( BaseProcessTest, executeOnSceneTest ) {
|
||||
TestingBaseProcess process;
|
||||
process.ExecuteOnScene(nullptr);
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
EXPECT_TRUE(BaseProcessTest::handlerWasCalled());
|
||||
#else
|
||||
EXPECT_FALSE(BaseProcessTest::handlerWasCalled());
|
||||
#endif
|
||||
|
||||
}
|
Loading…
Reference in New Issue