+++ /dev/null
--- A project defines one build target
-project "meshio"
---kind "WindowedApp"
---kind "ConsoleApp"
---kind "SharedLib"
-kind "StaticLib"
-language "C++"
-files { "include/*.h", "src/**.h", "src/**.cpp" }
-flags {
- --"Unicode",
- "StaticRuntime",
-}
-
-includedirs {
- "include", "boost",
-}
-defines {}
-linkoptions {}
-libdirs {}
-links {}
-
-configuration { "windows", "not gmake" }
-do
- -- VC
- buildoptions {
- "/wd4996",
- }
-end
-
-configuration { "gmake" }
-do
- buildoptions {
- "-fPIC"
- }
-end
-
-configuration "Debug"
-do
- defines { "DEBUG" }
- flags { "Symbols" }
- targetdir "debug"
-end
-
-configuration "Release"
-do
- defines { "NDEBUG" }
- flags { "Optimize" }
- targetdir "release"
-end
-
+++ /dev/null
--- A solution contains projects, and defines the available configurations
-solution "meshio"
-configurations { "Debug", "Release" }
-
-dofile "meshio.lua"
-
#include "binary.h"
namespace meshio {
-namespace binary {
-
-///////////////////////////////////////////////////////////////////////////////
-// FileReader
-///////////////////////////////////////////////////////////////////////////////
-FileReader::FileReader(const char *path)
-: io_(path, std::ios::binary), pos_(0), eof_(false)
-{
-}
-
-FileReader::~FileReader()
-{
-}
-
-unsigned int FileReader::read(char *buf, unsigned int size)
-{
- if(size==0){
- return 0;
- }
- io_.read(buf, size);
- size=io_.gcount();
- if(size==0){
- eof_=true;
- }
- pos_+=size;
- return size;
-}
-
-unsigned int FileReader::getPos()const
-{
- return pos_;
-}
-
-bool FileReader::isEnd()const
-{
- return eof_;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// MemoryReader
-///////////////////////////////////////////////////////////////////////////////
-MemoryReader::MemoryReader(const char *buf, unsigned int size)
-: buf_(buf), size_(size), pos_(0)
-{
-}
-
-MemoryReader::~MemoryReader()
-{
-}
-
-unsigned int MemoryReader::read(char *buf, unsigned int size)
-{
- if(pos_+size>=size_){
- size=size_-pos_;
- }
- std::copy(&buf_[pos_], &buf_[pos_+size], buf);
- pos_+=size;
- return size;
-}
-
-unsigned int MemoryReader::getPos()const
-{
- return pos_;
-}
-
-bool MemoryReader::isEnd()const
-{
- return pos_>=size_;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// readALL
-///////////////////////////////////////////////////////////////////////////////
-static void readALL_(FILE *fp, std::vector<char> &buf)
-{
- int iRet = fseek(fp, 0L, SEEK_END);
- if(iRet!=0){
- return;
- }
-
- long pos=ftell(fp);
- if(pos == -1){
- return;
- }
-
- iRet = fseek(fp, 0L, SEEK_SET);
- if(iRet != 0){
- return;
- }
-
- buf.resize(pos);
- iRet=fread(&buf[0], pos, 1, fp);
-}
-
-void readAll(const char *path, std::vector<char> &buf)
-{
- FILE* fp = fopen(path, "rb");
- if(fp){
- readALL_(fp, buf);
- fclose(fp);
- }
-}
+ namespace binary {
+
+ // FileReader
+ FileReader::FileReader(const char *path)
+ : io_(path, std::ios::binary), pos_(0), eof_(false)
+ {
+ }
+
+ FileReader::~FileReader()
+ {
+ }
+
+ unsigned int FileReader::read(char *buf, unsigned int size)
+ {
+ if(size==0){
+ return 0;
+ }
+ io_.read(buf, size);
+ size=io_.gcount();
+ if(size==0){
+ eof_=true;
+ }
+ pos_+=size;
+ return size;
+ }
+
+ unsigned int FileReader::getPos()const
+ {
+ return pos_;
+ }
+
+ bool FileReader::isEnd()const
+ {
+ return eof_;
+ }
+
+ // MemoryReader
+ MemoryReader::MemoryReader(const char *buf, unsigned int size)
+ : buf_(buf), size_(size), pos_(0)
+ {
+ }
+
+ MemoryReader::~MemoryReader()
+ {
+ }
+
+ unsigned int MemoryReader::read(char *buf, unsigned int size)
+ {
+ if(pos_+size>=size_){
+ size=size_-pos_;
+ }
+ std::copy(&buf_[pos_], &buf_[pos_+size], buf);
+ pos_+=size;
+ return size;
+ }
+
+ unsigned int MemoryReader::getPos()const
+ {
+ return pos_;
+ }
+
+ bool MemoryReader::isEnd()const
+ {
+ return pos_>=size_;
+ }
+
+ // readALL
+ static void readALL_(FILE *fp, std::vector<char> &buf)
+ {
+ int iRet = fseek(fp, 0L, SEEK_END);
+ if(iRet!=0){
+ return;
+ }
+
+ long pos=ftell(fp);
+ if(pos == -1){
+ return;
+ }
+
+ iRet = fseek(fp, 0L, SEEK_SET);
+ if(iRet != 0){
+ return;
+ }
+
+ buf.resize(pos);
+ iRet=fread(&buf[0], pos, 1, fp);
+ }
+
+ void readAll(const char *path, std::vector<char> &buf)
+ {
+ FILE* fp = fopen(path, "rb");
+ if(fp){
+ readALL_(fp, buf);
+ fclose(fp);
+ }
+ }
#ifdef _WIN32
-void readAll(const wchar_t *path, std::vector<char> &buf)
-{
- FILE* fp = _wfopen(path, L"rb");
- if(fp){
- readALL_(fp, buf);
- fclose(fp);
- }
-}
+ void readAll(const wchar_t *path, std::vector<char> &buf)
+ {
+ FILE* fp = _wfopen(path, L"rb");
+ if(fp){
+ readALL_(fp, buf);
+ fclose(fp);
+ }
+ }
#endif
-///////////////////////////////////////////////////////////////////////////////
-// FileWriter
-///////////////////////////////////////////////////////////////////////////////
-FileWriter::FileWriter(const char *path)
-{
- io_=fopen(path, "wb");
-}
+ // FileWriter
+ FileWriter::FileWriter(const char *path)
+ {
+ io_=fopen(path, "wb");
+ }
#if _WIN32
-FileWriter::FileWriter(const wchar_t *path)
-{
- io_=_wfopen(path, L"wb");
-}
+ FileWriter::FileWriter(const wchar_t *path)
+ {
+ io_=_wfopen(path, L"wb");
+ }
#endif
-FileWriter::~FileWriter()
-{
- fclose(io_);
-}
+ FileWriter::~FileWriter()
+ {
+ fclose(io_);
+ }
-void FileWriter::write(const char *buf, unsigned int size)
-{
- fwrite(buf, size, 1, io_);
-}
+ void FileWriter::write(const char *buf, unsigned int size)
+ {
+ fwrite(buf, size, 1, io_);
+ }
-} // namespace binary
+ } // namespace binary
} // namespace meshio
+/**
+ * \83o\83C\83i\83\8a\83t\83@\83C\83\8b\82Ì\93Ç\82Ý\8d\9e\82Ý\95â\8f\95\83\89\83C\83u\83\89\83\8a
+ */
#ifndef MESH_IO_BINARY_H_INCLUDED
#define MESH_IO_BINARY_H_INCLUDED
+#include "text.h"
#include <fstream>
#include <vector>
#include <assert.h>
#include <string.h>
namespace meshio {
-namespace binary {
+ namespace binary {
-/**
- * \83f\81[\83^\93Ç\82Ý\8d\9e\82Ý\83C\83\93\83^\81[\83t\83F\81[\83X
- */
-class IReader
-{
-public:
- virtual ~IReader(){}
- virtual unsigned int read(char *buf, unsigned int size)=0;
- virtual unsigned int getPos()const=0;
- virtual bool isEnd()const=0;
-
- template<typename T>
- bool get(T &t)
- {
- if(read(reinterpret_cast<char*>(&t), sizeof(t))){
- return true;
- }
- else{
- return false;
- }
- }
- char getChar()
- {
- char byte;
- return get(byte) ? byte : 0;
- }
- std::string getString(unsigned int length, bool isTrim=false)
- {
- std::vector<char> buf(length);
- read(&buf[0], buf.size());
-
- std::vector<char>::iterator it;
- if(isTrim){
- it=buf.begin();
- for(; it!=buf.end(); ++it){
- if(*it=='\0'){
- break;
- }
- }
- }
- else{
- it=buf.end();
- }
- return std::string(buf.begin(), it);
- }
- unsigned char getUchar()
- {
- unsigned char value;
- return get(value) ? value : 0;
- }
- unsigned short getUshort()
- {
- unsigned short value;
- return get(value) ? value : 0;
- }
- unsigned int getUint()
- {
- unsigned int value;
- return get(value) ? value : 0;
- }
-};
+ static void copyStringAndFillZero(char *dst, const std::string &src)
+ {
+ size_t i=0;
+ for(; i<src.size(); ++i)
+ {
+ dst[i]=src[i];
+ if(src[i]=='\0'){
+ break;
+ }
+ }
+ for(; i<src.size(); ++i)
+ {
+ dst[i]='\0';
+ }
+ }
-/**
- * \83t\83@\83C\83\8b\82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý
- */
-class FileReader : public IReader
-{
- std::ifstream io_;
- unsigned int pos_;
- bool eof_;
-
-public:
- FileReader(const char *path);
- virtual ~FileReader();
- virtual unsigned int read(char *buf, unsigned int size);
- virtual unsigned int getPos()const;
- virtual bool isEnd()const;
-};
+ /**
+ * \83f\81[\83^\93Ç\82Ý\8d\9e\82Ý\83C\83\93\83^\81[\83t\83F\81[\83X
+ */
+ class IReader
+ {
+ public:
+ virtual ~IReader(){}
+ virtual unsigned int read(char *buf, unsigned int size)=0;
+ virtual unsigned int getPos()const=0;
+ virtual bool isEnd()const=0;
-/**
- * \83\81\83\82\83\8a\82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý
- */
-class MemoryReader : public IReader
-{
- const char *buf_;
- unsigned int size_;
- unsigned int pos_;
-
-public:
- MemoryReader(const char *buf, unsigned int size);
- virtual ~MemoryReader();
- virtual unsigned int read(char *buf, unsigned int size);
- virtual unsigned int getPos()const;
- virtual bool isEnd()const;
-};
-
- void readAll(const char *path, std::vector<char> &all);
+ template<typename T>
+ bool get(T &t)
+ {
+ if(read(reinterpret_cast<char*>(&t), sizeof(t))){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+ template<int LENGTH>
+ bool get(fixed_string<LENGTH> &t)
+ {
+ copyStringAndFillZero(t.begin(), getString(t.size()));
+ return true;
+ }
+ char getChar()
+ {
+ char byte;
+ return get(byte) ? byte : 0;
+ }
+ std::string getString(unsigned int length, bool isTrim=false)
+ {
+ std::vector<char> buf(length);
+ read(&buf[0], buf.size());
+
+ std::vector<char>::iterator it;
+ if(isTrim){
+ it=buf.begin();
+ for(; it!=buf.end(); ++it){
+ if(*it=='\0'){
+ break;
+ }
+ }
+ }
+ else{
+ it=buf.end();
+ }
+ return std::string(buf.begin(), it);
+ }
+ unsigned char getUchar()
+ {
+ unsigned char value;
+ return get(value) ? value : 0;
+ }
+ unsigned short getUshort()
+ {
+ unsigned short value;
+ return get(value) ? value : 0;
+ }
+ unsigned int getUint()
+ {
+ unsigned int value;
+ return get(value) ? value : 0;
+ }
+ };
+
+ /**
+ * \83t\83@\83C\83\8b\82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý
+ */
+ class FileReader : public IReader
+ {
+ std::ifstream io_;
+ unsigned int pos_;
+ bool eof_;
+
+ public:
+ FileReader(const char *path);
+ virtual ~FileReader();
+ virtual unsigned int read(char *buf, unsigned int size);
+ virtual unsigned int getPos()const;
+ virtual bool isEnd()const;
+ };
+
+ /**
+ * \83\81\83\82\83\8a\82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý
+ */
+ class MemoryReader : public IReader
+ {
+ const char *buf_;
+ unsigned int size_;
+ unsigned int pos_;
+
+ public:
+ MemoryReader(const char *buf, unsigned int size);
+ virtual ~MemoryReader();
+ virtual unsigned int read(char *buf, unsigned int size);
+ virtual unsigned int getPos()const;
+ virtual bool isEnd()const;
+ };
+
+ void readAll(const char *path, std::vector<char> &all);
#ifdef _WIN32
- void readAll(const wchar_t *path, std::vector<char> &all);
+ void readAll(const wchar_t *path, std::vector<char> &all);
#endif
-/**
- * \83f\81[\83^\8f\91\82«\8d\9e\82Ý\83C\83\93\83^\81[\83t\83F\81[\83X
- */
-class IWriter
-{
-public:
- virtual ~IWriter(){}
- virtual void write(const char *buf, unsigned int size)=0;
- void printLn(const char *fmt, ...)
- {
- char buf[1024];
- va_list list;
- va_start(list, fmt);
- vsprintf(buf, fmt, list);
- write(buf, strlen(buf));
- write("\r\n", 2);
- va_end(list);
- }
- template<typename T>
- void writeArray(const T *array, size_t element_count)
- {
- write(
- reinterpret_cast<const char*>(array),
- sizeof(T)*element_count);
- }
- template<typename T>
- void writeValue(T value)
- {
- writeArray(&value, 1);
- }
-};
-
-class FileWriter : public IWriter
-{
- FILE *io_;
-
-public:
- FileWriter(const char *path);
- FileWriter(const wchar_t *path);
- virtual ~FileWriter();
- virtual void write(const char *buf, unsigned int size);
-};
-
-} // namespace binary
+ /**
+ * \83f\81[\83^\8f\91\82«\8d\9e\82Ý\83C\83\93\83^\81[\83t\83F\81[\83X
+ */
+ class IWriter
+ {
+ public:
+ virtual ~IWriter(){}
+ virtual void write(const char *buf, unsigned int size)=0;
+ void printLn(const char *fmt, ...)
+ {
+ char buf[1024];
+ va_list list;
+ va_start(list, fmt);
+ vsprintf(buf, fmt, list);
+ write(buf, strlen(buf));
+ write("\r\n", 2);
+ va_end(list);
+ }
+ template<int LENGTH>
+ void write(const fixed_string<LENGTH> &src)
+ {
+ write(
+ reinterpret_cast<const char*>(src.begin()),
+ src.size());
+ }
+ template<typename T>
+ void writeArray(const T *array, size_t element_count)
+ {
+ write(
+ reinterpret_cast<const char*>(array),
+ sizeof(T)*element_count);
+ }
+ template<typename T>
+ void writeValue(T value)
+ {
+ writeArray(&value, 1);
+ }
+ };
+
+ class FileWriter : public IWriter
+ {
+ FILE *io_;
+
+ public:
+ FileWriter(const char *path);
+ FileWriter(const wchar_t *path);
+ virtual ~FileWriter();
+ virtual void write(const char *buf, unsigned int size);
+ };
+
+ } // namespace binary
} // namespace meshio
#endif // MESH_IO_BINARY_H_INCLUDED
+/**
+ * Color
+ */
#ifndef MESH_IO_COLOR_H_INCLUDED
#define MESH_IO_COLOR_H_INCLUDED
namespace meshio {
-namespace color {
-//! Byte\95Û\8e\9d\82ÌGBA
-struct bRGBA
-{
- int r;
- int g;
- int b;
- int a;
+ struct bRGBA
+ {
+ int r;
+ int g;
+ int b;
+ int a;
- bRGBA()
- {}
+ bRGBA()
+ {}
- bRGBA(int _r, int _g, int _b, int _a)
- : r(_r), g(_g), b(_b), a(_a)
- {}
+ bRGBA(int _r, int _g, int _b, int _a)
+ : r(_r), g(_g), b(_b), a(_a)
+ {}
- static bRGBA createFromUInt(unsigned int uint)
- {
- return bRGBA(
- uint & 0x000000FF,
- uint & 0x0000FF00 >> 8,
- uint & 0x00FF0000 >> 16,
- uint & 0xFF000000 >> 24
- );
- }
-};
+ static bRGBA createFromUInt(unsigned int uint)
+ {
+ return bRGBA(
+ uint & 0x000000FF,
+ uint & 0x0000FF00 >> 8,
+ uint & 0x00FF0000 >> 16,
+ uint & 0xFF000000 >> 24
+ );
+ }
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const bRGBA &rhs)
-{
- return os
- << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << rhs.a << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const bRGBA &rhs)
+ {
+ return os
+ << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << rhs.a << ']';
+ }
#endif
-//! Float\95Û\8e\9d\82ÌRGBA
-struct fRGBA
-{
- float r;
- float g;
- float b;
- float a;
+ //! Float RGBA
+ struct fRGBA
+ {
+ float r;
+ float g;
+ float b;
+ float a;
- fRGBA()
- {}
+ fRGBA()
+ {}
- fRGBA(float _r, float _g, float _b, float _a)
- : r(_r), g(_g), b(_b), a(_a)
- {}
+ fRGBA(float _r, float _g, float _b, float _a)
+ : r(_r), g(_g), b(_b), a(_a)
+ {}
- static fRGBA createFromUInt(unsigned int uint)
- {
- return fRGBA(
- (uint & 0x000000FF) / 255.0f,
- (uint & 0x0000FF00 >> 8) / 255.0f,
- (uint & 0x00FF0000 >> 16) / 255.0f,
- (uint & 0xFF000000 >> 24) / 255.0f
- );
- }
-};
+ static fRGBA createFromUInt(unsigned int uint)
+ {
+ return fRGBA(
+ (uint & 0x000000FF) / 255.0f,
+ (uint & 0x0000FF00 >> 8) / 255.0f,
+ (uint & 0x00FF0000 >> 16) / 255.0f,
+ (uint & 0xFF000000 >> 24) / 255.0f
+ );
+ }
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const fRGBA &rhs)
-{
- return os
- << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << rhs.a << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const fRGBA &rhs)
+ {
+ return os
+ << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << rhs.a << ']';
+ }
#endif
-//! Float\95Û\8e\9d\82ÌRGB
-struct fRGB
-{
- float r;
- float g;
- float b;
-};
+ //! Float RGB
+ struct fRGB
+ {
+ float r;
+ float g;
+ float b;
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const fRGB &rhs)
-{
- return os
- << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const fRGB &rhs)
+ {
+ return os
+ << '[' << rhs.r << ',' << rhs.g << ',' << rhs.b << ',' << ']';
+ }
#endif
-} // namespace color
} // namespace meshio
#endif // MESH_IO_COLOR_H_INCLUDED
+/**
+ * Linear Algebra
+ */
#ifndef MESH_IO_LA_H_INCLUDED
#define MESH_IO_LA_H_INCLUDED
#include <ostream>
namespace meshio {
-namespace la {
-/**
- * \e$B@~7ABe?t\e(B(Linear Algebra)
- */
-
-struct Vector2
-{
- float x;
- float y;
-
- Vector2()
- {}
-
- Vector2(float _x, float _y)
- : x(_x), y(_y)
- {}
-};
+ struct Vector2
+ {
+ float x;
+ float y;
+
+ Vector2()
+ {}
+
+ Vector2(float _x, float _y)
+ : x(_x), y(_y)
+ {}
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const Vector2 &rhs)
-{
- return os
- << '[' << rhs.x << ',' << rhs.y << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const Vector2 &rhs)
+ {
+ return os
+ << '[' << rhs.x << ',' << rhs.y << ']';
+ }
#endif
-
-struct Vector3
-{
- float x;
- float y;
- float z;
-
- Vector3()
- {}
-
- Vector3(float _x, float _y, float _z)
- : x(_x), y(_y), z(_z)
- {}
-
- bool operator==(const Vector3 &rhs)const
- {
- return x==rhs.x && y==rhs.y && z==rhs.z;
- }
-
- Vector3 operator+(const Vector3 &rhs)
- {
- return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
- }
-
- Vector3 operator-(const Vector3 &rhs)
- {
- return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
- }
-};
+ struct Vector3
+ {
+ float x;
+ float y;
+ float z;
+
+ Vector3()
+ {}
+
+ Vector3(float _x, float _y, float _z)
+ : x(_x), y(_y), z(_z)
+ {}
+
+ bool operator==(const Vector3 &rhs)const
+ {
+ return x==rhs.x && y==rhs.y && z==rhs.z;
+ }
+
+ Vector3 operator+(const Vector3 &rhs)
+ {
+ return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
+ }
+
+ Vector3 operator-(const Vector3 &rhs)
+ {
+ return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
+ }
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const Vector3 &rhs)
-{
- return os
- << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const Vector3 &rhs)
+ {
+ return os
+ << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ']';
+ }
#endif
-struct Vector4
-{
- float x;
- float y;
- float z;
- float w;
+ struct Vector4
+ {
+ float x;
+ float y;
+ float z;
+ float w;
- Vector4()
- {}
+ Vector4()
+ {}
- Vector4(float _x, float _y, float _z, float _w)
- : x(_x), y(_y), z(_z), w(_w)
- {}
-};
+ Vector4(float _x, float _y, float _z, float _w)
+ : x(_x), y(_y), z(_z), w(_w)
+ {}
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const Vector4 &rhs)
-{
- return os
- << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ',' << rhs.w << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const Vector4 &rhs)
+ {
+ return os
+ << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ',' << rhs.w << ']';
+ }
#endif
-struct Quaternion
-{
- float x;
- float y;
- float z;
- float w;
+ struct Quaternion
+ {
+ float x;
+ float y;
+ float z;
+ float w;
- Quaternion()
- {}
+ Quaternion()
+ {}
- Quaternion(float _x, float _y, float _z, float _w)
- : x(_x), y(_y), z(_z), w(_w)
- {}
+ Quaternion(float _x, float _y, float _z, float _w)
+ : x(_x), y(_y), z(_z), w(_w)
+ {}
- float dot(const Quaternion &rhs)
- {
- return x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w;
- }
-};
+ float dot(const Quaternion &rhs)
+ {
+ return x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w;
+ }
+ };
#ifndef SWIG
-inline std::ostream &operator<<(std::ostream &os, const Quaternion &rhs)
-{
- return os
- << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ',' << rhs.w << ']';
-}
+ inline std::ostream &operator<<(std::ostream &os, const Quaternion &rhs)
+ {
+ return os
+ << '[' << rhs.x << ',' << rhs.y << ',' << rhs.z << ',' << rhs.w << ']';
+ }
#endif
-
-}
}
#endif // MESH_IO_LA_H_INCLUDED
--- /dev/null
+#ifndef LINEREADER_H
+#define LINEREADER_H
+
+#include "text.h"
+
+namespace meshio
+{
+ struct IsCRLF
+ {
+ bool operator()(char byte)const
+ {
+ switch(byte)
+ {
+ case '\n':
+ case '\r': // fall through
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ };
+
+ struct IsWhiteSpace
+ {
+ bool operator()(char byte)const
+ {
+ switch(byte)
+ {
+ case ' ':
+ case '\t': // fall through
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ };
+
+ struct IsEmpty
+ {
+ bool operator()(cstr line)const
+ {
+ return line.empty();
+ }
+ };
+
+ template<class DELIMITER=IsCRLF,
+ class TRIM=IsWhiteSpace,
+ class LINESKIP=IsEmpty>
+ class LineReader
+ {
+ binary::IReader &reader_;
+ unsigned int lineCount_;
+ std::vector<char> buf_;
+ bool isEnd_;
+
+ public:
+ LineReader(binary::IReader &reader)
+ : reader_(reader), lineCount_(0), isEnd_(false)
+ {
+ }
+
+ cstr getLine()
+ {
+ while(!isEnd_){
+ fill_();
+ cstr line;
+ if(!buf_.empty()){
+ line=trim_();
+ }
+ if(LINESKIP()(line)){
+ continue;
+ }
+ ++lineCount_;
+ return line;
+ }
+ return cstr();
+ }
+
+ unsigned int getLineCount()const
+ {
+ return lineCount_;
+ }
+
+ bool isEnd()const
+ {
+ return isEnd_;
+ }
+
+ private:
+ void fill_()
+ {
+ buf_.clear();
+ // skip delimeter
+ while(char byte=reader_.getChar()){
+ if(DELIMITER()(byte)){
+ continue;
+ }
+ buf_.push_back(byte);
+ break;
+ }
+ while(char byte=reader_.getChar()){
+ if(DELIMITER()(byte)){
+ break;
+ }
+ buf_.push_back(byte);
+ }
+ if(buf_.empty()){
+ isEnd_=true;
+ return;
+ }
+ }
+
+ cstr trim_()
+ {
+ if(buf_.empty()){
+ return cstr();
+ }
+
+ size_t front=0;
+ while(true){
+ if(front>=buf_.size()){
+ return cstr();
+ }
+ if(!TRIM()(buf_[front])){
+ break;
+ }
+ ++front;
+ }
+
+ size_t back=buf_.size()-1;
+ for(; back>=0; --back){
+ if(!TRIM()(buf_[back])){
+ break;
+ }
+ }
+ assert(front<=back);
+ return cstr(&buf_[0]+front, &buf_[0]+back+1);
+ }
+ };
+
+ template<class DELIMITER=IsWhiteSpace>
+ class LineSplitter
+ {
+ cstr line_;
+
+ public:
+ LineSplitter(cstr line)
+ : line_(line)
+ {
+ }
+
+ cstr get()
+ {
+ const char* head=0;
+ const char* tail=0;
+ const char *current=line_.begin();
+ for(; current!=line_.end();){
+ for(; current!=line_.end(); ++current){
+ if(!DELIMITER()(*current)){
+ head=current;
+ break;
+ }
+ }
+ if(head){
+ for(; current!=line_.end(); ++current){
+ if(DELIMITER()(*current)){
+ break;
+ }
+ }
+ tail=current;
+ }
+ if(tail){
+ break;
+ }
+ }
+ if(!tail){
+ return cstr();
+ }
+ line_=cstr(tail+1, line_.end());
+ return cstr(head, tail);
+ }
+
+ int getInt()
+ {
+ return atoi(get().begin());
+ }
+
+ float getFloat()
+ {
+ return static_cast<float>(atof(get().begin()));
+ }
+
+ Vector2 getVector2()
+ {
+ float x=getFloat();
+ float y=getFloat();
+ return Vector2(x, y);
+ }
+
+ Vector3 getVector3()
+ {
+ float x=getFloat();
+ float y=getFloat();
+ float z=getFloat();
+ return Vector3(x, y, z);
+ }
+
+ Vector4 getVector4()
+ {
+ float x=getFloat();
+ float y=getFloat();
+ float z=getFloat();
+ float w=getFloat();
+ return Vector4(x, y, z, w);
+ }
+
+ fRGBA getFloatRGBA()
+ {
+ float r=getFloat();
+ float g=getFloat();
+ float b=getFloat();
+ float a=getFloat();
+ return fRGBA(r, g, b, a);
+ }
+
+ bRGBA getByteRGBA()
+ {
+ int r=getInt();
+ int g=getInt();
+ int b=getInt();
+ int a=getInt();
+ return bRGBA(r, g, b, a);
+ }
+
+ cstr getQuated()
+ {
+ const char *begin=line_.begin();
+ for(; begin!=line_.end(); ++begin){
+ if(*begin=='"'){
+ break;
+ }
+ }
+ begin++;
+ assert(begin<=line_.end());
+
+ const char *c=begin+1;
+ for(; c!=line_.end(); ++c){
+ if(*c=='"'){
+ break;
+ }
+ }
+
+ cstr token=cstr(begin, c);
+
+ // advance
+ line_=cstr(c+1, line_.end());
+
+ return token;
+ }
+ };
+}
+
+#endif
#include "mqo.h"
+#include "linereader.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <vector>
-#include "text.h"
-
namespace meshio {
-namespace mqo {
-
-std::wstring
- Material::getName()const
- {
- return text::trim(text::cp932_to_unicode(name));
- }
-
-std::wstring
- Material::getTexture()const
- {
- return text::trim(text::cp932_to_unicode(texture));
- }
-
-std::wstring
- Object::getName()const
- {
- return text::trim(text::cp932_to_unicode(name));
- }
-
-//! Tokenizer
-struct DELIMITER
-{
- bool operator()(char c)
- {
- switch(c)
- {
- case ' ':
- case '\t':
- case '(':
- case ')':
- return true;
- default:
- return false;
- }
- }
-};
-typedef text::LineSplitter<DELIMITER> SPLITTER;
-
-
-//! \8eÀ\91\95
-class Implementation
-{
- Scene &scene;
- std::vector<Material> &materials;
- std::vector<Object> &objects;
-
-public:
- Implementation(Scene &_scene, std::vector<Material> &_materials,
- std::vector<Object> &_objects)
- : scene(_scene), materials(_materials), objects(_objects)
- {}
-
- template<class READER> bool
- parse(READER reader)
- {
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- SPLITTER splitter(line);
- text::cstr key=splitter.get();
- if(key=="Scene"){
- if(!readSceneChunk(reader)){
- return false;
- }
- }
- else if(key=="Material"){
- if(!readMaterialChunk(reader, splitter.getInt())){
- return false;
- }
- }
- else if(key=="Object"){
- if(!readObjectChunk(reader, splitter.getQuated())){
- return false;
- }
- }
- else if(key=="Eof"){
- if(materials.empty()){
- // fallback
- //materials.push_back(Material());
- }
- return true;
- }
- }
- std::cout << "not found 'EOF'" << std::endl;
- return true;
- }
-
-
-private:
- template<class READER> bool
- readObjectChunk(READER &reader, text::cstr name)
- {
- objects.push_back(Object());
- Object &object=objects.back();
- object.name=name.str();
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- return true;
- }
- SPLITTER splitter(line);
- text::cstr key=splitter.get();
- if(key=="depth"){
- object.depth=splitter.getInt();
- }
- else if(key=="folding"){
- object.folding=splitter.getInt();
- }
- else if(key=="scale"){
- object.scale=splitter.getVector3();
- }
- else if(key=="rotation"){
- object.rotation=splitter.getVector3();
- }
- else if(key=="translation"){
- object.translation=splitter.getVector3();
- }
- else if(key=="visible"){
- object.visible=splitter.getInt();
- }
- else if(key=="locking"){
- object.locking=splitter.getInt();
- }
- else if(key=="shading"){
- object.shading=splitter.getInt();
- }
- else if(key=="facet"){
- object.smoothing=splitter.getFloat();
- }
- else if(key=="color"){
- object.color=splitter.getVector3();
- }
- else if(key=="color_type"){
- object.color_type=splitter.getInt();
- }
- else if(key=="vertex"){
- if(!readObjectVertexChunk(reader, object, splitter.getInt())){
- return false;
- }
- }
- else if(key=="face"){
- if(!readObjectFaceChunk(reader, object, splitter.getInt())){
- return false;
- }
- }
- else if(key=="segment"){
- // ToDo
- continue;
- }
- else if(key=="patch"){
- // ToDo
- continue;
- }
- else if(key=="mirror"){
- object.mirror=splitter.getInt();
- }
- else{
- std::cout << "unknown object key: " << key << std::endl;
- }
- }
- std::cout << "fail to readObjectChunk" << std::endl;
- return false;
- }
- template<class READER> bool
- readObjectVertexChunk(READER &reader,
- Object &object, size_t vertex_count)
- {
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- if(object.vertices.size()!=vertex_count){
- std::cout << "invalid vertex count."
- << " expected " << vertex_count
- << ", but " << object.vertices.size()
- << std::endl;
- return false;
- }
- return true;
- }
- object.vertices.push_back(SPLITTER(line).getVector3());
- }
- std::cout << "fail to readObjectVertexChunk" << std::endl;
- return false;
- }
-
- template<class READER> bool
- readObjectFaceChunk(READER &reader,
- Object &object, size_t face_count)
- {
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- if(object.faces.size()!=face_count){
- std::cout << "invalid face count."
- << " expected " << face_count
- << ", but " << object.faces.size()
- << std::endl;
- return false;
- }
- return true;
- }
- if(!readObjectFaceLine(object, line)){
- return false;
- }
- }
- std::cout << "fail to readFaceChunk" << std::endl;
- return false;
- }
-
- bool
- readObjectFaceLine(Object &object, text::cstr line)
- {
- object.faces.push_back(Face());
- Face &face=object.faces.back();
- SPLITTER splitter(line);
- face.index_count=splitter.getInt();
- while(true){
- text::cstr key=splitter.get();
- if(key==""){
- break;
- }
-
- if(key=="V"){
- for(size_t i=0; i<face.index_count; ++i){
- face.indices[i]=splitter.getInt();
- }
- }
- else if(key=="M"){
- face.material_index=splitter.getInt();
- }
- else if(key=="UV"){
- for(size_t i=0; i<face.index_count; ++i){
- face.uv[i]=splitter.getVector2();
- }
- }
- else if(key=="COL"){
- for(size_t i=0; i<face.index_count; ++i){
- face.color[i]=
- color::fRGBA::createFromUInt(splitter.getInt());
- }
- }
- else{
- std::cout << "unknown face key: "
- << '"' << key << '"' << std::endl
- ;
- //return false;
- break;
- }
- }
- return true;
- }
-
- template<class READER> bool
- readMaterialChunk(READER &reader, size_t material_count)
- {
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- if(materials.size()!=material_count){
- std::cout << "invalid material count."
- << " expected " << material_count
- << ", but " << materials.size()
- << std::endl;
- return false;
- }
- return true;
- }
- readMaterialLine(line);
- }
- std::cout << "fail to readMaterialChunk" << std::endl;
- return false;
- }
-
- void
- readMaterialLine(text::cstr line)
- {
- materials.push_back(Material());
- Material &material=materials.back();
-
- SPLITTER splitter(line);
- material.name=splitter.getQuated().str();
- while(true){
- text::cstr key=splitter.get();
- if(key==""){
- break;
- }
- else if(key=="shader"){
- material.shader=splitter.getInt();
- }
- else if(key=="col"){
- material.color=splitter.getFloatRGBA();
- }
- else if(key=="dif"){
- material.diffuse=splitter.getFloat();
- }
- else if(key=="amb"){
- material.ambient=splitter.getFloat();
- }
- else if(key=="emi"){
- material.emit=splitter.getFloat();
- }
- else if(key=="spc"){
- material.specular=splitter.getFloat();
- }
- else if(key=="power"){
- material.power=splitter.getFloat();
- }
- else if(key=="tex"){
- material.texture=splitter.getQuated().str();
- }
- else if(key=="aplane"){
- material.alphamap=splitter.getQuated().str();
- }
- else if(key=="bump"){
- material.bumpmap=splitter.getQuated().str();
- }
- else if(key=="vcol"){
- material.vcol=splitter.getInt();
- }
- else{
- std::cout << "unknown material key: \"" << key << '"' << std::endl;
- //assert(false);
- return;
- }
- }
- }
-
- template<class READER> bool
- readSceneChunk(READER &reader)
- {
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- return true;
- }
- SPLITTER splitter(line);
- text::cstr key=splitter.get();
- if(key=="pos"){
- scene.pos=splitter.getVector3();
- }
- else if(key=="lookat"){
- scene.lookat=splitter.getVector3();
- }
- else if(key=="head"){
- scene.head=splitter.getFloat();
- }
- else if(key=="pich") {
- scene.pitch=splitter.getFloat();
- }
- else if(key=="ortho"){
- scene.ortho=splitter.getInt();
- }
- else if(key=="zoom2"){
- scene.zoom2=splitter.getFloat();
- }
- else if(key=="amb"){
- scene.ambient=splitter.getVector3();
- }
- else{
- std::cout << "unknown scene key: " << key << std::endl;
- }
- }
- std::cout << "fail to readSceneChunk" << std::endl;
- return false;
- }
-
- template<class READER> bool
- readChunk(READER &reader)
- {
- int level=1;
- while(!reader.isEnd()){
- text::cstr line=reader.getLine();
- if(line=="}"){
- level--;
- if(level==0){
- return true;
- }
- }
- else if(line.include('{')){
- level+=1;
- }
- }
- return false;
- }
-
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// IO
-///////////////////////////////////////////////////////////////////////////////
-bool IO::read(binary::IReader &input)
-{
- text::LineReader<text::IsCRLF, text::IsWhiteSpace, text::IsEmpty>
- reader(input);
- text::cstr line=reader.getLine();
- if(line!="Metasequoia Document"){
- return false;
- }
- line=reader.getLine();
- if(line!="Format Text Ver 1.0"){
- return false;
- }
-
- return Implementation(scene, materials, objects).parse(reader);
-}
-
-bool IO::read(const char *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-
-#ifdef _WIN32
-bool IO::read(const wchar_t *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-#endif
-
-bool IO::write(binary::IWriter &writer)
-{
- // header
- writer.printLn("Metasequoia Document");
- writer.printLn("Format Text Ver 1.0");
- writer.printLn("");
-
- // scene
- writer.printLn("Scene {");
- writer.printLn("\tpos 0.0000 0.0000 1500.0000");
- writer.printLn("\tlookat 0.0000 0.0000 0.0000");
- writer.printLn("\thead -0.5236");
- writer.printLn("\tpich 0.5236");
- writer.printLn("\tortho 0");
- writer.printLn("\tzoom2 5.0000");
- writer.printLn("\tamb 0.250 0.250 0.250");
- writer.printLn("}");
-
- // materials
- if(materials.size()>0){
- writer.printLn("Material %d {", materials.size());
- for(size_t i=0; i<materials.size(); ++i){
- Material &m=materials[i];
- }
- writer.printLn("}");
- }
-
- // objects
- for(size_t i=0; i<objects.size(); ++i){
- Object &o=objects[i];
- writer.printLn("Object \"%s\" {", o.name.c_str());
- writer.printLn("\tdepth 0");
- writer.printLn("\tfolding 0");
- writer.printLn("\tscale 1.000000 1.000000 1.000000");
- writer.printLn("\trotation 0.000000 0.000000 0.000000");
- writer.printLn("\ttranslation 0.000000 0.000000 0.000000");
- writer.printLn("\tvisible 15");
- writer.printLn("\tlocking 0");
- writer.printLn("\tshading 1");
- writer.printLn("\tfacet 59.5");
- writer.printLn("\tcolor 0.898 0.400 0.137");
- writer.printLn("\tcolor_type 0");
- // vertex
- writer.printLn("\tvertex %d {", o.vertices.size());
- for(size_t j=0; j<o.vertices.size(); ++j){
- Vector3 &v=o.vertices[j];
- writer.printLn("\t\t%.4f %.4f %.4f", v.x, v.y, v.z);
- }
- writer.printLn("\t}");
- // face
- writer.printLn("\tface %d {", o.faces.size());
- for(size_t j=0; j<o.faces.size(); ++j){
- Face &f=o.faces[j];
-
- std::stringstream ss;
- ss.setf(std::ios_base::fixed, std::ios_base::floatfield);
- ss
- << "\t\t"
- << f.index_count
- ;
- ss << " V(";
- for(size_t k=0; k<f.index_count; ++k){
- if(k){
- ss << ' ';
- }
- ss << f.indices[k];
- }
- ss << ") UV(";
- for(size_t k=0; k<f.index_count; ++k){
- if(k){
- ss << ' ';
- }
- Vector2 &uv=f.uv[k];
- ss
- << std::setprecision(5) << uv.x
- << ' ' << std::setprecision(5) << uv.y;
- }
- ss << ")";
-
- writer.printLn(ss.str().c_str());
- }
- writer.printLn("\t}");
- // close
- writer.printLn("}");
- }
- // Eof
- writer.printLn("Eof");
-
- return true;
-}
-
-bool IO::write(const char *path)
-{
- binary::FileWriter writer(path);
- return write(writer);
-}
-
-}
+ namespace mqo {
+
+ //! Tokenizer
+ struct DELIMITER
+ {
+ bool operator()(char c)
+ {
+ switch(c)
+ {
+ case ' ':
+ case '\t':
+ case '(':
+ case ')':
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+ typedef LineSplitter<DELIMITER> SPLITTER;
+
+
+ //! \8eÀ\91\95
+ class Implementation
+ {
+ Scene &scene;
+ std::vector<Material> &materials;
+ std::vector<Object> &objects;
+
+ public:
+ Implementation(Scene &_scene, std::vector<Material> &_materials,
+ std::vector<Object> &_objects)
+ : scene(_scene), materials(_materials), objects(_objects)
+ {}
+
+ template<class READER> bool
+ parse(READER reader)
+ {
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ SPLITTER splitter(line);
+ cstr key=splitter.get();
+ if(key=="Scene"){
+ if(!readSceneChunk(reader)){
+ return false;
+ }
+ }
+ else if(key=="Material"){
+ if(!readMaterialChunk(reader, splitter.getInt())){
+ return false;
+ }
+ }
+ else if(key=="Object"){
+ if(!readObjectChunk(reader, splitter.getQuated())){
+ return false;
+ }
+ }
+ else if(key=="Eof"){
+ if(materials.empty()){
+ // fallback
+ //materials.push_back(Material());
+ }
+ return true;
+ }
+ }
+ std::cout << "not found 'EOF'" << std::endl;
+ return true;
+ }
+
+
+ private:
+ template<class READER> bool
+ readObjectChunk(READER &reader, cstr name)
+ {
+ objects.push_back(Object());
+ Object &object=objects.back();
+ object.name=name.str();
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ return true;
+ }
+ SPLITTER splitter(line);
+ cstr key=splitter.get();
+ if(key=="depth"){
+ object.depth=splitter.getInt();
+ }
+ else if(key=="folding"){
+ object.folding=splitter.getInt();
+ }
+ else if(key=="scale"){
+ object.scale=splitter.getVector3();
+ }
+ else if(key=="rotation"){
+ object.rotation=splitter.getVector3();
+ }
+ else if(key=="translation"){
+ object.translation=splitter.getVector3();
+ }
+ else if(key=="visible"){
+ object.visible=splitter.getInt();
+ }
+ else if(key=="locking"){
+ object.locking=splitter.getInt();
+ }
+ else if(key=="shading"){
+ object.shading=splitter.getInt();
+ }
+ else if(key=="facet"){
+ object.smoothing=splitter.getFloat();
+ }
+ else if(key=="color"){
+ object.color=splitter.getVector3();
+ }
+ else if(key=="color_type"){
+ object.color_type=splitter.getInt();
+ }
+ else if(key=="vertex"){
+ if(!readObjectVertexChunk(reader, object, splitter.getInt())){
+ return false;
+ }
+ }
+ else if(key=="face"){
+ if(!readObjectFaceChunk(reader, object, splitter.getInt())){
+ return false;
+ }
+ }
+ else if(key=="segment"){
+ // ToDo
+ continue;
+ }
+ else if(key=="patch"){
+ // ToDo
+ continue;
+ }
+ else if(key=="mirror"){
+ object.mirror=splitter.getInt();
+ }
+ else{
+ std::cout << "unknown object key: " << key << std::endl;
+ }
+ }
+ std::cout << "fail to readObjectChunk" << std::endl;
+ return false;
+ }
+ template<class READER> bool
+ readObjectVertexChunk(READER &reader,
+ Object &object, size_t vertex_count)
+ {
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ if(object.vertices.size()!=vertex_count){
+ std::cout << "invalid vertex count."
+ << " expected " << vertex_count
+ << ", but " << object.vertices.size()
+ << std::endl;
+ return false;
+ }
+ return true;
+ }
+ object.vertices.push_back(SPLITTER(line).getVector3());
+ }
+ std::cout << "fail to readObjectVertexChunk" << std::endl;
+ return false;
+ }
+
+ template<class READER> bool
+ readObjectFaceChunk(READER &reader,
+ Object &object, size_t face_count)
+ {
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ if(object.faces.size()!=face_count){
+ std::cout << "invalid face count."
+ << " expected " << face_count
+ << ", but " << object.faces.size()
+ << std::endl;
+ return false;
+ }
+ return true;
+ }
+ if(!readObjectFaceLine(object, line)){
+ return false;
+ }
+ }
+ std::cout << "fail to readFaceChunk" << std::endl;
+ return false;
+ }
+
+ bool
+ readObjectFaceLine(Object &object, cstr line)
+ {
+ object.faces.push_back(Face());
+ Face &face=object.faces.back();
+ SPLITTER splitter(line);
+ face.index_count=splitter.getInt();
+ while(true){
+ cstr key=splitter.get();
+ if(key==""){
+ break;
+ }
+
+ if(key=="V"){
+ for(size_t i=0; i<face.index_count; ++i){
+ face.indices[i]=splitter.getInt();
+ }
+ }
+ else if(key=="M"){
+ face.material_index=splitter.getInt();
+ }
+ else if(key=="UV"){
+ for(size_t i=0; i<face.index_count; ++i){
+ face.uv[i]=splitter.getVector2();
+ }
+ }
+ else if(key=="COL"){
+ for(size_t i=0; i<face.index_count; ++i){
+ face.color[i]=
+ fRGBA::createFromUInt(splitter.getInt());
+ }
+ }
+ else{
+ std::cout << "unknown face key: "
+ << '"' << key << '"' << std::endl
+ ;
+ //return false;
+ break;
+ }
+ }
+ return true;
+ }
+
+ template<class READER> bool
+ readMaterialChunk(READER &reader, size_t material_count)
+ {
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ if(materials.size()!=material_count){
+ std::cout << "invalid material count."
+ << " expected " << material_count
+ << ", but " << materials.size()
+ << std::endl;
+ return false;
+ }
+ return true;
+ }
+ readMaterialLine(line);
+ }
+ std::cout << "fail to readMaterialChunk" << std::endl;
+ return false;
+ }
+
+ void
+ readMaterialLine(cstr line)
+ {
+ materials.push_back(Material());
+ Material &material=materials.back();
+
+ SPLITTER splitter(line);
+ material.name=splitter.getQuated().str();
+ while(true){
+ cstr key=splitter.get();
+ if(key==""){
+ break;
+ }
+ else if(key=="shader"){
+ material.shader=splitter.getInt();
+ }
+ else if(key=="col"){
+ material.color=splitter.getFloatRGBA();
+ }
+ else if(key=="dif"){
+ material.diffuse=splitter.getFloat();
+ }
+ else if(key=="amb"){
+ material.ambient=splitter.getFloat();
+ }
+ else if(key=="emi"){
+ material.emit=splitter.getFloat();
+ }
+ else if(key=="spc"){
+ material.specular=splitter.getFloat();
+ }
+ else if(key=="power"){
+ material.power=splitter.getFloat();
+ }
+ else if(key=="tex"){
+ material.texture=splitter.getQuated().str();
+ }
+ else if(key=="aplane"){
+ material.alphamap=splitter.getQuated().str();
+ }
+ else if(key=="bump"){
+ material.bumpmap=splitter.getQuated().str();
+ }
+ else if(key=="vcol"){
+ material.vcol=splitter.getInt();
+ }
+ else{
+ std::cout << "unknown material key: \"" << key << '"' << std::endl;
+ //assert(false);
+ return;
+ }
+ }
+ }
+
+ template<class READER> bool
+ readSceneChunk(READER &reader)
+ {
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ return true;
+ }
+ SPLITTER splitter(line);
+ cstr key=splitter.get();
+ if(key=="pos"){
+ scene.pos=splitter.getVector3();
+ }
+ else if(key=="lookat"){
+ scene.lookat=splitter.getVector3();
+ }
+ else if(key=="head"){
+ scene.head=splitter.getFloat();
+ }
+ else if(key=="pich") {
+ scene.pitch=splitter.getFloat();
+ }
+ else if(key=="ortho"){
+ scene.ortho=splitter.getInt();
+ }
+ else if(key=="zoom2"){
+ scene.zoom2=splitter.getFloat();
+ }
+ else if(key=="amb"){
+ scene.ambient=splitter.getVector3();
+ }
+ else{
+ std::cout << "unknown scene key: " << key << std::endl;
+ }
+ }
+ std::cout << "fail to readSceneChunk" << std::endl;
+ return false;
+ }
+
+ template<class READER> bool
+ readChunk(READER &reader)
+ {
+ int level=1;
+ while(!reader.isEnd()){
+ cstr line=reader.getLine();
+ if(line=="}"){
+ level--;
+ if(level==0){
+ return true;
+ }
+ }
+ else if(line.include('{')){
+ level+=1;
+ }
+ }
+ return false;
+ }
+
+ };
+
+
+ // IO
+ bool IO::read(binary::IReader &input)
+ {
+ LineReader<IsCRLF, IsWhiteSpace, IsEmpty>
+ reader(input);
+ cstr line=reader.getLine();
+ if(line!="Metasequoia Document"){
+ return false;
+ }
+ line=reader.getLine();
+ if(line!="Format Text Ver 1.0"){
+ return false;
+ }
+
+ return Implementation(scene, materials, objects).parse(reader);
+ }
+
+ bool IO::read(const char *path)
+ {
+ std::vector<char> all;
+ binary::readAll(path, all);
+ if(all.empty()){
+ return false;
+ }
+ binary::MemoryReader reader(&all[0], all.size());
+ return read(reader);
+ }
+
+ bool IO::write(binary::IWriter &writer)
+ {
+ // header
+ writer.printLn("Metasequoia Document");
+ writer.printLn("Format Text Ver 1.0");
+ writer.printLn("");
+
+ // scene
+ writer.printLn("Scene {");
+ writer.printLn("\tpos 0.0000 0.0000 1500.0000");
+ writer.printLn("\tlookat 0.0000 0.0000 0.0000");
+ writer.printLn("\thead -0.5236");
+ writer.printLn("\tpich 0.5236");
+ writer.printLn("\tortho 0");
+ writer.printLn("\tzoom2 5.0000");
+ writer.printLn("\tamb 0.250 0.250 0.250");
+ writer.printLn("}");
+
+ // materials
+ if(materials.size()>0){
+ writer.printLn("Material %d {", materials.size());
+ /*
+ for(size_t i=0; i<materials.size(); ++i){
+ Material &m=materials[i];
+ }
+ */
+ writer.printLn("}");
+ }
+
+ // objects
+ for(size_t i=0; i<objects.size(); ++i){
+ Object &o=objects[i];
+ writer.printLn("Object \"%s\" {", o.name.c_str());
+ writer.printLn("\tdepth 0");
+ writer.printLn("\tfolding 0");
+ writer.printLn("\tscale 1.000000 1.000000 1.000000");
+ writer.printLn("\trotation 0.000000 0.000000 0.000000");
+ writer.printLn("\ttranslation 0.000000 0.000000 0.000000");
+ writer.printLn("\tvisible 15");
+ writer.printLn("\tlocking 0");
+ writer.printLn("\tshading 1");
+ writer.printLn("\tfacet 59.5");
+ writer.printLn("\tcolor 0.898 0.400 0.137");
+ writer.printLn("\tcolor_type 0");
+ // vertex
+ writer.printLn("\tvertex %d {", o.vertices.size());
+ for(size_t j=0; j<o.vertices.size(); ++j){
+ Vector3 &v=o.vertices[j];
+ writer.printLn("\t\t%.4f %.4f %.4f", v.x, v.y, v.z);
+ }
+ writer.printLn("\t}");
+ // face
+ writer.printLn("\tface %d {", o.faces.size());
+ for(size_t j=0; j<o.faces.size(); ++j){
+ Face &f=o.faces[j];
+
+ std::stringstream ss;
+ ss.setf(std::ios_base::fixed, std::ios_base::floatfield);
+ ss
+ << "\t\t"
+ << f.index_count
+ ;
+ ss << " V(";
+ for(size_t k=0; k<f.index_count; ++k){
+ if(k){
+ ss << ' ';
+ }
+ ss << f.indices[k];
+ }
+ ss << ") UV(";
+ for(size_t k=0; k<f.index_count; ++k){
+ if(k){
+ ss << ' ';
+ }
+ Vector2 &uv=f.uv[k];
+ ss
+ << std::setprecision(5) << uv.x
+ << ' ' << std::setprecision(5) << uv.y;
+ }
+ ss << ")";
+
+ writer.printLn(ss.str().c_str());
+ }
+ writer.printLn("\t}");
+ // close
+ writer.printLn("}");
+ }
+ // Eof
+ writer.printLn("Eof");
+
+ return true;
+ }
+
+ bool IO::write(const char *path)
+ {
+ binary::FileWriter writer(path);
+ return write(writer);
+ }
+
+ }
}
#include <iosfwd>
#include <vector>
+#include <assert.h>
#include "la.h"
#include "color.h"
#include "text.h"
+#include "binary.h"
namespace meshio {
-namespace mqo {
-
-typedef ::meshio::la::Vector2 Vector2;
-typedef ::meshio::la::Vector3 Vector3;
-typedef ::meshio::la::Vector4 Vector4;
-typedef ::meshio::color::fRGBA RGBA;
-
-//! Scene\83`\83\83\83\93\83N
-struct Scene
-{
- Vector3 pos;
- Vector3 lookat;
- float head;
- float pitch;
- int ortho;
- float zoom2;
- Vector3 ambient;
- Scene()
- : head(0), pitch(0), ortho(false), zoom2(2)
- {}
-};
-inline std::ostream &operator<<(std::ostream &os, const Scene &rhs)
-{
- os
- << "<Scene"
- << " pos: " << rhs.pos
- << ", lookat: " << rhs.lookat
- << ", head: " << rhs.head
- << ", pitch: " << rhs.pitch
- << ", ortho: " << rhs.ortho
- << ", zoom2: " << rhs.zoom2
- << ", ambient: " << rhs.ambient
- << ">"
- ;
- return os;
-}
-
-//! Material\83`\83\83\83\93\83N
-struct Material
-{
- std::string name;
- int shader;
- RGBA color;
- float diffuse;
- float ambient;
- float emit;
- float specular;
- float power;
- std::string texture;
- std::string alphamap;
- std::string bumpmap;
- int vcol;
-
- Material()
- : shader(0), diffuse(1), ambient(0), emit(0), specular(0), power(0),
- vcol(0)
- {}
-
- // for python3 unicode
- std::wstring getName()const;
- std::wstring getTexture()const;
-};
-inline std::ostream &operator<<(std::ostream &os, const Material &rhs)
-{
- os
- << "<Material "
- << '"' << rhs.name << '"'
- << " shader:" << rhs.shader
- << ", color:" << rhs.color
- << ", diffuse:" << rhs.diffuse
- << ", ambient:" << rhs.ambient
- << ", emit:" << rhs.emit
- << ", specular:" << rhs.specular
- << ", power:" << rhs.power
- << ", texture:\"" << rhs.texture << '"'
- << ", alphamap:\"" << rhs.alphamap << '"'
- << ", bumpmap:\"" << rhs.bumpmap << '"'
- << ">"
- ;
- return os;
-}
-
-//! face\83`\83\83\83\93\83N
-struct Face
-{
- unsigned int index_count;
- unsigned int indices[4];
- unsigned int material_index;
- Vector2 uv[4];
- RGBA color[4];
- Face()
- : index_count(0), material_index(0)
- {
- indices[0]=0;
- indices[1]=0;
- indices[2]=0;
- indices[3]=0;
- uv[0]=Vector2();
- uv[1]=Vector2();
- uv[2]=Vector2();
- uv[3]=Vector2();
- }
- int getIndex(int i){ return indices[i]; }
- Vector2 getUV(int i){ return uv[i]; }
-};
-inline std::ostream &operator<<(std::ostream &os, const Face &rhs)
-{
- switch(rhs.index_count)
- {
- case 2:
- os
- << "<Edge "
- << "indices:{" << rhs.indices[0] << ',' << rhs.indices[1] << "}"
- << ", material_index: " << rhs.material_index
- << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1] << "}"
- << ", color:{" << rhs.color[0] << ',' << rhs.color[1] << "}"
- << ">"
- ;
- break;
-
- case 3:
- os
- << "<Triangle "
- << "indices:{" << rhs.indices[0]
- << ',' << rhs.indices[1]
- << ',' << rhs.indices[2] << "}"
- << ", material_index: " << rhs.material_index
- << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1] << ',' << rhs.uv[2] << "}"
- << ", color:{"
- << rhs.color[0] << ',' << rhs.color[1] << ',' << rhs.color[2] << "}"
- << ">"
- ;
- break;
-
- case 4:
- os
- << "<Rectangle "
- << "indices:{" << rhs.indices[0]
- << ',' << rhs.indices[1]
- << ',' << rhs.indices[2]
- << ',' << rhs.indices[3] << "}"
- << ", material_index: " << rhs.material_index
- << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1]
- << ',' << rhs.uv[2] << ',' << rhs.uv[3] << "}"
- << ", color:{" << rhs.color[0]
- << ',' << rhs.color[1]
- << ',' << rhs.color[2]
- << ',' << rhs.color[3] << "}"
- << ">"
- ;
- break;
- default:
- assert(false);
- }
-
- return os;
-}
-
-//! Object\83`\83\83\83\93\83N
-struct Object
-{
- std::string name;
- int depth;
- int folding;
- Vector3 scale;
- Vector3 rotation;
- Vector3 translation;
- int visible;
- int locking;
- int shading;
- float smoothing;
- Vector3 color;
- int color_type;
- int mirror;
-
- std::vector<Vector3> vertices;
- std::vector<Face> faces;
-
- Object()
- : depth(0), folding(0), visible(1), locking(0), shading(0),
- smoothing(60.0f), color_type(0), mirror(0)
- {}
-
- std::wstring getName()const;
-};
-inline std::ostream &operator<<(std::ostream &os, const Object &rhs)
-{
- os
- << "<Object "
- << '"' << rhs.name << '"'
- << " vertices:" << rhs.vertices.size()
- << ", faces:" << rhs.faces.size()
- << ">"
- ;
- return os;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// IO
-///////////////////////////////////////////////////////////////////////////////
-struct IO
-{
- Scene scene;
- std::vector<Material> materials;
- std::vector<Object> objects;
-
- bool read(binary::IReader &reader);
- bool read(const char *path);
-#ifdef _WIN32
- bool read(const wchar_t *path);
-#endif
- bool write(binary::IWriter &writer);
- bool write(const char *path);
-};
-
-} // namespace mqo
+ namespace mqo {
+
+ //! Scene\83`\83\83\83\93\83N
+ struct Scene
+ {
+ Vector3 pos;
+ Vector3 lookat;
+ float head;
+ float pitch;
+ int ortho;
+ float zoom2;
+ Vector3 ambient;
+ Scene()
+ : head(0), pitch(0), ortho(false), zoom2(2)
+ {}
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Scene &rhs)
+ {
+ os
+ << "<Scene"
+ << " pos: " << rhs.pos
+ << ", lookat: " << rhs.lookat
+ << ", head: " << rhs.head
+ << ", pitch: " << rhs.pitch
+ << ", ortho: " << rhs.ortho
+ << ", zoom2: " << rhs.zoom2
+ << ", ambient: " << rhs.ambient
+ << ">"
+ ;
+ return os;
+ }
+
+ //! Material\83`\83\83\83\93\83N
+ struct Material
+ {
+ std::string name;
+ int shader;
+ fRGBA color;
+ float diffuse;
+ float ambient;
+ float emit;
+ float specular;
+ float power;
+ std::string texture;
+ std::string alphamap;
+ std::string bumpmap;
+ int vcol;
+
+ Material()
+ : shader(0), diffuse(1), ambient(0), emit(0), specular(0), power(0),
+ vcol(0)
+ {}
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Material &rhs)
+ {
+ os
+ << "<Material "
+ << '"' << rhs.name << '"'
+ << " shader:" << rhs.shader
+ << ", color:" << rhs.color
+ << ", diffuse:" << rhs.diffuse
+ << ", ambient:" << rhs.ambient
+ << ", emit:" << rhs.emit
+ << ", specular:" << rhs.specular
+ << ", power:" << rhs.power
+ << ", texture:\"" << rhs.texture << '"'
+ << ", alphamap:\"" << rhs.alphamap << '"'
+ << ", bumpmap:\"" << rhs.bumpmap << '"'
+ << ">"
+ ;
+ return os;
+ }
+
+ //! face\83`\83\83\83\93\83N
+ struct Face
+ {
+ unsigned int index_count;
+ unsigned int indices[4];
+ unsigned int material_index;
+ Vector2 uv[4];
+ fRGBA color[4];
+ Face()
+ : index_count(0), material_index(0)
+ {
+ indices[0]=0;
+ indices[1]=0;
+ indices[2]=0;
+ indices[3]=0;
+ uv[0]=Vector2();
+ uv[1]=Vector2();
+ uv[2]=Vector2();
+ uv[3]=Vector2();
+ }
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Face &rhs)
+ {
+ switch(rhs.index_count)
+ {
+ case 2:
+ os
+ << "<Edge "
+ << "indices:{" << rhs.indices[0] << ',' << rhs.indices[1] << "}"
+ << ", material_index: " << rhs.material_index
+ << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1] << "}"
+ << ", color:{" << rhs.color[0] << ',' << rhs.color[1] << "}"
+ << ">"
+ ;
+ break;
+
+ case 3:
+ os
+ << "<Triangle "
+ << "indices:{" << rhs.indices[0]
+ << ',' << rhs.indices[1]
+ << ',' << rhs.indices[2] << "}"
+ << ", material_index: " << rhs.material_index
+ << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1] << ',' << rhs.uv[2] << "}"
+ << ", color:{"
+ << rhs.color[0] << ',' << rhs.color[1] << ',' << rhs.color[2] << "}"
+ << ">"
+ ;
+ break;
+
+ case 4:
+ os
+ << "<Rectangle "
+ << "indices:{" << rhs.indices[0]
+ << ',' << rhs.indices[1]
+ << ',' << rhs.indices[2]
+ << ',' << rhs.indices[3] << "}"
+ << ", material_index: " << rhs.material_index
+ << ", uv:{" << rhs.uv[0] << ',' << rhs.uv[1]
+ << ',' << rhs.uv[2] << ',' << rhs.uv[3] << "}"
+ << ", color:{" << rhs.color[0]
+ << ',' << rhs.color[1]
+ << ',' << rhs.color[2]
+ << ',' << rhs.color[3] << "}"
+ << ">"
+ ;
+ break;
+ default:
+ assert(false);
+ }
+
+ return os;
+ }
+
+ //! Object\83`\83\83\83\93\83N
+ struct Object
+ {
+ std::string name;
+ int depth;
+ int folding;
+ Vector3 scale;
+ Vector3 rotation;
+ Vector3 translation;
+ int visible;
+ int locking;
+ int shading;
+ float smoothing;
+ Vector3 color;
+ int color_type;
+ int mirror;
+
+ std::vector<Vector3> vertices;
+ std::vector<Face> faces;
+
+ Object()
+ : depth(0), folding(0), visible(1), locking(0), shading(0),
+ smoothing(60.0f), color_type(0), mirror(0)
+ {}
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Object &rhs)
+ {
+ os
+ << "<Object "
+ << '"' << rhs.name << '"'
+ << " vertices:" << rhs.vertices.size()
+ << ", faces:" << rhs.faces.size()
+ << ">"
+ ;
+ return os;
+ }
+
+ // IO
+ struct IO
+ {
+ Scene scene;
+ std::vector<Material> materials;
+ std::vector<Object> objects;
+
+ bool read(binary::IReader &reader);
+ bool read(const char *path);
+ bool write(binary::IWriter &writer);
+ bool write(const char *path);
+ };
+
+ } // namespace mqo
} // namespace meshio
#endif // MESH_IO_MQO_H_INCLUDED
#include "pmd.h"
-#include <iostream>
#include "text.h"
#ifndef _WIN32
#include "win32.h"
#endif
+#include <iostream>
namespace meshio {
-namespace pmd {
-
-// IO
-bool IO::write(const char *path)
-{
- binary::FileWriter w(path);
- return write(w);
-}
-
-#ifdef _WIN32
-bool IO::write(const wchar_t *path)
-{
- binary::FileWriter w(path);
- return write(w);
-}
-#endif
-
-std::wstring
-IO::getName()const
-{
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+20)));
-}
-
-std::wstring
-IO::getComment()const
-{
- return text::trim(text::cp932_to_unicode(
- std::string(comment, comment+256)));
-}
-
-std::wstring
-IO::getEnglishName()const
-{
- return text::trim(text::cp932_to_unicode(
- std::string(english_name, english_name+20)));
-}
-
-std::wstring
-IO::getEnglishComment()const
-{
- return text::trim(text::cp932_to_unicode(
- std::string(english_comment, english_comment+256)));
-}
-
-const Vector2* IO::getUV(int index)const
-{
- return &vertices[index].uv;
-}
-
-void IO::setName(const char *src)
-{
- strncpy(name, src, 20);
-}
-
-void IO::setComment(const char *src)
-{
- strncpy(comment, src, 256);
-}
-
-void IO::setEnglishName(const char *src)
-{
- strncpy(english_name, src, 20);
-}
-
-void IO::setEnglishComment(const char *src)
-{
- strncpy(english_comment, src, 256);
-}
-
-// Material
-std::wstring
-Material::getTexture()const
-{
- return text::trim(text::cp932_to_unicode(
- std::string(texture, texture+20)));
-}
-
-void Material::setTexture(const char *src)
-{
- strncpy(texture, src, 20);
-}
-
-// Bone
-std::wstring
- Bone::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+20)));
- }
-
-void Bone::setName(const char *src)
-{
- strncpy(name, src, 20);
-}
-
-void Bone::setEnglishName(const char *src)
-{
- strncpy(english_name, src, 20);
-}
-
-// Morph
-std::wstring
- Morph::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+20)));
- }
-
-void
- Morph::append(int index, float x, float y, float z)
- {
- indices.push_back(index);
- pos_list.push_back(Vector3(x, y, z));
- }
-
-void Morph::setName(const char *src)
-{
- strncpy(name, src, 20);
-}
-
-void Morph::setEnglishName(const char *src)
-{
- strncpy(english_name, src, 20);
-}
-
-// BoneGroup
-std::wstring
- BoneGroup::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+50)));
- }
-
-void BoneGroup::setName(const char *src)
-{
- strncpy(name, src, 50);
-}
-
-void BoneGroup::setEnglishName(const char *src)
-{
- strncpy(english_name, src, 50);
-}
-
-// RigidBody
-std::wstring
- RigidBody::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+20)));
- }
-
-void RigidBody::setName(const char *src)
-{
- strncpy(name, src, 20);
-}
-
-// Constraint
-std::wstring
- Constraint::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+20)));
- }
-
-void Constraint::setName(const char *src)
-{
- strncpy(name, src, 20);
-}
-
-// ToonTexture
-std::wstring
- ToonTexture::getName()const
- {
- return text::trim(text::cp932_to_unicode(
- std::string(name, name+100)));
- }
-
-void ToonTexture::setName(const char *src)
-{
- strncpy(name, src, 100);
-}
-
-
-// 38bytes
-template<class READER>
- void
- read(READER &reader, Vertex &v)
- {
- unsigned int pos=reader.getPos();
- reader.get(v.pos);
- reader.get(v.normal);
- reader.get(v.uv);
- reader.get(v.bone0);
- reader.get(v.bone1);
- reader.get(v.weight0);
- reader.get(v.edge_flag);
- assert(reader.getPos()-pos==38);
- }
-
-
-// 70bytes
-template<class READER>
- void
- read(READER &reader, Material &m)
- {
- unsigned int pos=reader.getPos();
- reader.get(m.diffuse);
- reader.get(m.shinness);
- reader.get(m.specular);
- reader.get(m.ambient);
- reader.get(m.toon_index);
- reader.get(m.flag);
- reader.get(m.vertex_count);
- text::copyStringAndFillZero(m.texture, reader.getString(20));
- assert(reader.getPos()-pos==70);
- }
-
-// 39bytes
-template<class READER>
- void
- read(READER &reader, Bone &b)
- {
- unsigned int pos=reader.getPos();
- text::copyStringAndFillZero(b.name, reader.getString(20));
- reader.get(b.parent_index);
- reader.get(b.tail_index);
- b.type=static_cast<BONE_TYPE>(reader.getUchar());
- reader.get(b.ik_index);
- reader.get(b.pos);
- assert(reader.getPos()-pos==39);
- }
-
-// 11+2xIK_COUNT bytes
-template<class READER>
- void
- read(READER &reader, IK &ik)
- {
- // 11bytes
- reader.get(ik.index);
- reader.get(ik.target);
- reader.get(ik.length);
- reader.get(ik.iterations);
- reader.get(ik.weight);
- // 2 x length bytes
- for(unsigned short j=0; j<ik.length; ++j){
- ik.children.push_back(reader.getUshort());
- }
- }
-
-// 25+12xMORPH_COUNT bytes
-template<class READER>
- void
- read(READER &reader, Morph &m)
- {
- // 25bytes
- text::copyStringAndFillZero(m.name, reader.getString(20));
- reader.get(m.vertex_count);
- m.type=static_cast<MORPH_TYPE>(reader.getUchar());
- // 12 x vertex_count bytes
- for(unsigned short i=0; i<m.vertex_count; ++i){
- m.indices.push_back(reader.getUint());
- m.pos_list.push_back(Vector3());
- reader.get(m.pos_list.back());
- }
- }
-
-// 83bytes
-template<class READER>
- void
- read(READER &reader, RigidBody &r)
- {
- unsigned int pos=reader.getPos();
- text::copyStringAndFillZero(r.name, reader.getString(20));
- reader.get(r.boneIndex);
- reader.get(r.group);
- reader.get(r.target);
- r.shapeType=static_cast<SHAPE_TYPE>(reader.getUchar());
- reader.get(r.w);
- reader.get(r.h);
- reader.get(r.d);
- reader.get(r.position);
- reader.get(r.rotation);
- reader.get(r.weight);
- reader.get(r.linearDamping);
- reader.get(r.angularDamping);
- reader.get(r.restitution);
- reader.template get<float>(r.friction);
- r.processType=static_cast<PROCESS_TYPE>(reader.getUchar());
- assert(reader.getPos()-pos==83);
- }
-
-// 124bytes
-template<class READER>
- void
- read(READER &reader, Constraint &c)
- {
- unsigned int base_pos=reader.getPos();
- text::copyStringAndFillZero(c.name, reader.getString(20));
- reader.get(c.rigidA);
- reader.get(c.rigidB);
- reader.get(c.pos);
- reader.get(c.rot);
- reader.get(c.constraintPosMin);
- reader.get(c.constraintPosMax);
- reader.get(c.constraintRotMin);
- reader.get(c.constraintRotMax);
- reader.get(c.springPos);
- reader.get(c.springRot);
- assert(reader.getPos()-base_pos==124);
- }
-
-class Impl
-{
- IO &io_;
- binary::IReader &reader_;
-
-public:
- Impl(IO &io, binary::IReader &reader)
- : io_(io), reader_(reader)
- {}
-
- bool parse()
- {
- if(!parseHeader()){
- return false;
- }
- if(!parseVertices()){
- return false;
- }
- if(!parseIndices()){
- return false;
- }
- if(!parseMaterials()){
- return false;
- }
- if(!parseBones()){
- return false;
- }
- if(!parseIK()){
- return false;
- }
- if(!parseMorph()){
- return false;
- }
- if(!parseFaceList()){
- return false;
- }
- if(!parseBoneGroupList()){
- return false;
- }
- if(!parseBoneList()){
- return false;
- }
- if(reader_.isEnd()){
- return true;
- }
-
- ////////////////////////////////////////////////////////////
- // extended data
- ////////////////////////////////////////////////////////////
- // english
- ////////////////////////////////////////////////////////////
- if(reader_.getChar()){
- if(!parseEnglishName()){
- return false;
- }
- if(!parseEnglishBone()){
- return false;
- }
- if(!parseEnglishMorph()){
- return false;
- }
- if(!parseEnglishBoneList()){
- return false;
- }
- }
- if(reader_.isEnd()){
- return true;
- }
-
- // toone texture
- ////////////////////////////////////////////////////////////
- if(!parseToonTextures()){
- return false;
- }
- if(reader_.isEnd()){
- return true;
- }
-
- // physics
- ////////////////////////////////////////////////////////////
- if(!parseRigid()){
- return false;
- }
- if(!parseConstraint()){
- return false;
- }
-
- // end
- assert(reader_.isEnd());
-
- return true;
- }
-
-private:
- bool parseConstraint()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- io_.constraints.push_back(Constraint());
- read(reader_, io_.constraints.back());
- }
- return true;
- }
-
- bool parseRigid()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- io_.rigidbodies.push_back(RigidBody());
- read(reader_, io_.rigidbodies.back());
- }
- return true;
- }
-
- bool parseToonTextures()
- {
- for(size_t i=0; i<10; ++i){
- text::copyStringAndFillZero(
- io_.toon_textures[i].name,
- reader_.getString(100));
- }
- return true;
- }
-
- bool parseEnglishBoneList()
- {
- for(size_t i=0; i<io_.bone_group_list.size(); ++i){
- text::copyStringAndFillZero(
- io_.bone_group_list[i].english_name,
- reader_.getString(50));
- }
- return true;
- }
-
- bool parseEnglishMorph()
- {
- int count=io_.morph_list.size()-1;
- for(int i=0; i<count; ++i){
- text::copyStringAndFillZero(
- io_.morph_list[i].english_name, reader_.getString(20));
- }
- return true;
- }
-
- bool parseEnglishBone()
- {
- for(size_t i=0; i<io_.bones.size(); ++i){
- text::copyStringAndFillZero(
- io_.bones[i].english_name, reader_.getString(20));
- }
- return true;
- }
-
- bool parseEnglishName()
- {
- text::copyStringAndFillZero(io_.english_name,
- reader_.getString(20));
- text::copyStringAndFillZero(io_.english_comment,
- reader_.getString(256));
- return true;
- }
-
- bool parseBoneList()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- unsigned short bone=reader_.getUshort();
- unsigned char disp=reader_.getUchar();
- io_.bone_display_list.push_back(std::make_pair(bone, disp));
- }
- return true;
- }
-
- bool parseBoneGroupList()
- {
- unsigned int count=reader_.getUchar();
- for(unsigned int i=0; i<count; ++i){
- io_.bone_group_list.push_back(BoneGroup());
- text::copyStringAndFillZero(
- io_.bone_group_list.back().name,
- reader_.getString(50));
- }
- return true;
- }
-
- bool parseFaceList()
- {
- unsigned int count=reader_.getUchar();
- for(unsigned int i=0; i<count; ++i){
- io_.face_list.push_back(reader_.getUshort());
- }
- return true;
- }
-
- bool parseMorph()
- {
- unsigned int count=reader_.getUshort();
- for(unsigned int i=0; i<count; ++i){
- io_.morph_list.push_back(Morph());
- read(reader_, io_.morph_list.back());
- }
- return true;
- }
-
- bool parseIK()
- {
- unsigned int count=reader_.getUshort();
- for(unsigned int i=0; i<count; ++i){
- io_.ik_list.push_back(IK());
- read(reader_, io_.ik_list.back());
- }
- return true;
- }
-
- bool parseBones()
- {
- unsigned int count=reader_.getUshort();
- for(unsigned int i=0; i<count; ++i){
- io_.bones.push_back(Bone());
- read(reader_, io_.bones.back());
- }
- return true;
- }
-
- bool parseMaterials()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- io_.materials.push_back(new Material());
- read(reader_, *io_.materials.back());
- }
- return true;
- }
-
- bool parseIndices()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- io_.indices.push_back(reader_.getUshort());
- }
- return true;
- }
-
- bool parseVertices()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- io_.vertices.push_back(Vertex());
- read(reader_, io_.vertices.back());
- }
- return true;
- }
-
- bool parseHeader()
- {
- if(reader_.getString(3)!="Pmd"){
- //std::cout << "invalid pmd" << std::endl;
- return false;
- }
- reader_.get(io_.version);
- if(io_.version!=1.0){
- std::cout << "invalid vesion: " << io_.version <<std::endl;
- return false;
- }
- text::copyStringAndFillZero(io_.name, reader_.getString(20));
- text::copyStringAndFillZero(io_.comment, reader_.getString(256));
-
- return true;
- }
-
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// IO
-///////////////////////////////////////////////////////////////////////////////
-IO::IO()
-: version(0)
-{}
-
-IO::~IO()
-{
- for(size_t i=0; i<materials.size(); ++i){
- delete materials[i];
- }
- materials.clear();
-}
-
-bool IO::read(binary::IReader &input)
-{
- Impl impl(*this, input);
- if(!impl.parse()){
- return false;
- }
-
- ////////////////////////////////////////////////////////////
- // post process
- ////////////////////////////////////////////////////////////
- if(!morph_list.empty()){
- // validate morph
- assert(morph_list[0].type==MORPH_BASE);
- // check base
- Morph &base=morph_list[0];
- for(size_t i=0; i<base.vertex_count; ++i){
- assert(vertices[base.indices[i]].pos==base.pos_list[i]);
- }
- // check each face
- for(size_t i=1; i<morph_list.size(); ++i){
- Morph &m=morph_list[i];
- assert(m.type!=MORPH_BASE);
- }
- }
- ////////////////////////////////////////////////////////////
- // setup bone
- ////////////////////////////////////////////////////////////
- for(size_t i=0; i<bones.size(); ++i){
- Bone &bone=bones[i];
- bone.index=i;
- if(bone.parent_index!=0xFFFF){
- bone.parent=&bones[bone.parent_index];
- bone.parent->children.push_back(&bone);
- }
- if(bone.tail_index==0){
- bone.tail=Vector3(0, 0, 0);
- }
- else{
- bone.tail=bones[bone.tail_index].pos;
- }
- }
-
- return true;
-}
-
-bool IO::read(const char *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-
-#ifdef _WIN32
-bool IO::read(const wchar_t *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- std::cerr << all.size() << "bytes" << std::endl;
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-#endif
-
-bool IO::write(binary::IWriter &w)
-{
- w.write("Pmd", 3);
- w.writeValue<float>(version);
- w.write(name, 20);
- w.write(comment, 256);
-
- // vertices
- //std::cout << "vertices" << std::endl;
- w.writeValue<DWORD>(vertices.size());
- for(size_t i=0; i<vertices.size(); ++i){
- Vertex &v=vertices[i];
- w.writeValue<float>(v.pos.x);
- w.writeValue<float>(v.pos.y);
- w.writeValue<float>(v.pos.z);
- w.writeValue<float>(v.normal.x);
- w.writeValue<float>(v.normal.y);
- w.writeValue<float>(v.normal.z);
- w.writeValue<float>(v.uv.x);
- w.writeValue<float>(v.uv.y);
- w.writeValue<WORD>(v.bone0);
- w.writeValue<WORD>(v.bone1);
- w.writeValue<BYTE>(v.weight0);
- w.writeValue<BYTE>(v.edge_flag);
- }
-
- // faces
- //std::cout << "faces" << std::endl;
- w.writeValue<DWORD>(indices.size());
- if(indices.size()>0){
- w.writeArray<WORD>(&indices[0], indices.size());
- }
-
- // materials
- //std::cout << "materials" << std::endl;
- w.writeValue<DWORD>(materials.size());
- for(size_t i=0; i<materials.size(); ++i){
- Material &m=*materials[i];
- w.writeValue<float>(m.diffuse.r);
- w.writeValue<float>(m.diffuse.g);
- w.writeValue<float>(m.diffuse.b);
- w.writeValue<float>(m.diffuse.a);
- w.writeValue<float>(m.shinness);
- w.writeValue<float>(m.specular.r);
- w.writeValue<float>(m.specular.g);
- w.writeValue<float>(m.specular.b);
- w.writeValue<float>(m.ambient.r);
- w.writeValue<float>(m.ambient.g);
- w.writeValue<float>(m.ambient.b);
- w.writeValue<BYTE>(m.toon_index);
- w.writeValue<BYTE>(m.flag);
- w.writeValue<DWORD>(m.vertex_count);
- w.writeArray<char>(m.texture, 20);
- }
-
- // bones
- //std::cout << "bones" << std::endl;
- w.writeValue<WORD>(bones.size());
- for(size_t i=0; i<bones.size(); ++i){
- Bone &b=bones[i];
- w.writeArray<char>(b.name, 20);
- w.writeValue<WORD>(b.parent_index);
- w.writeValue<WORD>(b.tail_index);
- w.writeValue<BYTE>(b.type);
- w.writeValue<WORD>(b.ik_index);
- w.writeValue<float>(b.pos.x);
- w.writeValue<float>(b.pos.y);
- w.writeValue<float>(b.pos.z);
- }
-
- // ik
- //std::cout << "ik" << std::endl;
- w.writeValue<WORD>(ik_list.size());
- for(size_t i=0; i<ik_list.size(); ++i){
- IK &ik=ik_list[i];
- w.writeValue<WORD>(ik.index);
- w.writeValue<WORD>(ik.target);
- w.writeValue<BYTE>(ik.length);
- w.writeValue<WORD>(ik.iterations);
- w.writeValue<float>(ik.weight);
- WORD parent_index=bones[ik.target].parent_index;
- for(size_t j=0; j<ik.length;
- ++j, parent_index=bones[parent_index].parent_index){
- w.writeValue<WORD>(parent_index);
- }
- }
-
- // morph
- //std::cout << "morph" << std::endl;
- w.writeValue<WORD>(morph_list.size());
- for(size_t i=0; i<morph_list.size(); ++i){
- Morph &m=morph_list[i];
- w.writeArray<char>(m.name, 20);
- w.writeValue<DWORD>(m.indices.size());
- w.writeValue<BYTE>(m.type);
- for(size_t j=0; j<m.indices.size(); ++j){
- w.writeValue<DWORD>(m.indices[j]);
- Vector3 &pos=m.pos_list[j];
- w.writeValue<float>(pos.x);
- w.writeValue<float>(pos.y);
- w.writeValue<float>(pos.z);
- }
- }
-
- // face list
- //std::cout << "face list" << std::endl;
- w.writeValue<BYTE>(face_list.size());
- if(face_list.size()>0){
- w.writeArray<WORD>(&face_list[0], face_list.size());
- }
-
- // bone name list
- //std::cout << "bone name list" << std::endl;
- w.writeValue<BYTE>(bone_group_list.size());
- for(size_t i=0; i<bone_group_list.size(); ++i){
- // 50bytes
- w.writeArray<char>(bone_group_list[i].name, 50);
- }
-
- // bone list
- //std::cout << "bone list" << std::endl;
- w.writeValue<DWORD>(bone_display_list.size());
- for(size_t i=0; i<bone_display_list.size(); ++i){
- w.writeValue<WORD>(bone_display_list[i].first);
- w.writeValue<BYTE>(bone_display_list[i].second);
- }
-
- ////////////////////////////////////////////////////////////
- // extend
- ////////////////////////////////////////////////////////////
- w.writeValue<char>(0x01);
-
- ////////////////////////////////////////////////////////////
- // english names
- ////////////////////////////////////////////////////////////
- w.writeArray<char>(english_name, 20);
- w.writeArray<char>(english_comment, 256);
-
- for(size_t i=0; i<bones.size(); ++i){
- w.writeArray<char>(bones[i].english_name, 20);
- }
-
- // skip base
- for(size_t i=1; i<morph_list.size(); ++i){
- w.writeArray<char>(morph_list[i].english_name, 20);
- }
-
- for(size_t i=0; i<bone_group_list.size(); ++i){
- w.writeArray<char>(bone_group_list[i].english_name, 50);
- }
-
- ////////////////////////////////////////////////////////////
- // toon textures
- ////////////////////////////////////////////////////////////
- for(size_t i=0; i<10; ++i){
- w.writeArray<char>(toon_textures[i].name, 100);
- }
-
- ////////////////////////////////////////////////////////////
- // rigid bodies
- ////////////////////////////////////////////////////////////
- w.writeValue<DWORD>(rigidbodies.size());
- for(size_t i=0; i<rigidbodies.size(); ++i){
- RigidBody &rb=rigidbodies[i];
- w.writeArray<char>(rb.name, 20);
- w.writeValue<WORD>(rb.boneIndex);
- w.writeValue<BYTE>(rb.group);
- w.writeValue<WORD>(rb.target);
- w.writeValue<BYTE>(rb.shapeType);
- w.writeValue<float>(rb.w);
- w.writeValue<float>(rb.h);
- w.writeValue<float>(rb.d);
- w.writeValue<float>(rb.position.x);
- w.writeValue<float>(rb.position.y);
- w.writeValue<float>(rb.position.z);
- w.writeValue<float>(rb.rotation.x);
- w.writeValue<float>(rb.rotation.y);
- w.writeValue<float>(rb.rotation.z);
- w.writeValue<float>(rb.weight);
- w.writeValue<float>(rb.linearDamping);
- w.writeValue<float>(rb.angularDamping);
- w.writeValue<float>(rb.restitution);
- w.writeValue<float>(rb.friction);
- w.writeValue<BYTE>(rb.processType);
- }
-
- ////////////////////////////////////////////////////////////
- // constraints
- ////////////////////////////////////////////////////////////
- w.writeValue<DWORD>(constraints.size());
- for(size_t i=0; i<constraints.size(); ++i){
- Constraint &c=constraints[i];
- w.writeArray<char>(c.name, 20);
- w.writeValue<DWORD>(c.rigidA);
- w.writeValue<DWORD>(c.rigidB);
- w.writeValue<float>(c.pos.x);
- w.writeValue<float>(c.pos.y);
- w.writeValue<float>(c.pos.z);
- w.writeValue<float>(c.rot.x);
- w.writeValue<float>(c.rot.y);
- w.writeValue<float>(c.rot.z);
- w.writeValue<float>(c.constraintPosMin.x);
- w.writeValue<float>(c.constraintPosMin.y);
- w.writeValue<float>(c.constraintPosMin.z);
- w.writeValue<float>(c.constraintPosMax.x);
- w.writeValue<float>(c.constraintPosMax.y);
- w.writeValue<float>(c.constraintPosMax.z);
- w.writeValue<float>(c.constraintRotMin.x);
- w.writeValue<float>(c.constraintRotMin.y);
- w.writeValue<float>(c.constraintRotMin.z);
- w.writeValue<float>(c.constraintRotMax.x);
- w.writeValue<float>(c.constraintRotMax.y);
- w.writeValue<float>(c.constraintRotMax.z);
- w.writeValue<float>(c.springPos.x);
- w.writeValue<float>(c.springPos.y);
- w.writeValue<float>(c.springPos.z);
- w.writeValue<float>(c.springRot.x);
- w.writeValue<float>(c.springRot.y);
- w.writeValue<float>(c.springRot.z);
- }
-
- return true;
-}
-
-
-} // namespace
-} // namespace
+ namespace pmd {
+
+ // IO
+ bool IO::write(const char *path)
+ {
+ binary::FileWriter w(path);
+ return write(w);
+ }
+
+ // 38bytes
+ template<class READER>
+ void
+ read(READER &reader, Vertex &v)
+ {
+ unsigned int pos=reader.getPos();
+ reader.get(v.pos);
+ reader.get(v.normal);
+ reader.get(v.uv);
+ reader.get(v.bone0);
+ reader.get(v.bone1);
+ reader.get(v.weight0);
+ reader.get(v.edge_flag);
+ assert(reader.getPos()-pos==38);
+ }
+
+ // 70bytes
+ template<class READER>
+ void
+ read(READER &reader, Material &m)
+ {
+ unsigned int pos=reader.getPos();
+ reader.get(m.diffuse);
+ reader.get(m.shinness);
+ reader.get(m.specular);
+ reader.get(m.ambient);
+ reader.get(m.toon_index);
+ reader.get(m.flag);
+ reader.get(m.vertex_count);
+ reader.get(m.texture);
+ assert(reader.getPos()-pos==70);
+ }
+
+ // 39bytes
+ template<class READER>
+ void
+ read(READER &reader, Bone &b)
+ {
+ unsigned int pos=reader.getPos();
+ reader.get(b.name);
+ reader.get(b.parent_index);
+ reader.get(b.tail_index);
+ b.type=static_cast<BONE_TYPE>(reader.getUchar());
+ reader.get(b.ik_index);
+ reader.get(b.pos);
+ assert(reader.getPos()-pos==39);
+ }
+
+ // 11+2xIK_COUNT bytes
+ template<class READER>
+ void
+ read(READER &reader, IK &ik)
+ {
+ // 11bytes
+ reader.get(ik.index);
+ reader.get(ik.target);
+ reader.get(ik.length);
+ reader.get(ik.iterations);
+ reader.get(ik.weight);
+ // 2 x length bytes
+ for(unsigned short j=0; j<ik.length; ++j){
+ ik.children.push_back(reader.getUshort());
+ }
+ }
+
+ // 25+12xMORPH_COUNT bytes
+ template<class READER>
+ void
+ read(READER &reader, Morph &m)
+ {
+ // 25bytes
+ reader.get(m.name);
+ reader.get(m.vertex_count);
+ m.type=static_cast<MORPH_TYPE>(reader.getUchar());
+ // 12 x vertex_count bytes
+ for(unsigned short i=0; i<m.vertex_count; ++i){
+ m.indices.push_back(reader.getUint());
+ m.pos_list.push_back(Vector3());
+ reader.get(m.pos_list.back());
+ }
+ }
+
+ // 83bytes
+ template<class READER>
+ void
+ read(READER &reader, RigidBody &r)
+ {
+ unsigned int pos=reader.getPos();
+ reader.get(r.name);
+ reader.get(r.boneIndex);
+ reader.get(r.group);
+ reader.get(r.target);
+ r.shapeType=static_cast<SHAPE_TYPE>(reader.getUchar());
+ reader.get(r.w);
+ reader.get(r.h);
+ reader.get(r.d);
+ reader.get(r.position);
+ reader.get(r.rotation);
+ reader.get(r.weight);
+ reader.get(r.linearDamping);
+ reader.get(r.angularDamping);
+ reader.get(r.restitution);
+ reader.template get<float>(r.friction);
+ r.processType=static_cast<PROCESS_TYPE>(reader.getUchar());
+ assert(reader.getPos()-pos==83);
+ }
+
+ // 124bytes
+ template<class READER>
+ void
+ read(READER &reader, Constraint &c)
+ {
+ unsigned int base_pos=reader.getPos();
+ reader.get(c.name);
+ reader.get(c.rigidA);
+ reader.get(c.rigidB);
+ reader.get(c.pos);
+ reader.get(c.rot);
+ reader.get(c.constraintPosMin);
+ reader.get(c.constraintPosMax);
+ reader.get(c.constraintRotMin);
+ reader.get(c.constraintRotMax);
+ reader.get(c.springPos);
+ reader.get(c.springRot);
+ assert(reader.getPos()-base_pos==124);
+ }
+
+ class Impl
+ {
+ IO &io_;
+ binary::IReader &reader_;
+
+ public:
+ Impl(IO &io, binary::IReader &reader)
+ : io_(io), reader_(reader)
+ {}
+
+ bool parse()
+ {
+ if(!parseHeader()){
+ return false;
+ }
+ if(!parseVertices()){
+ return false;
+ }
+ if(!parseIndices()){
+ return false;
+ }
+ if(!parseMaterials()){
+ return false;
+ }
+ if(!parseBones()){
+ return false;
+ }
+ if(!parseIK()){
+ return false;
+ }
+ if(!parseMorph()){
+ return false;
+ }
+ if(!parseFaceList()){
+ return false;
+ }
+ if(!parseBoneGroupList()){
+ return false;
+ }
+ if(!parseBoneList()){
+ return false;
+ }
+ if(reader_.isEnd()){
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////
+ // extended data
+ ////////////////////////////////////////////////////////////
+ // english
+ ////////////////////////////////////////////////////////////
+ if(reader_.getChar()){
+ if(!parseEnglishName()){
+ return false;
+ }
+ if(!parseEnglishBone()){
+ return false;
+ }
+ if(!parseEnglishMorph()){
+ return false;
+ }
+ if(!parseEnglishBoneList()){
+ return false;
+ }
+ }
+ if(reader_.isEnd()){
+ return true;
+ }
+
+ // toone texture
+ ////////////////////////////////////////////////////////////
+ if(!parseToonTextures()){
+ return false;
+ }
+ if(reader_.isEnd()){
+ return true;
+ }
+
+ // physics
+ ////////////////////////////////////////////////////////////
+ if(!parseRigid()){
+ return false;
+ }
+ if(!parseConstraint()){
+ return false;
+ }
+
+ // end
+ assert(reader_.isEnd());
+
+ return true;
+ }
+
+ private:
+ bool parseConstraint()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ io_.constraints.push_back(Constraint());
+ read(reader_, io_.constraints.back());
+ }
+ return true;
+ }
+
+ bool parseRigid()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ io_.rigidbodies.push_back(RigidBody());
+ read(reader_, io_.rigidbodies.back());
+ }
+ return true;
+ }
+
+ bool parseToonTextures()
+ {
+ for(size_t i=0; i<10; ++i){
+ reader_.get(io_.toon_textures[i]);
+ }
+ return true;
+ }
+
+ bool parseEnglishBoneList()
+ {
+ for(size_t i=0; i<io_.bone_group_list.size(); ++i){
+ reader_.get(io_.bone_group_list[i].english_name);
+ }
+ return true;
+ }
+
+ bool parseEnglishMorph()
+ {
+ int count=io_.morph_list.size()-1;
+ for(int i=0; i<count; ++i){
+ reader_.get(io_.morph_list[i].english_name);
+ }
+ return true;
+ }
+
+ bool parseEnglishBone()
+ {
+ for(size_t i=0; i<io_.bones.size(); ++i){
+ reader_.get(io_.bones[i].english_name);
+ }
+ return true;
+ }
+
+ bool parseEnglishName()
+ {
+ reader_.get(io_.english_name);
+ reader_.get(io_.english_comment);
+ return true;
+ }
+
+ bool parseBoneList()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ unsigned short bone=reader_.getUshort();
+ unsigned char disp=reader_.getUchar();
+ io_.bone_display_list.push_back(std::make_pair(bone, disp));
+ }
+ return true;
+ }
+
+ bool parseBoneGroupList()
+ {
+ unsigned int count=reader_.getUchar();
+ for(unsigned int i=0; i<count; ++i){
+ io_.bone_group_list.push_back(BoneGroup());
+ reader_.get(io_.bone_group_list.back().name);
+ }
+ return true;
+ }
+
+ bool parseFaceList()
+ {
+ unsigned int count=reader_.getUchar();
+ for(unsigned int i=0; i<count; ++i){
+ io_.face_list.push_back(reader_.getUshort());
+ }
+ return true;
+ }
+
+ bool parseMorph()
+ {
+ unsigned int count=reader_.getUshort();
+ for(unsigned int i=0; i<count; ++i){
+ io_.morph_list.push_back(Morph());
+ read(reader_, io_.morph_list.back());
+ }
+ return true;
+ }
+
+ bool parseIK()
+ {
+ unsigned int count=reader_.getUshort();
+ for(unsigned int i=0; i<count; ++i){
+ io_.ik_list.push_back(IK());
+ read(reader_, io_.ik_list.back());
+ }
+ return true;
+ }
+
+ bool parseBones()
+ {
+ unsigned int count=reader_.getUshort();
+ for(unsigned int i=0; i<count; ++i){
+ io_.bones.push_back(Bone());
+ read(reader_, io_.bones.back());
+ }
+ return true;
+ }
+
+ bool parseMaterials()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ io_.materials.push_back(Material());
+ read(reader_, io_.materials.back());
+ }
+ return true;
+ }
+
+ bool parseIndices()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ io_.indices.push_back(reader_.getUshort());
+ }
+ return true;
+ }
+
+ bool parseVertices()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ io_.vertices.push_back(Vertex());
+ read(reader_, io_.vertices.back());
+ }
+ return true;
+ }
+
+ bool parseHeader()
+ {
+ if(reader_.getString(3)!="Pmd"){
+ //std::cout << "invalid pmd" << std::endl;
+ return false;
+ }
+ reader_.get(io_.version);
+ if(io_.version!=1.0){
+ std::cout << "invalid vesion: " << io_.version <<std::endl;
+ return false;
+ }
+ reader_.get(io_.name);
+ reader_.get(io_.comment);
+ return true;
+ }
+
+ };
+
+ // IO
+ IO::IO()
+ : version(0)
+ {
+ int i=1;
+ for(auto it=toon_textures.begin(); it!=toon_textures.end(); ++it){
+ char toon[100];
+ sprintf(toon, "toon%02d.bmp", i);
+ *it=toon;
+ }
+ }
+
+ bool IO::read(binary::IReader &input)
+ {
+ Impl impl(*this, input);
+ if(!impl.parse()){
+ return false;
+ }
+
+ ////////////////////////////////////////////////////////////
+ // post process
+ ////////////////////////////////////////////////////////////
+ if(!morph_list.empty()){
+ // validate morph
+ assert(morph_list[0].type==MORPH_BASE);
+ // check base
+ Morph &base=morph_list[0];
+ for(size_t i=0; i<base.vertex_count; ++i){
+ assert(vertices[base.indices[i]].pos==base.pos_list[i]);
+ }
+ // check each face
+ for(size_t i=1; i<morph_list.size(); ++i){
+ Morph &m=morph_list[i];
+ assert(m.type!=MORPH_BASE);
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ // setup bone
+ ////////////////////////////////////////////////////////////
+ for(size_t i=0; i<bones.size(); ++i){
+ Bone &bone=bones[i];
+ bone.index=i;
+ if(bone.parent_index!=0xFFFF){
+ bone.parent=&bones[bone.parent_index];
+ bone.parent->children.push_back(&bone);
+ }
+ if(bone.tail_index==0){
+ bone.tail=Vector3(0, 0, 0);
+ }
+ else{
+ bone.tail=bones[bone.tail_index].pos;
+ }
+ }
+
+ return true;
+ }
+
+ bool IO::read(const char *path)
+ {
+ std::vector<char> all;
+ binary::readAll(path, all);
+ if(all.empty()){
+ return false;
+ }
+ binary::MemoryReader reader(&all[0], all.size());
+ return read(reader);
+ }
+
+ bool IO::write(binary::IWriter &w)
+ {
+ w.write("Pmd", 3);
+ w.writeValue<float>(version);
+ w.write(name);
+ w.write(comment);
+
+ // vertices
+ //std::cout << "vertices" << std::endl;
+ w.writeValue<DWORD>(vertices.size());
+ for(size_t i=0; i<vertices.size(); ++i){
+ Vertex &v=vertices[i];
+ w.writeValue<float>(v.pos.x);
+ w.writeValue<float>(v.pos.y);
+ w.writeValue<float>(v.pos.z);
+ w.writeValue<float>(v.normal.x);
+ w.writeValue<float>(v.normal.y);
+ w.writeValue<float>(v.normal.z);
+ w.writeValue<float>(v.uv.x);
+ w.writeValue<float>(v.uv.y);
+ w.writeValue<WORD>(v.bone0);
+ w.writeValue<WORD>(v.bone1);
+ w.writeValue<BYTE>(v.weight0);
+ w.writeValue<BYTE>(v.edge_flag);
+ }
+
+ // faces
+ //std::cout << "faces" << std::endl;
+ w.writeValue<DWORD>(indices.size());
+ if(indices.size()>0){
+ w.writeArray<WORD>(&indices[0], indices.size());
+ }
+
+ // materials
+ //std::cout << "materials" << std::endl;
+ w.writeValue<DWORD>(materials.size());
+ for(size_t i=0; i<materials.size(); ++i){
+ Material &m=materials[i];
+ w.writeValue<float>(m.diffuse.r);
+ w.writeValue<float>(m.diffuse.g);
+ w.writeValue<float>(m.diffuse.b);
+ w.writeValue<float>(m.diffuse.a);
+ w.writeValue<float>(m.shinness);
+ w.writeValue<float>(m.specular.r);
+ w.writeValue<float>(m.specular.g);
+ w.writeValue<float>(m.specular.b);
+ w.writeValue<float>(m.ambient.r);
+ w.writeValue<float>(m.ambient.g);
+ w.writeValue<float>(m.ambient.b);
+ w.writeValue<BYTE>(m.toon_index);
+ w.writeValue<BYTE>(m.flag);
+ w.writeValue<DWORD>(m.vertex_count);
+ w.write(m.texture);
+ }
+
+ // bones
+ //std::cout << "bones" << std::endl;
+ w.writeValue<WORD>(bones.size());
+ for(size_t i=0; i<bones.size(); ++i){
+ Bone &b=bones[i];
+ w.write(b.name);
+ w.writeValue<WORD>(b.parent_index);
+ w.writeValue<WORD>(b.tail_index);
+ w.writeValue<BYTE>(b.type);
+ w.writeValue<WORD>(b.ik_index);
+ w.writeValue<float>(b.pos.x);
+ w.writeValue<float>(b.pos.y);
+ w.writeValue<float>(b.pos.z);
+ }
+
+ // ik
+ //std::cout << "ik" << std::endl;
+ w.writeValue<WORD>(ik_list.size());
+ for(size_t i=0; i<ik_list.size(); ++i){
+ IK &ik=ik_list[i];
+ w.writeValue<WORD>(ik.index);
+ w.writeValue<WORD>(ik.target);
+ w.writeValue<BYTE>(ik.length);
+ w.writeValue<WORD>(ik.iterations);
+ w.writeValue<float>(ik.weight);
+ WORD parent_index=bones[ik.target].parent_index;
+ for(size_t j=0; j<ik.length;
+ ++j, parent_index=bones[parent_index].parent_index){
+ w.writeValue<WORD>(parent_index);
+ }
+ }
+
+ // morph
+ //std::cout << "morph" << std::endl;
+ w.writeValue<WORD>(morph_list.size());
+ for(size_t i=0; i<morph_list.size(); ++i){
+ Morph &m=morph_list[i];
+ w.write(m.name);
+ w.writeValue<DWORD>(m.indices.size());
+ w.writeValue<BYTE>(m.type);
+ for(size_t j=0; j<m.indices.size(); ++j){
+ w.writeValue<DWORD>(m.indices[j]);
+ Vector3 &pos=m.pos_list[j];
+ w.writeValue<float>(pos.x);
+ w.writeValue<float>(pos.y);
+ w.writeValue<float>(pos.z);
+ }
+ }
+
+ // face list
+ //std::cout << "face list" << std::endl;
+ w.writeValue<BYTE>(face_list.size());
+ if(face_list.size()>0){
+ w.writeArray<WORD>(&face_list[0], face_list.size());
+ }
+
+ // bone name list
+ //std::cout << "bone name list" << std::endl;
+ w.writeValue<BYTE>(bone_group_list.size());
+ for(size_t i=0; i<bone_group_list.size(); ++i){
+ // 50bytes
+ w.write(bone_group_list[i].name);
+ }
+
+ // bone list
+ //std::cout << "bone list" << std::endl;
+ w.writeValue<DWORD>(bone_display_list.size());
+ for(size_t i=0; i<bone_display_list.size(); ++i){
+ w.writeValue<WORD>(bone_display_list[i].first);
+ w.writeValue<BYTE>(bone_display_list[i].second);
+ }
+
+ ////////////////////////////////////////////////////////////
+ // extend
+ ////////////////////////////////////////////////////////////
+ w.writeValue<char>(0x01);
+
+ ////////////////////////////////////////////////////////////
+ // english names
+ ////////////////////////////////////////////////////////////
+ w.write(english_name);
+ w.write(english_comment);
+
+ for(size_t i=0; i<bones.size(); ++i){
+ w.write(bones[i].english_name);
+ }
+
+ // skip base
+ for(size_t i=1; i<morph_list.size(); ++i){
+ w.write(morph_list[i].english_name);
+ }
+
+ for(size_t i=0; i<bone_group_list.size(); ++i){
+ w.write(bone_group_list[i].english_name);
+ }
+
+ ////////////////////////////////////////////////////////////
+ // toon textures
+ ////////////////////////////////////////////////////////////
+ for(size_t i=0; i<10; ++i){
+ w.write(toon_textures[i]);
+ }
+
+ ////////////////////////////////////////////////////////////
+ // rigid bodies
+ ////////////////////////////////////////////////////////////
+ w.writeValue<DWORD>(rigidbodies.size());
+ for(size_t i=0; i<rigidbodies.size(); ++i){
+ RigidBody &rb=rigidbodies[i];
+ w.write(rb.name);
+ w.writeValue<WORD>(rb.boneIndex);
+ w.writeValue<BYTE>(rb.group);
+ w.writeValue<WORD>(rb.target);
+ w.writeValue<BYTE>(rb.shapeType);
+ w.writeValue<float>(rb.w);
+ w.writeValue<float>(rb.h);
+ w.writeValue<float>(rb.d);
+ w.writeValue<float>(rb.position.x);
+ w.writeValue<float>(rb.position.y);
+ w.writeValue<float>(rb.position.z);
+ w.writeValue<float>(rb.rotation.x);
+ w.writeValue<float>(rb.rotation.y);
+ w.writeValue<float>(rb.rotation.z);
+ w.writeValue<float>(rb.weight);
+ w.writeValue<float>(rb.linearDamping);
+ w.writeValue<float>(rb.angularDamping);
+ w.writeValue<float>(rb.restitution);
+ w.writeValue<float>(rb.friction);
+ w.writeValue<BYTE>(rb.processType);
+ }
+
+ ////////////////////////////////////////////////////////////
+ // constraints
+ ////////////////////////////////////////////////////////////
+ w.writeValue<DWORD>(constraints.size());
+ for(size_t i=0; i<constraints.size(); ++i){
+ Constraint &c=constraints[i];
+ w.write(c.name);
+ w.writeValue<DWORD>(c.rigidA);
+ w.writeValue<DWORD>(c.rigidB);
+ w.writeValue<float>(c.pos.x);
+ w.writeValue<float>(c.pos.y);
+ w.writeValue<float>(c.pos.z);
+ w.writeValue<float>(c.rot.x);
+ w.writeValue<float>(c.rot.y);
+ w.writeValue<float>(c.rot.z);
+ w.writeValue<float>(c.constraintPosMin.x);
+ w.writeValue<float>(c.constraintPosMin.y);
+ w.writeValue<float>(c.constraintPosMin.z);
+ w.writeValue<float>(c.constraintPosMax.x);
+ w.writeValue<float>(c.constraintPosMax.y);
+ w.writeValue<float>(c.constraintPosMax.z);
+ w.writeValue<float>(c.constraintRotMin.x);
+ w.writeValue<float>(c.constraintRotMin.y);
+ w.writeValue<float>(c.constraintRotMin.z);
+ w.writeValue<float>(c.constraintRotMax.x);
+ w.writeValue<float>(c.constraintRotMax.y);
+ w.writeValue<float>(c.constraintRotMax.z);
+ w.writeValue<float>(c.springPos.x);
+ w.writeValue<float>(c.springPos.y);
+ w.writeValue<float>(c.springPos.z);
+ w.writeValue<float>(c.springRot.x);
+ w.writeValue<float>(c.springRot.y);
+ w.writeValue<float>(c.springRot.z);
+ }
+
+ return true;
+ }
+
+
+ } // namespace pmd
+} // namespace meshio
#ifndef MESH_IO_PMD_H_INCLUDED
#define MESH_IO_PMD_H_INCLUDED
-#include <ostream>
-#include <vector>
#include "la.h"
#include "text.h"
+#include "binary.h"
+#include <ostream>
+#include <vector>
+#include <array>
namespace meshio {
-namespace pmd {
-
-typedef ::meshio::la::Vector2 Vector2;
-typedef ::meshio::la::Vector3 Vector3;
-typedef ::meshio::la::Vector4 Vector4;
-typedef ::meshio::color::fRGBA fRGBA;
-typedef ::meshio::color::fRGB fRGB;
-
-////////////////////////////////////////////////////////////
-//! \92¸\93_
-////////////////////////////////////////////////////////////
-struct Vertex
-{
- //! \8dÀ\95W
- Vector3 pos;
- //! \96@\90ü\83x\83N\83g\83\8b
- Vector3 normal;
- //! \83e\83N\83X\83`\83\83UV
- Vector2 uv;
- //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\931
- unsigned short bone0;
- //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\932
- unsigned short bone1;
- //! \83E\83F\83C\83g[0 - 100]
- unsigned char weight0;
- //! \94ñ\83G\83b\83W
- unsigned char edge_flag;
-};
-inline std::ostream &operator<<(std::ostream &os, const Vertex &rhs)
-{
- os
- << "[Vertex"
- << " pos:" << rhs.pos
- << " normal:" << rhs.normal
- << " uv:" << rhs.uv
- << " bone0:" << rhs.bone0
- << " bone1:" << rhs.bone1
- << " weight0:" << (int)rhs.weight0
- << " edge_flag:" << (int)rhs.edge_flag
- << "]"
- ;
- return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \8dÞ\8e¿
-////////////////////////////////////////////////////////////
-struct Material
-{
- //! Diffuse
- fRGBA diffuse;
- //! Shinness
- float shinness;
- //! Specular
- fRGB specular;
- //! Ambient
- fRGB ambient;
- //! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
- unsigned char toon_index;
- //! \97Ö\8as/\89e
- unsigned char flag;
- //! \96Ê\92¸\93_\90\94
- unsigned int vertex_count;
- //! \83e\83N\83X\83`\83\83
- char texture[20];
-
- std::wstring getTexture()const;
- void setTexture(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os,
- const Material &rhs)
-{
- os
- << "[Material"
- << " diffuse:" << rhs.diffuse
- << " toon_index:" << (int)rhs.toon_index
- << " flag:" << (int)rhs.flag
- << " vertex_count:" << rhs.vertex_count
- << " texture:" << rhs.texture
- << "]"
- ;
- return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93\82Ì\8eí\97Þ
-enum BONE_TYPE
-{
- // \89ñ\93]
- BONE_ROTATE=0,
- // \89ñ\93]\82Æ\88Ú\93®
- BONE_ROTATE_MOVE,
- // IK
- BONE_IK,
- // \95s\96¾
- BONE_UNKNOWN,
- // IK\89e\8b¿\89º
- BONE_IK_INFLUENCED,
- // \89ñ\93]\89e\8b¿\89º
- BONE_ROTATE_INFLUENCED,
- // IK\90Ú\91±\90æ
- BONE_IK_CONNECT,
- // \94ñ\95\\8e¦
- BONE_INVISIBLE,
- // \94P\82è
- BONE_TWIST,
- // \89ñ\93]\98A\93®
- BONE_REVOLVE,
-};
-struct Bone
-{
- //! \96¼\91O
- char name[20];
- //! \90e\83{\81[\83\93
- unsigned short parent_index;
- //! \8eq\83{\81[\83\93
- unsigned short tail_index;
- //! \83{\81[\83\93\8eí\97Þ
- BONE_TYPE type;
- //! \89e\8b¿IK\83{\81[\83\93
- unsigned short ik_index;
- // \83{\81[\83\93\8dÀ\95W
- Vector3 pos;
- //! \89p\8cê\96¼
- char english_name[20];
- //! \83{\81[\83\93\8aK\91w\8d\\92z\97p
- Bone* parent;
- Vector3 tail;
- std::vector<Bone*> children;
- unsigned short index;
-
- Bone()
- : parent(0)
- {}
- std::wstring getName()const;
- void setName(const char *src);
- void setEnglishName(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os,
- const Bone &rhs)
-{
- os
- << "[Bone "
- << '"' << rhs.name << '"'
- << "]"
- ;
- return os;
-}
-
-////////////////////////////////////////////////////////////
-//! IK
-////////////////////////////////////////////////////////////
-struct IK
-{
- //! IK(IK\83^\81[\83Q\83b\83g)
- unsigned short index;
- //! Target(\83G\83t\83F\83N\83^\81[)
- unsigned short target;
- //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93\90\94
- unsigned char length;
- //! IK\92l1\81BCCD-IK\8e\8e\8ds\89ñ\90\94
- unsigned short iterations;
- //! IK\92l2\81BCCD-IK\8e\8e\8ds\88ê\89ñ\95Ó\82è\82Ì\89e\8b¿\93x
- float weight;
- //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93(\8aî\96{\93I\82É\90e\83{\81[\83\93\82É\91k\82é)
- std::vector<unsigned short> children;
-};
-inline std::ostream &operator<<(std::ostream &os, const IK &rhs)
-{
- os
- << "[IK "
- << "]"
- ;
- return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \95\\8fî
-////////////////////////////////////////////////////////////
-//! \95\\8fî\82Ì\8eí\97Þ
-enum MORPH_TYPE
-{
- //! \83x\81[\83X\95\\8fî
- MORPH_BASE=0,
- //! \82Ü\82ä
- MORPH_MAYU,
- //! \96Ú
- MORPH_ME,
- //! \83\8a\83b\83v
- MORPH_LIP,
- //! \82»\82Ì\91¼
- MORPH_OTHER,
-};
-struct Morph
-{
- //! \95\\8fî\96¼
- char name[20];
- //! \8eg\97p\82·\82é\92¸\93_\90\94
- unsigned int vertex_count;
- //! \95ª\97Þ
- unsigned char type;
- //! \92¸\93_Index
- std::vector<unsigned int> indices;
- //! \88Ú\93®\97Ê
- std::vector<Vector3> pos_list;
- //! \89p\8cê\96¼
- char english_name[20];
-
- void append(int index, float x, float y, float z);
- std::wstring getName()const;
- void setName(const char *src);
- void setEnglishName(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os, const Morph &rhs)
-{
- os
- << "[Morph "
- << '"' << rhs.name << '"'
- << "]"
- ;
- return os;
-}
-
-////////////////////////////////////////////////////////////
-//! \83{\81[\83\93\95\\8e¦\98g
-////////////////////////////////////////////////////////////
-struct BoneGroup
-{
- char name[50];
- char english_name[50];
-
- void setName(const char *src);
- void setEnglishName(const char *src);
- std::wstring getName()const;
-};
-
-////////////////////////////////////////////////////////////
-//! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
-////////////////////////////////////////////////////////////
-struct ToonTexture
-{
- char name[100];
- std::wstring getName()const;
- void setName(const char *src);
-};
-
-////////////////////////////////////////////////////////////
-//! \8d\84\91Ì
-////////////////////////////////////////////////////////////
-//! \8c`\8fó
-enum SHAPE_TYPE
-{
- //! \8b\85
- SHAPE_SPHERE=0,
- //! \94
- SHAPE_BOX,
- //! \83J\83v\83Z\83\8b
- SHAPE_CAPSULE,
-};
-//! \8d\84\91Ì\83^\83C\83v
-enum PROCESS_TYPE
-{
- //! \83{\81[\83\93\82Æ\93¯\82¶\93®\82«
- RIGIDBODY_KINEMATICS=0,
- //! \95¨\97\9d\89\89\8eZ
- RIGIDBODY_PHYSICS,
- //! \95¨\97\9d\89\89\8eZ\8c\8b\89Ê\82ð\83{\81[\83\93\82É\94½\89f\82·\82é
- RIGIDBODY_PHYSICS_WITH_BONE,
-};
-
-struct RigidBody
-{
- //! \8d\84\91Ì\96¼
- char name[20];
- //! \8aÖ\98A\83{\81[\83\93(\83{\81[\83\93\92Ç\8f]\82Æ\83{\81[\83\93\88Ê\92u\8d\87\82í\82¹\82Å\95K\97v)
- unsigned short boneIndex;
- //! \83O\83\8b\81[\83v
- unsigned char group;
- //! \94ñ\8fÕ\93Ë\83O\83\8b\81[\83v
- unsigned short target;
- //! \8c`\8fó
- SHAPE_TYPE shapeType;
- //! \83T\83C\83Y
- float w;
- float h;
- float d;
- //! \8ep\90¨
- Vector3 position;
- Vector3 rotation;
- //! \8e¿\97Ê
- float weight;
- //! \95¨\97\9d\89\89\8eZ\83p\83\89\83\81\81[\83^(bullet)
- float linearDamping;
- float angularDamping;
- float restitution;
- float friction;
- //! \8d\84\91Ì\83^\83C\83v
- PROCESS_TYPE processType;
-
- std::wstring getName()const;
- void setName(const char *src);
-};
-
-//! Joint(\95¨\97\9d\89\89\8eZ\82Å\82ÌJoint\82ÆConstraint\82Í\93¯\82¶\88Ó\96¡)
-struct Constraint
-{
- //! Joint\96¼
- char name[20];
- //! \90Ú\91±\8d\84\91ÌA
- unsigned int rigidA;
- //! \90Ú\91±\8d\84\91ÌB
- unsigned int rigidB;
- //! \88Ê\92u
- Vector3 pos;
- //! \89ñ\93]
- Vector3 rot;
- //! \88Ú\93®\90§\8cÀ
- Vector3 constraintPosMin;
- Vector3 constraintPosMax;
- //! \89ñ\93]\90§\8cÀ
- Vector3 constraintRotMin;
- Vector3 constraintRotMax;
- //! \82Î\82Ë
- Vector3 springPos;
- Vector3 springRot;
-
- std::wstring getName()const;
- void setName(const char *src);
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// IO
-///////////////////////////////////////////////////////////////////////////////
-struct IO
-{
- float version;
- char name[20];
- char comment[256];
- std::vector<Vertex> vertices;
- std::vector<unsigned short> indices;
- std::vector<Material*> materials;
- std::vector<Bone> bones;
- std::vector<IK> ik_list;
- std::vector<Morph> morph_list;
- std::vector<unsigned short> face_list;
- std::vector<BoneGroup> bone_group_list;
- std::vector<std::pair<unsigned short, unsigned char> > bone_display_list;
- ToonTexture toon_textures[10];
- std::vector<RigidBody> rigidbodies;
- std::vector<Constraint> constraints;
-
- char english_name[20];
- char english_comment[256];
-
- IO();
- ~IO();
- bool read(const char *path);
- bool write(const char *path);
- bool read(binary::IReader &reader);
- bool write(binary::IWriter &writer);
-#ifdef _WIN32
- bool read(const wchar_t *path);
- bool write(const wchar_t *path);
-#endif
-
- const Vector2* getUV(int index)const;
- std::wstring getName()const;
- std::wstring getComment()const;
- std::wstring getEnglishName()const;
- std::wstring getEnglishComment()const;
- void setName(const char *src);
- void setComment(const char *src);
- void setEnglishName(const char *src);
- void setEnglishComment(const char *src);
-};
-inline std::ostream &operator<<(std::ostream &os, const IO &rhs)
-{
- os
- << "<PMD " << rhs.name << std::endl
- << rhs.comment << std::endl
- << "[vertices] " << rhs.vertices.size() << std::endl
- << "[indices] " << rhs.indices.size() << std::endl
- << "[materials] " << rhs.materials.size() << std::endl
- ;
- /*
- std::copy(rhs.materials.begin(), rhs.materials.end(),
- std::ostream_iterator<Material>(os, ""));
-
- os
- << "[bones] " << rhs.bones.size() << std::endl
- ;
- std::copy(rhs.bones.begin(), rhs.bones.end(),
- std::ostream_iterator<Bone>(os, ""));
-
- os
- << "[ik] " << rhs.ik_list.size() << std::endl
- ;
- std::copy(rhs.ik_list.begin(), rhs.ik_list.end(),
- std::ostream_iterator<IK>(os, ""));
-
- os
- << "[morph] " << rhs.morph_list.size() << std::endl
- ;
- std::copy(rhs.morph_list.begin(), rhs.morph_list.end(),
- std::ostream_iterator<Morph>(os, ""));
- */
-
- os
- << ">" << std::endl
- ;
- return os;
-}
-
-
-} // namespace pmd
+ namespace pmd {
+
+ ////////////////////////////////////////////////////////////
+ //! \92¸\93_
+ ////////////////////////////////////////////////////////////
+ struct Vertex
+ {
+ //! \8dÀ\95W
+ Vector3 pos;
+ //! \96@\90ü\83x\83N\83g\83\8b
+ Vector3 normal;
+ //! \83e\83N\83X\83`\83\83UV
+ Vector2 uv;
+ //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\931
+ unsigned short bone0;
+ //! \83u\83\8c\83\93\83f\83B\83\93\83O\83{\81[\83\932
+ unsigned short bone1;
+ //! \83E\83F\83C\83g[0 - 100]
+ unsigned char weight0;
+ //! \94ñ\83G\83b\83W
+ unsigned char edge_flag;
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Vertex &rhs)
+ {
+ os
+ << "[Vertex"
+ << " pos:" << rhs.pos
+ << " normal:" << rhs.normal
+ << " uv:" << rhs.uv
+ << " bone0:" << rhs.bone0
+ << " bone1:" << rhs.bone1
+ << " weight0:" << (int)rhs.weight0
+ << " edge_flag:" << (int)rhs.edge_flag
+ << "]"
+ ;
+ return os;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! \8dÞ\8e¿
+ ////////////////////////////////////////////////////////////
+ struct Material
+ {
+ //! Diffuse
+ fRGBA diffuse;
+ //! Shinness
+ float shinness;
+ //! Specular
+ fRGB specular;
+ //! Ambient
+ fRGB ambient;
+ //! \83g\83D\81[\83\93\83e\83N\83X\83`\83\83
+ unsigned char toon_index;
+ //! \97Ö\8as/\89e
+ unsigned char flag;
+ //! \96Ê\92¸\93_\90\94
+ unsigned int vertex_count;
+ //! \83e\83N\83X\83`\83\83
+ fixed_string<20> texture;
+ };
+ inline std::ostream &operator<<(std::ostream &os,
+ const Material &rhs)
+ {
+ os
+ << "[Material"
+ << " diffuse:" << rhs.diffuse
+ << " toon_index:" << (int)rhs.toon_index
+ << " flag:" << (int)rhs.flag
+ << " vertex_count:" << rhs.vertex_count
+ << " texture:" << rhs.texture
+ << "]"
+ ;
+ return os;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! \83{\81[\83\93
+ ////////////////////////////////////////////////////////////
+ //! \83{\81[\83\93\82Ì\8eí\97Þ
+ enum BONE_TYPE
+ {
+ // \89ñ\93]
+ BONE_ROTATE=0,
+ // \89ñ\93]\82Æ\88Ú\93®
+ BONE_ROTATE_MOVE,
+ // IK
+ BONE_IK,
+ // \95s\96¾
+ BONE_UNKNOWN,
+ // IK\89e\8b¿\89º
+ BONE_IK_INFLUENCED,
+ // \89ñ\93]\89e\8b¿\89º
+ BONE_ROTATE_INFLUENCED,
+ // IK\90Ú\91±\90æ
+ BONE_IK_CONNECT,
+ // \94ñ\95\\8e¦
+ BONE_INVISIBLE,
+ // \94P\82è
+ BONE_TWIST,
+ // \89ñ\93]\98A\93®
+ BONE_REVOLVE,
+ };
+ struct Bone
+ {
+ //! \96¼\91O
+ fixed_string<20> name;
+ //! \90e\83{\81[\83\93
+ unsigned short parent_index;
+ //! \8eq\83{\81[\83\93
+ unsigned short tail_index;
+ //! \83{\81[\83\93\8eí\97Þ
+ BONE_TYPE type;
+ //! \89e\8b¿IK\83{\81[\83\93
+ unsigned short ik_index;
+ // \83{\81[\83\93\8dÀ\95W
+ Vector3 pos;
+ //! \89p\8cê\96¼
+ fixed_string<20> english_name;
+ //! \83{\81[\83\93\8aK\91w\8d\\92z\97p
+ Bone* parent;
+ Vector3 tail;
+ std::vector<Bone*> children;
+ unsigned short index;
+
+ Bone()
+ : parent_index(-1), tail_index(-1), type(BONE_UNKNOWN), ik_index(-1), parent(0), index(-1)
+ {}
+ };
+ inline std::ostream &operator<<(std::ostream &os,
+ const Bone &rhs)
+ {
+ os
+ << "[Bone "
+ << '"' << rhs.name << '"'
+ << "]"
+ ;
+ return os;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! IK
+ ////////////////////////////////////////////////////////////
+ struct IK
+ {
+ //! IK(IK\83^\81[\83Q\83b\83g)
+ unsigned short index;
+ //! Target(\83G\83t\83F\83N\83^\81[)
+ unsigned short target;
+ //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93\90\94
+ unsigned char length;
+ //! IK\92l1\81BCCD-IK\8e\8e\8ds\89ñ\90\94
+ unsigned short iterations;
+ //! IK\92l2\81BCCD-IK\8e\8e\8ds\88ê\89ñ\95Ó\82è\82Ì\89e\8b¿\93x
+ float weight;
+ //! \83G\83t\83F\83N\83^\82É\98A\93®\82·\82é\83{\81[\83\93(\8aî\96{\93I\82É\90e\83{\81[\83\93\82É\91k\82é)
+ std::vector<unsigned short> children;
+ };
+ inline std::ostream &operator<<(std::ostream &os, const IK &rhs)
+ {
+ os
+ << "[IK "
+ << "]"
+ ;
+ return os;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! \95\\8fî
+ ////////////////////////////////////////////////////////////
+ //! \95\\8fî\82Ì\8eí\97Þ
+ enum MORPH_TYPE
+ {
+ //! \83x\81[\83X\95\\8fî
+ MORPH_BASE=0,
+ //! \82Ü\82ä
+ MORPH_MAYU,
+ //! \96Ú
+ MORPH_ME,
+ //! \83\8a\83b\83v
+ MORPH_LIP,
+ //! \82»\82Ì\91¼
+ MORPH_OTHER,
+ };
+ struct Morph
+ {
+ //! \95\\8fî\96¼
+ fixed_string<20> name;
+ //! \8eg\97p\82·\82é\92¸\93_\90\94
+ unsigned int vertex_count;
+ //! \95ª\97Þ
+ unsigned char type;
+ //! \92¸\93_Index
+ std::vector<unsigned int> indices;
+ //! \88Ú\93®\97Ê
+ std::vector<Vector3> pos_list;
+ //! \89p\8cê\96¼
+ fixed_string<20> english_name;
+ };
+ inline std::ostream &operator<<(std::ostream &os, const Morph &rhs)
+ {
+ os
+ << "[Morph "
+ << '"' << rhs.name << '"'
+ << "]"
+ ;
+ return os;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! \83{\81[\83\93\95\\8e¦\98g
+ ////////////////////////////////////////////////////////////
+ struct BoneGroup
+ {
+ fixed_string<50> name;
+ fixed_string<50> english_name;
+ };
+
+ ////////////////////////////////////////////////////////////
+ //! \8d\84\91Ì
+ ////////////////////////////////////////////////////////////
+ //! \8c`\8fó
+ enum SHAPE_TYPE
+ {
+ //! \8b\85
+ SHAPE_SPHERE=0,
+ //! \94
+ SHAPE_BOX,
+ //! \83J\83v\83Z\83\8b
+ SHAPE_CAPSULE,
+ };
+ //! \8d\84\91Ì\83^\83C\83v
+ enum PROCESS_TYPE
+ {
+ //! \83{\81[\83\93\82Æ\93¯\82¶\93®\82«
+ RIGIDBODY_KINEMATICS=0,
+ //! \95¨\97\9d\89\89\8eZ
+ RIGIDBODY_PHYSICS,
+ //! \95¨\97\9d\89\89\8eZ\8c\8b\89Ê\82ð\83{\81[\83\93\82É\94½\89f\82·\82é
+ RIGIDBODY_PHYSICS_WITH_BONE,
+ };
+
+ struct RigidBody
+ {
+ //! \8d\84\91Ì\96¼
+ fixed_string<20> name;
+ //! \8aÖ\98A\83{\81[\83\93(\83{\81[\83\93\92Ç\8f]\82Æ\83{\81[\83\93\88Ê\92u\8d\87\82í\82¹\82Å\95K\97v)
+ unsigned short boneIndex;
+ //! \83O\83\8b\81[\83v
+ unsigned char group;
+ //! \94ñ\8fÕ\93Ë\83O\83\8b\81[\83v
+ unsigned short target;
+ //! \8c`\8fó
+ SHAPE_TYPE shapeType;
+ //! \83T\83C\83Y
+ float w;
+ float h;
+ float d;
+ //! \8ep\90¨
+ Vector3 position;
+ Vector3 rotation;
+ //! \8e¿\97Ê
+ float weight;
+ //! \95¨\97\9d\89\89\8eZ\83p\83\89\83\81\81[\83^(bullet)
+ float linearDamping;
+ float angularDamping;
+ float restitution;
+ float friction;
+ //! \8d\84\91Ì\83^\83C\83v
+ PROCESS_TYPE processType;
+ };
+
+ //! Joint(\95¨\97\9d\89\89\8eZ\82Å\82ÌJoint\82ÆConstraint\82Í\93¯\82¶\88Ó\96¡)
+ struct Constraint
+ {
+ //! Joint\96¼
+ fixed_string<20> name;
+ //! \90Ú\91±\8d\84\91ÌA
+ unsigned int rigidA;
+ //! \90Ú\91±\8d\84\91ÌB
+ unsigned int rigidB;
+ //! \88Ê\92u
+ Vector3 pos;
+ //! \89ñ\93]
+ Vector3 rot;
+ //! \88Ú\93®\90§\8cÀ
+ Vector3 constraintPosMin;
+ Vector3 constraintPosMax;
+ //! \89ñ\93]\90§\8cÀ
+ Vector3 constraintRotMin;
+ Vector3 constraintRotMax;
+ //! \82Î\82Ë
+ Vector3 springPos;
+ Vector3 springRot;
+ };
+
+
+ // IO
+ struct IO
+ {
+ float version;
+ fixed_string<20> name;
+ fixed_string<256> comment;
+ std::vector<Vertex> vertices;
+ std::vector<unsigned short> indices;
+ std::vector<Material> materials;
+ std::vector<Bone> bones;
+ std::vector<IK> ik_list;
+ std::vector<Morph> morph_list;
+ std::vector<unsigned short> face_list;
+ std::vector<BoneGroup> bone_group_list;
+ std::vector<std::pair<unsigned short, unsigned char> > bone_display_list;
+ std::array<fixed_string<100>, 10> toon_textures;
+ std::vector<RigidBody> rigidbodies;
+ std::vector<Constraint> constraints;
+
+ fixed_string<20> english_name;
+ fixed_string<256> english_comment;
+
+ IO();
+ bool read(const char *path);
+ bool write(const char *path);
+ bool read(binary::IReader &reader);
+ bool write(binary::IWriter &writer);
+ };
+ inline std::ostream &operator<<(std::ostream &os, const IO &rhs)
+ {
+ os
+ << "<PMD " << rhs.name << std::endl
+ << rhs.comment << std::endl
+ << "[vertices] " << rhs.vertices.size() << std::endl
+ << "[indices] " << rhs.indices.size() << std::endl
+ << "[materials] " << rhs.materials.size() << std::endl
+ ;
+ /*
+ std::copy(rhs.materials.begin(), rhs.materials.end(),
+ std::ostream_iterator<Material>(os, ""));
+
+ os
+ << "[bones] " << rhs.bones.size() << std::endl
+ ;
+ std::copy(rhs.bones.begin(), rhs.bones.end(),
+ std::ostream_iterator<Bone>(os, ""));
+
+ os
+ << "[ik] " << rhs.ik_list.size() << std::endl
+ ;
+ std::copy(rhs.ik_list.begin(), rhs.ik_list.end(),
+ std::ostream_iterator<IK>(os, ""));
+
+ os
+ << "[morph] " << rhs.morph_list.size() << std::endl
+ ;
+ std::copy(rhs.morph_list.begin(), rhs.morph_list.end(),
+ std::ostream_iterator<Morph>(os, ""));
+ */
+
+ os
+ << ">" << std::endl
+ ;
+ return os;
+ }
+
+
+ } // namespace pmd
} // namespace meshio
#endif // MESH_IO_PMD_H_INCLUDED
--- /dev/null
+solution "meshio"
+configurations { "Debug", "Release" }
+
+configuration "Debug"
+do
+ targetdir "../debug"
+ flags { "Symbols" }
+ buildoptions { "-g", "-Wall" }
+ defines { "DEBUG" }
+ linkoptions { "-g" }
+end
+
+configuration "Release"
+do
+ targetdir "../release"
+ flags { "Optimize" }
+ defines { "NDEBUG" }
+end
+
+
+-- A project defines one build target
+project "meshio"
+--kind "WindowedApp"
+--kind "ConsoleApp"
+--kind "SharedLib"
+kind "StaticLib"
+
+language "C++"
+files { "*.h", "*.cpp" }
+flags {
+ "StaticRuntime",
+}
+includedirs {
+}
+defines {}
+linkoptions {}
+libdirs {}
+links {}
+
+configuration { "windows", "not gmake" }
+do
+ -- VC
+ buildoptions {
+ "/wd4996",
+ }
+end
+
+configuration { "gmake" }
+do
+ buildoptions {
+ "-std=c++0x",
+ }
+end
+
#ifndef MESH_IO_TEXT_H_INCLUDED
#define MESH_IO_TEXT_H_INCLUDED
-#include "binary.h"
+//#include "binary.h"
#include "la.h"
#include "color.h"
#include <string>
#include <iostream>
+#include <vector>
#include <stdlib.h>
#include <cstring>
-#ifdef _WIN32
+#if defined(_WIN32)
#include <windows.h>
#else
#include <iconv.h>
#endif
namespace meshio {
-namespace text {
-
-/**
- * \8eQ\8fÆ\83I\83\93\83\8a\81[\82Ì\8aÈ\88Õ\95¶\8e\9a\97ñ\83N\83\89\83X
- */
-class cstr
-{
- const char *begin_;
- const char *end_;
-
-public:
- cstr()
- : begin_(0), end_(0)
- {}
-
- cstr(const char *begin, const char *end)
- : begin_(begin), end_(end)
- { }
-
- bool operator==(const char *rhs)const
- {
- const char *l=begin_;
- for(const char *r=rhs; *r; ++r, ++l){
- if(l==end_){
- return false;
- }
- if(*l!=*r){
- return false;
- }
- }
- return l==end_;
- }
-
- bool operator!=(const char *rhs)const
- {
- return !(*this==rhs);
- }
-
- bool include(char c)const
- {
- for(const char *l=begin_; l!=end_; ++l){
- if(*l==c){
- return true;
- }
- }
- return false;
- }
-
- bool startswith(const char *rhs)
- {
- const char *r=rhs;
- for(const char *l=begin_; l!=end_ && *r!='\0'; ++l, ++r){
- if(*l!=*r){
- return false;
- }
- }
- return true;
- }
-
- bool empty()const
- {
- return begin_==end_;
- }
-
- std::string str()const{ return std::string(begin_, end_); }
- const char* begin()const{ return begin_; }
- const char* end()const{ return end_; }
- std::pair<const char*, const char*> range()const{
- return std::make_pair(begin_, end_);
- }
-
- template<typename IsTrim>
- cstr &trim(IsTrim isTrim){
- while(begin_!=end_ && isTrim(*begin_)){
- begin_++;
- }
- while(end_!=begin_ && isTrim(end_[-1])){
- end_--;
- }
- return *this;
- }
-};
-inline std::ostream &operator<<(std::ostream &os, const cstr &rhs)
-{
- return os << rhs.str();
-}
-
-struct IsCRLF
-{
- bool operator()(char byte)const
- {
- switch(byte)
- {
- case '\n':
- case '\r': // fall through
- return true;
-
- default:
- return false;
- }
- }
-};
-
-struct IsWhiteSpace
-{
- bool operator()(char byte)const
- {
- switch(byte)
- {
- case ' ':
- case '\t': // fall through
- return true;
-
- default:
- return false;
- }
- }
-};
-
-struct IsEmpty
-{
- bool operator()(cstr line)const
- {
- return line.empty();
- }
-};
-
-template<class DELIMITER=IsCRLF,
- class TRIM=IsWhiteSpace,
- class LINESKIP=IsEmpty>
- class LineReader
-{
- binary::IReader &reader_;
- unsigned int lineCount_;
- std::vector<char> buf_;
- bool isEnd_;
-
-public:
- LineReader(binary::IReader &reader)
- : reader_(reader), lineCount_(0), isEnd_(false)
- {
- }
-
- cstr getLine()
- {
- while(!isEnd_){
- fill_();
- cstr line;
- if(!buf_.empty()){
- line=trim_();
- }
- if(LINESKIP()(line)){
- continue;
- }
- ++lineCount_;
- return line;
- }
- return cstr();
- }
-
- unsigned int getLineCount()const
- {
- return lineCount_;
- }
-
- bool isEnd()const
- {
- return isEnd_;
- }
-
-private:
- void fill_()
- {
- buf_.clear();
- // skip delimeter
- while(char byte=reader_.getChar()){
- if(DELIMITER()(byte)){
- continue;
- }
- buf_.push_back(byte);
- break;
- }
- while(char byte=reader_.getChar()){
- if(DELIMITER()(byte)){
- break;
- }
- buf_.push_back(byte);
- }
- if(buf_.empty()){
- isEnd_=true;
- return;
- }
- }
-
- cstr trim_()
- {
- if(buf_.empty()){
- return cstr();
- }
-
- size_t front=0;
- while(true){
- if(front>=buf_.size()){
- return cstr();
- }
- if(!TRIM()(buf_[front])){
- break;
- }
- ++front;
- }
-
- size_t back=buf_.size()-1;
- for(; back>=0; --back){
- if(!TRIM()(buf_[back])){
- break;
- }
- }
- assert(front<=back);
- return cstr(&buf_[0]+front, &buf_[0]+back+1);
- }
-};
-
-template<class DELIMITER=IsWhiteSpace>
-class LineSplitter
-{
- cstr line_;
-
-public:
- LineSplitter(cstr line)
- : line_(line)
- {
- }
-
- cstr get()
- {
- const char* head=0;
- const char* tail=0;
- const char *current=line_.begin();
- for(; current!=line_.end();){
- for(; current!=line_.end(); ++current){
- if(!DELIMITER()(*current)){
- head=current;
- break;
- }
- }
- if(head){
- for(; current!=line_.end(); ++current){
- if(DELIMITER()(*current)){
- break;
- }
- }
- tail=current;
- }
- if(tail){
- break;
- }
- }
- if(!tail){
- return cstr();
- }
- line_=cstr(tail+1, line_.end());
- return cstr(head, tail);
- }
-
- int getInt()
- {
- return atoi(get().begin());
- }
- float getFloat()
- {
- return static_cast<float>(atof(get().begin()));
- }
-
- la::Vector2 getVector2()
- {
- float x=getFloat();
- float y=getFloat();
- return la::Vector2(x, y);
- }
-
- la::Vector3 getVector3()
- {
- float x=getFloat();
- float y=getFloat();
- float z=getFloat();
- return la::Vector3(x, y, z);
- }
-
- la::Vector4 getVector4()
- {
- float x=getFloat();
- float y=getFloat();
- float z=getFloat();
- float w=getFloat();
- return la::Vector4(x, y, z, w);
- }
-
- color::fRGBA getFloatRGBA()
- {
- float r=getFloat();
- float g=getFloat();
- float b=getFloat();
- float a=getFloat();
- return color::fRGBA(r, g, b, a);
- }
-
- color::bRGBA getByteRGBA()
- {
- int r=getInt();
- int g=getInt();
- int b=getInt();
- int a=getInt();
- return color::bRGBA(r, g, b, a);
- }
+ class cstr
+ {
+ const char *begin_;
+ const char *end_;
+
+ public:
+ cstr()
+ : begin_(0), end_(0)
+ {}
+
+ cstr(const char *begin, const char *end)
+ : begin_(begin), end_(end)
+ { }
+
+ bool operator==(const char *rhs)const
+ {
+ const char *l=begin_;
+ for(const char *r=rhs; *r; ++r, ++l){
+ if(l==end_){
+ return false;
+ }
+ if(*l!=*r){
+ return false;
+ }
+ }
+ return l==end_;
+ }
- cstr getQuated()
- {
- const char *begin=line_.begin();
- for(; begin!=line_.end(); ++begin){
- if(*begin=='"'){
- break;
- }
- }
- begin++;
- assert(begin<=line_.end());
+ bool operator!=(const char *rhs)const
+ {
+ return !(*this==rhs);
+ }
- const char *c=begin+1;
- for(; c!=line_.end(); ++c){
- if(*c=='"'){
- break;
- }
- }
+ bool include(char c)const
+ {
+ for(const char *l=begin_; l!=end_; ++l){
+ if(*l==c){
+ return true;
+ }
+ }
+ return false;
+ }
- cstr token=cstr(begin, c);
+ bool startswith(const char *rhs)
+ {
+ const char *r=rhs;
+ for(const char *l=begin_; l!=end_ && *r!='\0'; ++l, ++r){
+ if(*l!=*r){
+ return false;
+ }
+ }
+ return true;
+ }
- // advance
- line_=cstr(c+1, line_.end());
+ bool empty()const
+ {
+ return begin_==end_;
+ }
- return token;
- }
-};
+ std::string str()const{ return std::string(begin_, end_); }
+ const char* begin()const{ return begin_; }
+ const char* end()const{ return end_; }
+ std::pair<const char*, const char*> range()const{
+ return std::make_pair(begin_, end_);
+ }
-inline void copyStringAndFillZero(char *dst, const std::string &src)
-{
- size_t i=0;
- for(; i<src.size(); ++i)
- {
- dst[i]=src[i];
- if(src[i]=='\0'){
- break;
- }
- }
- for(; i<src.size(); ++i)
- {
- dst[i]='\0';
- }
-}
+ template<typename IsTrim>
+ cstr &trim(IsTrim isTrim){
+ while(begin_!=end_ && isTrim(*begin_)){
+ begin_++;
+ }
+ while(end_!=begin_ && isTrim(end_[-1])){
+ end_--;
+ }
+ return *this;
+ }
+ };
+ inline std::ostream &operator<<(std::ostream &os, const cstr &rhs)
+ {
+ return os << rhs.str();
+ }
+
+ template<int LENGTH>
+ class fixed_string
+ {
+ char begin_[LENGTH];
+ char *end_;
+ public:
+ fixed_string()
+ : end_(begin_)
+ {
+ begin_[0]='\0';;
+ }
+ fixed_string(const std::string &str)
+ : end_(begin_)
+ {
+ assign(str);
+ }
+ fixed_string& operator=(const std::string &src)
+ {
+ assign(src);
+ return *this;
+ }
+ void assign(const std::string &src)
+ {
+ if(src.empty()){
+ return;
+ }
+ auto it=src.begin();
+ for(int i=0; i<LENGTH && *it; ++i, ++it, ++end_){
+ begin_[i]=*it;
+ }
+ if(std::distance(
+ static_cast<char*>(begin_),
+ static_cast<char*>(end_))<LENGTH)
+ {
+ *end_='\0';
+ }
+ }
+ size_t size()const { return LENGTH; }
+ char *begin() { return begin_; }
+ const char *begin() const { return begin_; }
+ std::string str() const
+ {
+ auto end=begin_;
+ for(; end!=end_ && *end!='\0'; ++end){
+ }
+ return std::string(
+ static_cast<const char*>(begin_),
+ static_cast<const char*>(end));
+ }
+ };
+ template<int LENGTH>
+ inline std::ostream &operator<<(std::ostream &os, const fixed_string<LENGTH> &rhs)
+ {
+ return os << rhs.str();
+ }
#ifdef _WIN32
-inline std::wstring to_WideChar(UINT uCodePage, const std::string &text)
-{
- int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
- std::vector<wchar_t> buf(size);
- size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
- return std::wstring(buf.begin(), buf.begin()+size);
-}
-
-inline std::string to_MultiByte(UINT uCodePage, const std::wstring &text)
-{
- int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL);
- std::vector<char> buf(size);
- size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL);
- return std::string(buf.begin(), buf.begin()+size);
-}
-
-inline std::wstring cp932_to_unicode(const std::string &text)
-{
+ inline std::wstring to_WideChar(UINT uCodePage, const std::string &text)
+ {
+ int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
+ std::vector<wchar_t> buf(size);
+ size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
+ return std::wstring(buf.begin(), buf.begin()+size);
+ }
+
+ inline std::string to_MultiByte(UINT uCodePage, const std::wstring &text)
+ {
+ int size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, NULL, 0, 0, NULL);
+ std::vector<char> buf(size);
+ size=WideCharToMultiByte(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size(), 0, NULL);
+ return std::string(buf.begin(), buf.begin()+size);
+ }
+
+ inline std::wstring cp932_to_unicode(const std::string &text)
+ {
return to_WideChar(CP_OEMCP, text);
-}
+ }
-inline std::string cp932_to_utf8(const std::string &text)
-{
- return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text));
-}
+ inline std::string cp932_to_utf8(const std::string &text)
+ {
+ return to_MultiByte(CP_UTF8, to_WideChar(CP_OEMCP, text));
+ }
#else
-inline std::wstring to_unicode(const char *text, const char *fromcode)
-{
+ inline std::wstring to_unicode(const char *text, const char *fromcode)
+ {
const char* tocode="WCHAR_T";
iconv_t cd=iconv_open(tocode, fromcode);
if(cd==(iconv_t)-1){
- std::cerr << "fail to iconv_open: " << fromcode << " --> " << tocode << std::endl;
- return L"";
+ std::cerr << "fail to iconv_open: " << fromcode << " --> " << tocode << std::endl;
+ return L"";
}
// inbuf
size_t outbytesleft=0;
while(inbytesleft){
- buf.resize(buf.size()+inbytesleft);
- wchar_t *woutbuf=&buf[pos];
- outbytesleft=(buf.size()-pos)*sizeof(wchar_t);
- int ret=iconv(cd, &inbuf, &inbytesleft, (char**)&woutbuf, &outbytesleft);
- if(ret==-1){
- std::cerr << "fail to iconv" << std::endl;
- return L"";
- }
- pos=woutbuf-&buf[0];
+ buf.resize(buf.size()+inbytesleft);
+ wchar_t *woutbuf=&buf[pos];
+ outbytesleft=(buf.size()-pos)*sizeof(wchar_t);
+ int ret=iconv(cd, &inbuf, &inbytesleft, (char**)&woutbuf, &outbytesleft);
+ if(ret==-1){
+ std::cerr << "fail to iconv" << std::endl;
+ return L"";
+ }
+ pos=woutbuf-&buf[0];
}
if(outbytesleft==0){
- buf.push_back('\0');
+ buf.push_back('\0');
}
iconv_close(cd);
return &buf[0];
-}
+ }
-inline std::wstring cp932_to_unicode(const std::string &text)
-{
+ inline std::wstring cp932_to_unicode(const std::string &text)
+ {
return to_unicode(text.c_str(), "CP932");
-}
+ }
#endif
-inline std::wstring trim(const std::wstring &src){
- std::wstring::const_iterator end=src.begin();
- for(; end!=src.end(); ++end){
- if(*end==L'\0'){
- break;
- }
- }
- return std::wstring(src.begin(), end);
-}
+ inline std::wstring trim(const std::wstring &src){
+ std::wstring::const_iterator end=src.begin();
+ for(; end!=src.end(); ++end){
+ if(*end==L'\0'){
+ break;
+ }
+ }
+ return std::wstring(src.begin(), end);
+ }
-} // namespace text
} // namespace meshio
#endif // MESH_IO_TEXT_H_INCLUDED
#include <string>
namespace meshio {
-namespace vmd {
-
-template<typename T>
-struct SortKeyFrameList
-{
- typedef T MAP;
- void operator()(typename MAP::value_type &channel)
- {
- channel.second->sort();
- }
-};
-
-template<class READER>
- void
- readBoneMap(READER &reader, IO &io)
- {
- std::wstring name=
- text::trim(text::cp932_to_unicode(reader.getString(15, true)));
- unsigned int frame=reader.getUint();
- IO::BoneMap::iterator found=io.boneMap.find(name);
- if(found==io.boneMap.end()){
- // not found
- found=io.boneMap.insert(
- std::make_pair(name,
- new KeyFrameList<KeyFrame<BoneKey> >())).first;
- io.boneKeys.push_back(name);
- }
- BoneKey &key=found->second->push(frame).key;
-
- reader.get(key.pos);
- reader.get(key.q);
- reader.get(key.interpolationX);
- reader.get(key.interpolationY);
- reader.get(key.interpolationZ);
- reader.get(key.interpolationRot);
- }
-
-template<class READER>
- void
- readMorphMap(READER &reader, IO &io)
- {
- std::wstring name=
- text::trim(text::cp932_to_unicode(reader.getString(15, true)));
- unsigned int frame=reader.getUint();
- IO::MorphMap::iterator found=io.morphMap.find(name);
- if(found==io.morphMap.end()){
- // not found
- found=io.morphMap.insert(
- std::make_pair(name,
- new KeyFrameList<KeyFrame<MorphKey> >())).first;
- io.morphKeys.push_back(name);
- }
- MorphKey &key=found->second->push(frame).key;
-
- reader.get(key.weight);
- }
-
-class Implementation
-{
- IO &io_;
- binary::IReader &reader_;
-
-public:
- Implementation(IO &io, binary::IReader &reader)
- : io_(io), reader_(reader)
- {}
-
- bool parse()
- {
- // check header
- std::string line=reader_.getString(30, true);
- if(line=="Vocaloid Motion Data file"){
- io_.version="1";
- text::copyStringAndFillZero(io_.name, reader_.getString(10));
- return parseBody();
- }
- else if(line=="Vocaloid Motion Data 0002"){
- io_.version="2";
- text::copyStringAndFillZero(io_.name, reader_.getString(20));
- return parseBody();
- }
- else{
- //std::cout << "unknown header:" << line << std::endl;
- return false;
- }
- }
-
-
-private:
- bool parseBody()
- {
- if(!parseFrame()){
- return false;
- }
- if(!parseMorph()){
- return false;
- }
- if(!parseCamera()){
- return false;
- }
- if(!parseLight()){
- return false;
- }
- // sort
- std::for_each(io_.boneMap.begin(), io_.boneMap.end(),
- SortKeyFrameList<IO::BoneMap>());
- std::for_each(io_.morphMap.begin(), io_.morphMap.end(),
- SortKeyFrameList<IO::MorphMap>());
- return true;
- }
-
- bool parseMorph()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- readMorphMap(reader_, io_);
- }
- return true;
- }
-
- bool parseFrame()
- {
- unsigned int count=reader_.getUint();
- for(unsigned int i=0; i<count; ++i){
- readBoneMap(reader_, io_);
- }
- return true;
- }
-
- bool parseCamera()
- {
- return true;
- }
-
- bool parseLight()
- {
- return true;
- }
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-//! IO
-///////////////////////////////////////////////////////////////////////////////
-IO::IO()
-{
-}
-
-IO::~IO()
-{
- for(BoneMap::iterator it=boneMap.begin(); it!=boneMap.end(); ++it){
- delete it->second;
- }
- boneMap.clear();
-
- for(MorphMap::iterator it=morphMap.begin(); it!=morphMap.end(); ++it){
- delete it->second;
- }
- morphMap.clear();
-
-}
-
-bool IO::read(binary::IReader &reader)
-{
- return Implementation(*this, reader).parse();
-}
-
-#ifdef _WIN32
-bool IO::read(const wchar_t *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-#endif
-
-bool IO::read(const char *path)
-{
- std::vector<char> all;
- binary::readAll(path, all);
- if(all.empty()){
- return false;
- }
- binary::MemoryReader reader(&all[0], all.size());
- return read(reader);
-}
-
-bool IO::write(std::ostream &os)
-{
- return false;
-}
-
-BoneKeyFrameList* IO::getBoneKeyFrameList(const std::wstring &name)
-{
- return boneMap[name];
-}
-
-MorphKeyFrameList* IO::getMorphKeyFrameList(const std::wstring &name)
-{
- return morphMap[name];
-}
-
-} // namespace vmd
+ namespace vmd {
+
+ template<typename T>
+ struct SortKeyFrameList
+ {
+ typedef T MAP;
+ void operator()(typename MAP::value_type &channel)
+ {
+ channel.second->sort();
+ }
+ };
+
+ template<class READER>
+ void
+ readBoneMap(READER &reader, IO &io)
+ {
+ std::wstring name=
+ trim(cp932_to_unicode(reader.getString(15, true)));
+ unsigned int frame=reader.getUint();
+ IO::BoneMap::iterator found=io.boneMap.find(name);
+ if(found==io.boneMap.end()){
+ // not found
+ found=io.boneMap.insert(
+ std::make_pair(name,
+ new KeyFrameList<KeyFrame<BoneKey> >())).first;
+ io.boneKeys.push_back(name);
+ }
+ BoneKey &key=found->second->push(frame).key;
+
+ reader.get(key.pos);
+ reader.get(key.q);
+ reader.get(key.interpolationX);
+ reader.get(key.interpolationY);
+ reader.get(key.interpolationZ);
+ reader.get(key.interpolationRot);
+ }
+
+ template<class READER>
+ void
+ readMorphMap(READER &reader, IO &io)
+ {
+ std::wstring name=
+ trim(cp932_to_unicode(reader.getString(15, true)));
+ unsigned int frame=reader.getUint();
+ IO::MorphMap::iterator found=io.morphMap.find(name);
+ if(found==io.morphMap.end()){
+ // not found
+ found=io.morphMap.insert(
+ std::make_pair(name,
+ new KeyFrameList<KeyFrame<MorphKey> >())).first;
+ io.morphKeys.push_back(name);
+ }
+ MorphKey &key=found->second->push(frame).key;
+
+ reader.get(key.weight);
+ }
+
+ class Implementation
+ {
+ IO &io_;
+ binary::IReader &reader_;
+
+ public:
+ Implementation(IO &io, binary::IReader &reader)
+ : io_(io), reader_(reader)
+ {}
+
+ bool parse()
+ {
+ // check header
+ std::string line=reader_.getString(30, true);
+ if(line=="Vocaloid Motion Data file"){
+ io_.version="1";
+ reader_.get(io_.name);
+ return parseBody();
+ }
+ else if(line=="Vocaloid Motion Data 0002"){
+ io_.version="2";
+ reader_.get(io_.name);
+ return parseBody();
+ }
+ else{
+ //std::cout << "unknown header:" << line << std::endl;
+ return false;
+ }
+ }
+
+
+ private:
+ bool parseBody()
+ {
+ if(!parseFrame()){
+ return false;
+ }
+ if(!parseMorph()){
+ return false;
+ }
+ if(!parseCamera()){
+ return false;
+ }
+ if(!parseLight()){
+ return false;
+ }
+ // sort
+ std::for_each(io_.boneMap.begin(), io_.boneMap.end(),
+ SortKeyFrameList<IO::BoneMap>());
+ std::for_each(io_.morphMap.begin(), io_.morphMap.end(),
+ SortKeyFrameList<IO::MorphMap>());
+ return true;
+ }
+
+ bool parseMorph()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ readMorphMap(reader_, io_);
+ }
+ return true;
+ }
+
+ bool parseFrame()
+ {
+ unsigned int count=reader_.getUint();
+ for(unsigned int i=0; i<count; ++i){
+ readBoneMap(reader_, io_);
+ }
+ return true;
+ }
+
+ bool parseCamera()
+ {
+ return true;
+ }
+
+ bool parseLight()
+ {
+ return true;
+ }
+ };
+
+
+ ///////////////////////////////////////////////////////////////////////////////
+ //! IO
+ ///////////////////////////////////////////////////////////////////////////////
+ IO::IO()
+ {
+ }
+
+ IO::~IO()
+ {
+ for(BoneMap::iterator it=boneMap.begin(); it!=boneMap.end(); ++it){
+ delete it->second;
+ }
+ boneMap.clear();
+
+ for(MorphMap::iterator it=morphMap.begin(); it!=morphMap.end(); ++it){
+ delete it->second;
+ }
+ morphMap.clear();
+
+ }
+
+ bool IO::read(binary::IReader &reader)
+ {
+ return Implementation(*this, reader).parse();
+ }
+
+ bool IO::read(const char *path)
+ {
+ std::vector<char> all;
+ binary::readAll(path, all);
+ if(all.empty()){
+ return false;
+ }
+ binary::MemoryReader reader(&all[0], all.size());
+ return read(reader);
+ }
+
+ bool IO::write(std::ostream &os)
+ {
+ // not implemented
+ return false;
+ }
+
+ } // namespace vmd
} // namespace meshio
* http://blog.goo.ne.jp/torisu_tetosuki/e/bc9f1c4d597341b394bd02b64597499d
* http://atupdate.web.fc2.com/vmd_format.htm
*/
-
#ifndef MESH_IO_VMD_H_INCLUDED
#define MESH_IO_VMD_H_INCLUDED
#include <algorithm>
namespace meshio {
-namespace vmd {
-
-typedef ::meshio::la::Vector2 Vector2;
-typedef ::meshio::la::Vector3 Vector3;
-typedef ::meshio::la::Quaternion Quaternion;
-typedef ::meshio::color::fRGB fRGB;
-
-////////////////////////////////////////////////////////////
-//! \83\82\81[\83V\83\87\83\93
-////////////////////////////////////////////////////////////
-struct BoneKey
-{
- Vector3 pos;
- Quaternion q;
- char interpolationX[16];
- char interpolationY[16];
- char interpolationZ[16];
- char interpolationRot[16];
-};
-inline std::ostream& operator<<(std::ostream &os, const BoneKey &rhs)
-{
- return os
- << "<BoneKey: " << rhs.pos << rhs.q << ">"
- ;
-}
-
-////////////////////////////////////////////////////////////
-//! \95\\8fî
-////////////////////////////////////////////////////////////
-struct MorphKey
-{
- float weight;
-};
-inline std::ostream& operator<<(std::ostream &os, const MorphKey &rhs)
-{
- return os
- << "<MorphKey: " << rhs.weight << ">"
- ;
-}
-
-
-////////////////////////////////////////////////////////////
-//! \83J\83\81\83\89
-////////////////////////////////////////////////////////////
-struct CameraKey
-{
- //! \89½\82Ì\8b\97\97£\81H
- float length;
- //! \88Ê\92u
- Vector3 pos;
- //! \83I\83C\83\89\81[\8ap
- Vector3 euler;
- //! \95â\8aÔ
- char interpolation[24];
- //! \8e\8b\96ì\8ap
- unsigned short viewAngle;
- //! \89\93\8bß\8a´ 0\82ªon
- unsigned char perspective;
-};
-inline std::ostream& operator<<(std::ostream &os, const CameraKey &rhs)
-{
- return os
- << "<CameraKey: " << rhs.length
- << rhs.pos << rhs.euler << ">"
- ;
-}
-
-
-////////////////////////////////////////////////////////////
-//! \8cõ\8c¹
-////////////////////////////////////////////////////////////
-struct LightKey
-{
- fRGB color;
- Vector3 pos;
-};
-inline std::ostream& operator<<(std::ostream &os, const LightKey &rhs)
-{
- return os
- << "<LightKey: " << rhs.color << rhs.pos << ">"
- ;
-}
-
-
-////////////////////////////////////////////////////////////
-//! \83Z\83\8b\83t\83V\83\83\83h\83E
-////////////////////////////////////////////////////////////
-struct SelfShadowKey
-{
-};
-
-////////////////////////////////////////////////////////////
-//! KeyFrame
-////////////////////////////////////////////////////////////
-template<typename T>
-struct KeyFrame
-{
- typedef T VALUE_TYPE;
-
- //! \83t\83\8c\81[\83\80\94Ô\8d\86
- unsigned int frame;
- //! \83L\81[
- T key;
-
- //! \83t\83\8c\81[\83\80\94Ô\8d\86\82Å\83L\81[\82ð\83\\81[\83g\82·\82é
- bool operator<(const KeyFrame &rhs)const{ return frame<rhs.frame; }
-};
-
-////////////////////////////////////////////////////////////
-//! 1\83`\83\83\83\93\83l\83\8b\95ª\82Ì\83L\81[\83t\83\8c\81[\83\80\82Ì\83\8a\83X\83g\81B
-//! \93Ç\82Ý\8d\9e\82ñ\82¾\8cã\82Å\83t\83\8c\81[\83\80\94Ô\8d\86\82Å\83\\81[\83g\82·\82é\81B
-////////////////////////////////////////////////////////////
-template<typename T>
-struct KeyFrameList
-{
- typedef T KEYFRAME_TYPE;
-
- std::vector<KEYFRAME_TYPE> list;
- void sort(){ std::sort(list.begin(), list.end()); }
- KEYFRAME_TYPE& push(unsigned int frame)
- {
- list.push_back(KEYFRAME_TYPE());
- KEYFRAME_TYPE &keyFrame=list.back();
- keyFrame.frame=frame;
- return keyFrame;
- }
- unsigned int getFrame(int index)
- {
- return list[index].frame;
- }
- typename KEYFRAME_TYPE::VALUE_TYPE* getKey(int index)
- {
- return &list[index].key;
- }
-};
-
-////////////////////////////////////////////////////////////
-//! IO
-////////////////////////////////////////////////////////////
-typedef KeyFrame<BoneKey> BoneKeyFrame;
-typedef KeyFrameList<BoneKeyFrame> BoneKeyFrameList;
-
-typedef KeyFrame<MorphKey> MorphKeyFrame;
-typedef KeyFrameList<MorphKeyFrame> MorphKeyFrameList;
-
-struct IO
-{
- std::string version;
- char name[20];
-
- //! \83\82\81[\83V\83\87\83\93
- typedef std::map<std::wstring, BoneKeyFrameList*> BoneMap;
- BoneMap boneMap;
- std::vector<std::wstring> boneKeys;
-
- //! \95\\8fî
- typedef std::map<std::wstring, MorphKeyFrameList*> MorphMap;
- MorphMap morphMap;
- std::vector<std::wstring> morphKeys;
-
- IO();
- ~IO();
- bool read(binary::IReader &reader);
- bool read(const wchar_t *path);
- bool read(const char *path);
- bool write(std::ostream &os);
-
- BoneKeyFrameList* getBoneKeyFrameList(const std::wstring &name);
- MorphKeyFrameList* getMorphKeyFrameList(const std::wstring &name);
-};
-inline std::ostream& operator<<(std::ostream &os, const IO &rhs)
-{
- os
- << "<VMD " << rhs.name << std::endl
- << "[bones] " << rhs.boneMap.size() << std::endl
- << "[morphs] " << rhs.morphMap.size() << std::endl
- << ">"
- ;
- return os;
-}
-
-} // namespace vmd
+ namespace vmd {
+
+ ////////////////////////////////////////////////////////////
+ //! \83\82\81[\83V\83\87\83\93
+ ////////////////////////////////////////////////////////////
+ struct BoneKey
+ {
+ Vector3 pos;
+ Quaternion q;
+ char interpolationX[16];
+ char interpolationY[16];
+ char interpolationZ[16];
+ char interpolationRot[16];
+ };
+ inline std::ostream& operator<<(std::ostream &os, const BoneKey &rhs)
+ {
+ return os
+ << "<BoneKey: " << rhs.pos << rhs.q << ">"
+ ;
+ }
+
+ ////////////////////////////////////////////////////////////
+ //! \95\\8fî
+ ////////////////////////////////////////////////////////////
+ struct MorphKey
+ {
+ float weight;
+ };
+ inline std::ostream& operator<<(std::ostream &os, const MorphKey &rhs)
+ {
+ return os
+ << "<MorphKey: " << rhs.weight << ">"
+ ;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ //! \83J\83\81\83\89
+ ////////////////////////////////////////////////////////////
+ struct CameraKey
+ {
+ //! \89½\82Ì\8b\97\97£\81H
+ float length;
+ //! \88Ê\92u
+ Vector3 pos;
+ //! \83I\83C\83\89\81[\8ap
+ Vector3 euler;
+ //! \95â\8aÔ
+ char interpolation[24];
+ //! \8e\8b\96ì\8ap
+ unsigned short viewAngle;
+ //! \89\93\8bß\8a´ 0\82ªon
+ unsigned char perspective;
+ };
+ inline std::ostream& operator<<(std::ostream &os, const CameraKey &rhs)
+ {
+ return os
+ << "<CameraKey: " << rhs.length
+ << rhs.pos << rhs.euler << ">"
+ ;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ //! \8cõ\8c¹
+ ////////////////////////////////////////////////////////////
+ struct LightKey
+ {
+ fRGB color;
+ Vector3 pos;
+ };
+ inline std::ostream& operator<<(std::ostream &os, const LightKey &rhs)
+ {
+ return os
+ << "<LightKey: " << rhs.color << rhs.pos << ">"
+ ;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ //! \83Z\83\8b\83t\83V\83\83\83h\83E
+ ////////////////////////////////////////////////////////////
+ struct SelfShadowKey
+ {
+ };
+
+ ////////////////////////////////////////////////////////////
+ //! KeyFrame
+ ////////////////////////////////////////////////////////////
+ template<typename T>
+ struct KeyFrame
+ {
+ typedef T VALUE_TYPE;
+
+ //! \83t\83\8c\81[\83\80\94Ô\8d\86
+ unsigned int frame;
+ //! \83L\81[
+ T key;
+
+ //! \83t\83\8c\81[\83\80\94Ô\8d\86\82Å\83L\81[\82ð\83\\81[\83g\82·\82é
+ bool operator<(const KeyFrame &rhs)const{ return frame<rhs.frame; }
+ };
+
+ ////////////////////////////////////////////////////////////
+ //! 1\83`\83\83\83\93\83l\83\8b\95ª\82Ì\83L\81[\83t\83\8c\81[\83\80\82Ì\83\8a\83X\83g\81B
+ //! \93Ç\82Ý\8d\9e\82ñ\82¾\8cã\82Å\83t\83\8c\81[\83\80\94Ô\8d\86\82Å\83\\81[\83g\82·\82é\81B
+ ////////////////////////////////////////////////////////////
+ template<typename T>
+ struct KeyFrameList
+ {
+ typedef T KEYFRAME_TYPE;
+
+ std::vector<KEYFRAME_TYPE> list;
+ void sort(){ std::sort(list.begin(), list.end()); }
+ KEYFRAME_TYPE& push(unsigned int frame)
+ {
+ list.push_back(KEYFRAME_TYPE());
+ KEYFRAME_TYPE &keyFrame=list.back();
+ keyFrame.frame=frame;
+ return keyFrame;
+ }
+ };
+
+ ////////////////////////////////////////////////////////////
+ //! IO
+ ////////////////////////////////////////////////////////////
+ typedef KeyFrame<BoneKey> BoneKeyFrame;
+ typedef KeyFrameList<BoneKeyFrame> BoneKeyFrameList;
+
+ typedef KeyFrame<MorphKey> MorphKeyFrame;
+ typedef KeyFrameList<MorphKeyFrame> MorphKeyFrameList;
+
+ struct IO
+ {
+ std::string version;
+ char name[20];
+
+ //! \83\82\81[\83V\83\87\83\93
+ typedef std::map<std::wstring, BoneKeyFrameList*> BoneMap;
+ BoneMap boneMap;
+ std::vector<std::wstring> boneKeys;
+
+ //! \95\\8fî
+ typedef std::map<std::wstring, MorphKeyFrameList*> MorphMap;
+ MorphMap morphMap;
+ std::vector<std::wstring> morphKeys;
+
+ IO();
+ ~IO();
+ bool read(binary::IReader &reader);
+ bool read(const char *path);
+ bool write(std::ostream &os);
+ };
+ inline std::ostream& operator<<(std::ostream &os, const IO &rhs)
+ {
+ os
+ << "<VMD " << rhs.name << std::endl
+ << "[bones] " << rhs.boneMap.size() << std::endl
+ << "[morphs] " << rhs.morphMap.size() << std::endl
+ << ">"
+ ;
+ return os;
+ }
+
+ } // namespace vmd
} // namespace meshio
#endif // MESH_IO_VMD_H_INCLUDED
"/wd4996",
}
includedirs {
- "../include",
+ "../src",
"T:/vc/gtest-1.5.0/include",
}
defines {}
configurations { "Debug", "Release" }
dofile "meshio_test.lua"
-dofile "../meshio.lua"