summaryrefslogtreecommitdiff
path: root/libs/assimp/code/AssetLib/MMD/MMDPmdParser.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/assimp/code/AssetLib/MMD/MMDPmdParser.h')
-rw-r--r--libs/assimp/code/AssetLib/MMD/MMDPmdParser.h597
1 files changed, 597 insertions, 0 deletions
diff --git a/libs/assimp/code/AssetLib/MMD/MMDPmdParser.h b/libs/assimp/code/AssetLib/MMD/MMDPmdParser.h
new file mode 100644
index 0000000..35e4f09
--- /dev/null
+++ b/libs/assimp/code/AssetLib/MMD/MMDPmdParser.h
@@ -0,0 +1,597 @@
+/*
+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.
+
+----------------------------------------------------------------------
+*/
+#pragma once
+
+#include <vector>
+#include <string>
+#include <memory>
+#include <iostream>
+#include <fstream>
+#include "MMDCpp14.h"
+
+namespace pmd
+{
+ class PmdHeader
+ {
+ public:
+ std::string name;
+ std::string name_english;
+ std::string comment;
+ std::string comment_english;
+
+ bool Read(std::ifstream* stream)
+ {
+ char buffer[256];
+ stream->read(buffer, 20);
+ name = std::string(buffer);
+ stream->read(buffer, 256);
+ comment = std::string(buffer);
+ return true;
+ }
+
+ bool ReadExtension(std::ifstream* stream)
+ {
+ 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:
+ 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)
+ {
+ stream->read((char*) position, sizeof(float) * 3);
+ stream->read((char*) normal, sizeof(float) * 3);
+ stream->read((char*) uv, sizeof(float) * 2);
+ stream->read((char*) bone_index, sizeof(uint16_t) * 2);
+ stream->read((char*) &bone_weight, sizeof(uint8_t));
+ stream->read((char*) &edge_invisible, sizeof(uint8_t));
+ return true;
+ }
+ };
+
+ class PmdMaterial
+ {
+ public:
+ float diffuse[4];
+ float power;
+ float specular[3];
+ float ambient[3];
+ uint8_t toon_index;
+ uint8_t edge_flag;
+ uint32_t index_count;
+ std::string texture_filename;
+ std::string sphere_filename;
+
+ bool Read(std::ifstream* stream)
+ {
+ char buffer[20];
+ stream->read((char*) &diffuse, sizeof(float) * 4);
+ stream->read((char*) &power, sizeof(float));
+ stream->read((char*) &specular, sizeof(float) * 3);
+ stream->read((char*) &ambient, sizeof(float) * 3);
+ 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);
+ char* pstar = strchr(buffer, '*');
+ if (nullptr == pstar)
+ {
+ texture_filename = std::string(buffer);
+ sphere_filename.clear();
+ }
+ else {
+ *pstar = 0;
+ texture_filename = std::string(buffer);
+ sphere_filename = std::string(pstar+1);
+ }
+ return true;
+ }
+ };
+
+ enum class BoneType : uint8_t
+ {
+ Rotation,
+ RotationAndMove,
+ IkEffector,
+ Unknown,
+ IkEffectable,
+ RotationEffectable,
+ IkTarget,
+ Invisible,
+ Twist,
+ RotationMovement
+ };
+
+ class PmdBone
+ {
+ public:
+ std::string name;
+ std::string name_english;
+ uint16_t parent_bone_index;
+ uint16_t tail_pos_bone_index;
+ BoneType bone_type;
+ uint16_t ik_parent_bone_index;
+ float bone_head_pos[3];
+
+ void Read(std::istream *stream)
+ {
+ char buffer[20];
+ stream->read(buffer, 20);
+ name = std::string(buffer);
+ stream->read((char*) &parent_bone_index, sizeof(uint16_t));
+ stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
+ stream->read((char*) &bone_type, sizeof(uint8_t));
+ stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
+ stream->read((char*) &bone_head_pos, sizeof(float) * 3);
+ }
+
+ void ReadExpantion(std::istream *stream)
+ {
+ char buffer[20];
+ stream->read(buffer, 20);
+ name_english = std::string(buffer);
+ }
+ };
+
+ class PmdIk
+ {
+ public:
+ 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)
+ {
+ stream->read((char *) &ik_bone_index, sizeof(uint16_t));
+ stream->read((char *) &target_bone_index, sizeof(uint16_t));
+ uint8_t ik_chain_length;
+ stream->read((char*) &ik_chain_length, sizeof(uint8_t));
+ 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++)
+ {
+ stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
+ }
+ }
+ };
+
+ class PmdFaceVertex
+ {
+ public:
+ int vertex_index;
+ float position[3];
+
+ void Read(std::istream *stream)
+ {
+ stream->read((char *) &vertex_index, sizeof(int));
+ stream->read((char *) position, sizeof(float) * 3);
+ }
+ };
+
+ enum class FaceCategory : uint8_t
+ {
+ Base,
+ Eyebrow,
+ Eye,
+ Mouth,
+ Other
+ };
+
+ class PmdFace
+ {
+ public:
+ 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);
+ 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++)
+ {
+ vertices[i].Read(stream);
+ }
+ }
+
+ void ReadExpantion(std::istream *stream)
+ {
+ char buffer[20];
+ stream->read(buffer, 20);
+ name_english = std::string(buffer);
+ }
+ };
+
+ class PmdBoneDispName
+ {
+ public:
+ std::string bone_disp_name;
+ std::string bone_disp_name_english;
+
+ void Read(std::istream *stream)
+ {
+ char buffer[50];
+ stream->read(buffer, 50);
+ bone_disp_name = std::string(buffer);
+ bone_disp_name_english.clear();
+ }
+ void ReadExpantion(std::istream *stream)
+ {
+ char buffer[50];
+ stream->read(buffer, 50);
+ bone_disp_name_english = std::string(buffer);
+ }
+ };
+
+ class PmdBoneDisp
+ {
+ public:
+ uint16_t bone_index;
+ uint8_t bone_disp_index;
+
+ void Read(std::istream *stream)
+ {
+ stream->read((char*) &bone_index, sizeof(uint16_t));
+ stream->read((char*) &bone_disp_index, sizeof(uint8_t));
+ }
+ };
+
+ enum class RigidBodyShape : uint8_t
+ {
+ Sphere = 0,
+ Box = 1,
+ Cpusel = 2
+ };
+
+ enum class RigidBodyType : uint8_t
+ {
+ BoneConnected = 0,
+ Physics = 1,
+ ConnectedPhysics = 2
+ };
+
+ class PmdRigidBody
+ {
+ public:
+ std::string name;
+ uint16_t related_bone_index;
+ uint8_t group_index;
+ uint16_t mask;
+ RigidBodyShape shape;
+ float size[3];
+ float position[3];
+ float orientation[3];
+ float weight;
+ float linear_damping;
+ float anglar_damping;
+ float restitution;
+ float friction;
+ RigidBodyType rigid_type;
+
+ void Read(std::istream *stream)
+ {
+ char buffer[20];
+ stream->read(buffer, sizeof(char) * 20);
+ name = (std::string(buffer));
+ stream->read((char*) &related_bone_index, sizeof(uint16_t));
+ stream->read((char*) &group_index, sizeof(uint8_t));
+ stream->read((char*) &mask, sizeof(uint16_t));
+ stream->read((char*) &shape, sizeof(uint8_t));
+ stream->read((char*) size, sizeof(float) * 3);
+ stream->read((char*) position, sizeof(float) * 3);
+ stream->read((char*) orientation, sizeof(float) * 3);
+ stream->read((char*) &weight, sizeof(float));
+ stream->read((char*) &linear_damping, sizeof(float));
+ stream->read((char*) &anglar_damping, sizeof(float));
+ stream->read((char*) &restitution, sizeof(float));
+ stream->read((char*) &friction, sizeof(float));
+ stream->read((char*) &rigid_type, sizeof(char));
+ }
+ };
+
+ class PmdConstraint
+ {
+ public:
+ std::string name;
+ uint32_t rigid_body_index_a;
+ uint32_t rigid_body_index_b;
+ float position[3];
+ float orientation[3];
+ float linear_lower_limit[3];
+ float linear_upper_limit[3];
+ float angular_lower_limit[3];
+ float angular_upper_limit[3];
+ float linear_stiffness[3];
+ float angular_stiffness[3];
+
+ void Read(std::istream *stream)
+ {
+ char buffer[20];
+ stream->read(buffer, 20);
+ name = std::string(buffer);
+ stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
+ stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
+ stream->read((char *) position, sizeof(float) * 3);
+ stream->read((char *) orientation, sizeof(float) * 3);
+ stream->read((char *) linear_lower_limit, sizeof(float) * 3);
+ stream->read((char *) linear_upper_limit, sizeof(float) * 3);
+ stream->read((char *) angular_lower_limit, sizeof(float) * 3);
+ stream->read((char *) angular_upper_limit, sizeof(float) * 3);
+ stream->read((char *) linear_stiffness, sizeof(float) * 3);
+ stream->read((char *) angular_stiffness, sizeof(float) * 3);
+ }
+ };
+
+ class PmdModel
+ {
+ public:
+ float version;
+ PmdHeader header;
+ std::vector<PmdVertex> vertices;
+ std::vector<uint16_t> indices;
+ std::vector<PmdMaterial> materials;
+ std::vector<PmdBone> bones;
+ std::vector<PmdIk> iks;
+ std::vector<PmdFace> faces;
+ std::vector<uint16_t> faces_indices;
+ std::vector<PmdBoneDispName> bone_disp_name;
+ std::vector<PmdBoneDisp> bone_disp;
+ std::vector<std::string> toon_filenames;
+ std::vector<PmdRigidBody> rigid_bodies;
+ std::vector<PmdConstraint> constraints;
+
+ static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
+ {
+ std::ifstream stream(filename, std::ios::binary);
+ if (stream.fail())
+ {
+ std::cerr << "could not open \"" << filename << "\"" << std::endl;
+ return nullptr;
+ }
+ auto result = LoadFromStream(&stream);
+ stream.close();
+ return result;
+ }
+
+ 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')
+ {
+ std::cerr << "invalid file" << std::endl;
+ return nullptr;
+ }
+
+ // version
+ stream->read((char*) &(result->version), sizeof(float));
+ if (result ->version != 1.0f)
+ {
+ std::cerr << "invalid version" << std::endl;
+ return nullptr;
+ }
+
+ // header
+ result->header.Read(stream);
+
+ // vertices
+ 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++)
+ {
+ result->vertices[i].Read(stream);
+ }
+
+ // indices
+ 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++)
+ {
+ stream->read((char*) &result->indices[i], sizeof(uint16_t));
+ }
+
+ // materials
+ 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++)
+ {
+ result->materials[i].Read(stream);
+ }
+
+ // bones
+ 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++)
+ {
+ result->bones[i].Read(stream);
+ }
+
+ // iks
+ 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++)
+ {
+ result->iks[i].Read(stream);
+ }
+
+ // faces
+ 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++)
+ {
+ result->faces[i].Read(stream);
+ }
+
+ // face frames
+ 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++)
+ {
+ stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
+ }
+
+ // bone names
+ 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++)
+ {
+ result->bone_disp_name[i].Read(stream);
+ }
+
+ // bone frame
+ 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++)
+ {
+ result->bone_disp[i].Read(stream);
+ }
+
+ // english name
+ bool english;
+ stream->read((char*) &english, sizeof(char));
+ if (english)
+ {
+ result->header.ReadExtension(stream);
+ 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)
+ {
+ continue;
+ }
+ result->faces[i].ReadExpantion(stream);
+ }
+ 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())
+ {
+ result->toon_filenames.clear();
+ }
+ else {
+ result->toon_filenames.resize(10);
+ 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())
+ {
+ result->rigid_bodies.clear();
+ result->constraints.clear();
+ }
+ 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++)
+ {
+ 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++)
+ {
+ result->constraints[i].Read(stream);
+ }
+ }
+
+ if (stream->peek() != std::ios::traits_type::eof())
+ {
+ std::cerr << "there is unknown data" << std::endl;
+ }
+
+ return result;
+ }
+ };
+}