#pragma once
#include "PNG.h"
#include <math.h>
#define PAI 3.14159
using namespace std;
struct MATRIX;
//クォータニオン構造体
struct QUATERNION{
union {
struct {
float w;
float x;
float y;
float z;
};
float Index[4];
};
MATRIX ToMatrix();//クォータニオンを回転行列にする
}qua;
//マトリクス構造体
struct MATRIX {
union {
struct {
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
float mat_4x4[4][4];
float mat_16[16];
};
MATRIX(){//単位行列に初期化
for(int i=0;i<16;i++){
this->mat_16[i]=0;
}
this->_11=this->_22=this->_33=this->_44=1;
}
void PRINT(char* text){
printf("%s\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n\n",
text,
this->_11,this->_21,this->_31,this->_41,
this->_12,this->_22,this->_32,this->_42,
this->_13,this->_23,this->_33,this->_43,
this->_14,this->_24,this->_34,this->_44);
}
MATRIX Multiplication(MATRIX& mat);//合成
QUATERNION ToQuaternion();//回転行列をクォータニオンにする
};
//合成
MATRIX MATRIX::Multiplication(MATRIX& mat)
{
MATRIX ret;
for(int y=0;y<4;y++){
for(int x=0;x<4;x++){
ret.mat_16[y*4+x]=mat.mat_16[y*4]*this->mat_16[x]+mat.mat_16[y*4+1]*this->mat_16[x+4]+mat.mat_16[y*4+2]*this->mat_16[x+8]+mat.mat_16[y*4+3]*this->mat_16[x+12];
}
}
return ret;
}
float SGN(float x) {
return (x >= 0.0f) ? +1.0f : -1.0f;
}
//回転行列をクォータニオンにする
QUATERNION MATRIX::ToQuaternion(){
QUATERNION q;
q.w = ( this->_11 + this->_22 + this->_33 + 1.0f) / 4.0f;
q.x = ( this->_11 - this->_22 - this->_33 + 1.0f) / 4.0f;
q.y = (-this->_11 + this->_22 - this->_33 + 1.0f) / 4.0f;
q.z = (-this->_11 - this->_22 + this->_33 + 1.0f) / 4.0f;
for(int i=0;i<4;i++){
if(q.Index[i] < 0.0f) q.Index[i] = 0.0f;
q.Index[i] = sqrt(q.Index[i]);
}
if(q.w >= q.x && q.w >= q.y && q.w >= q.z) {
q.w *= +1.0f;
q.x *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21);
q.y *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21);
q.z *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21);
} else {
q.w *= +1.0f*-1;
q.x *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21)*-1;
q.y *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21)*-1;
q.z *= SGN(this->_23 - this->_32)*SGN(this->_31 -
this->_13)*SGN(this->_12 - this->_21)*-1;
}
float nor = sqrt(q.w * q.w + q.x * q.x + q.y * q.y + q.z *q.z);
for(int i=0;i<4;i++){
q.Index[i] /= nor;
}
return q;
}
//クォータニオンを回転行列にする
MATRIX QUATERNION::ToMatrix(){
MATRIX ret;
float sx = this->x * this->x;
float sy = this->y * this->y;
float sz = this->z * this->z;
float cx = this->y * this->z;
float cy = this->x * this->z;
float cz = this->x * this->y;
float wx = this->w * this->x;
float wy = this->w * this->y;
float wz = this->w * this->z;
ret._11= 1.0f - 2.0f * (sy + sz);
ret._12= 2.0f * (cz + wz);
ret._13= 2.0f * (cy - wy);
ret._21= 2.0f * (cz - wz);
ret._22= 1.0f - 2.0f * (sx + sz);
ret._23= 2.0f * (cx + wx);
ret._31= 2.0f * (cy + wy);
ret._32= 2.0f * (cx - wx);
ret._33= 1.0f - 2.0f * (sx + sy);
ret._41= 0.0f;
ret._42= 0.0f;
ret._43= 0.0f;
return ret;
}
//3つのベクトル
struct Vector3f{
float x;
float y;
float z;
Vector3f(){};
Vector3f(float _x,float _y,float _z){
x=_x;y=_y;z=_z;
};
}vec3d;
Vector3f & operator*(Vector3f &v,float size){
v.x *= size;
v.y *= size;
v.z *= size;
return v;
}
Vector3f & operator+(Vector3f &a,Vector3f &b){
a.x+=b.x;
a.y+=b.y;
a.z+=b.z;
return a;
}
//4つのベクトル
struct Vector4f{
float x;
float y;
float z;
float w;
Vector4f(){};
Vector4f(float _x,float _y,float _z,float _w){
x=_x;y=_y;z=_z;w=_w;
};
}vec4d;
//正規化
void normalize(Vector3f& v){
float m=sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
if(m > 0.0f){m = 1.0f / m;}else{m = 0.0f;}
v.x*=m;
v.y*=m;
v.z*=m;
}
//外積
void cross( Vector3f& src1, Vector3f& src2 ,Vector3f& dst){
dst.x = src1.y*src2.z - src1.z*src2.y;
dst.y = src1.z*src2.x - src1.x*src2.z;
dst.z = src1.x*src2.y - src1.y*src2.x;
}
//内積
void dot(Vector3f& src1,Vector3f& src2,float& dst){
dst= src1.x*src2.x+src1.y*src2.y+src1.z*src2.z;
}
//4つのカラー
struct Color4{
float r;
float g;
float b;
float a;
};
//4つの反射
struct Reflection4{
Color4 diffuse;
Color4 ambient;
Color4 emission;
Color4 specular;
};
//UV座標
struct UV{
float u;//u値
float v;//v値
}vec2d;
//ポリゴンデータ
struct Triangle{
Vector3f TriVer;
Vector3f TriNor;
UV TriUV;
}Tri;
//ポリゴンデータ
struct Quadrangle{
Vector3f QuadVer;
Vector3f QuadNor;
UV QuadUV;
}Quad;
//フレーム外マテリアル構造体
struct OUTSIDEMATERIAL{
string MaterialName;//マテリアル名
Reflection4 MaterialColor;//反射
float Shininess;//shininess
string TextureName;//テクスチャ名
int TexNo;//テクスチャNO.
}outmtl;
//マテリアル構造体
struct MATERIAL{
string MaterialName;//マテリアル名
Reflection4 MaterialColor;//反射
float Shininess;//shininess
string TextureName;//テクスチャ名
int TexNo;//テクスチャNO.
vector <Triangle> Tridata;//三角面データ
vector <Quadrangle> Quaddata;//四角面データ
}mtl;
//メッシュ構造体
struct MESH{
public:
vector <MATERIAL> Material;//マテリアル
vector <TEXTURE*> TexData;//テクスチャデータ
vector<GLuint> TexID;//テクスチャID
GLuint TexID2;//代入用
TEXTURE* tex;//代入用
}msh;
//アニメーションデータ構造体
struct ANIMATION{
public:
vector <int> Key;//アニメーションキー
vector <MATRIX> Matrix;//行列データ
}anm;
//ノード構造体
struct NODE{
NODE* Node;//子ノード
NODE* Next;//隣の階層
string FrameName;//フレーム名
MESH* Mesh;//メッシュ
vector<GLuint> MatNo;//マテリアルNO.
ANIMATION Anim;//アニメーションデータ
MATRIX BoneOfSet;//ボーンオフセット行列
MATRIX FrameTransformMatrix;//親フレームからのトランスフォーム行列
bool isBone;//ボーンフラグ
}nde;
//階層メッシュクラス
class HIERARCHY{
public:
void Draw();//描画
void Draw_Frame(NODE& node,int Frame_Time,MATRIX& mat);//フレーム描画
void Animation_Draw(int Animation_NO,int Frame);//アニメーション描画
HIERARCHY();
HIERARCHY(char* FileName,float size);
NODE Root;//ルートノード
float Size;//サイズ
int Animation_MaxFrame;//最大フレーム
private:
bool Load_Mesh(FILE& fp,NODE& node);//メッシュ読み込み
QUATERNION Spherical_Linear_Interpolation( QUATERNION& q1, QUATERNION&
q2, float t);//球面線形補間
char buffer[255];
protected:
void Init();
bool Load_Hierarchy(char* FileName); //階層メッシュ読み込み
bool Load_Frame(FILE& fp,NODE& node,int& hierarchy);
//フレーム読み込み
bool Load_Animation(FILE& fp);//アニメーション読み込み
vector <string> Bone_Name;
void Find_Frame(NODE& node,char* name);//フレームを探す
MATRIX Linear_Interpolation(MATRIX& a,MATRIX& b,float t);//線形補間
NODE* pNode;//ノードポインタ
int Back;//階層戻し
vector<MATRIX> bone_ofset;
vector<OUTSIDEMATERIAL> OutSide_Mat;
};
//スキンメッシュクラス
class SKINNEDMESH : public HIERARCHY{
public:
bool SkinnedMeshFlag;//スキンメッシュか階層メッシュか
int AnimTicksPerSecond;//一秒間のコマ数
bool Load_SkinnedMesh(char* FileName, float size);//スキンメッシュ読み込み
SKINNEDMESH();
SKINNEDMESH(char* FileName,float size);
void Draw_Joint(NODE& node,int Frame_Time,MATRIX& mat);//ジョイント描画
void Draw_Bone(MATRIX& mat1,MATRIX& mat2);//ボーン描画
};
SKINNEDMESH::SKINNEDMESH(){
SkinnedMeshFlag=false;
AnimTicksPerSecond=60;
Size=1;
Animation_MaxFrame=0;
}
SKINNEDMESH::SKINNEDMESH(char *FileName, float size){
//階層メッシュアニメーションかスキンメッシュアニメーションかの判定
char key[255];
FILE* fp=NULL;
SkinnedMeshFlag=false;
AnimTicksPerSecond=60;
Animation_MaxFrame=0;
fopen_s(&fp,FileName,"rt");
//読み込み
fseek(fp,0,SEEK_SET);
while(!feof(fp)){
//キーワード 読み込み
ZeroMemory(key,sizeof(key));
fscanf_s(fp,"%s ",key,sizeof(key));
//テンプレート読み飛ばし
if(strcmp(key,"template")==0){
while(strcmp(key,"}")){
fscanf_s(fp,"%s ",key,sizeof(key));
}
continue;
}
if(strcmp(key,"AnimTicksPerSecond")==0){
fgets(key,sizeof(key),fp);
fscanf_s(fp,"%d;",&AnimTicksPerSecond);
}
if((strcmp(key,"FrameTransformMatrix")==0)||(strcmp(key,"XSkinMeshHeader")==0)||
(strcmp(key,"VertexDuplicationIndices")==0)||(strcmp(key,"SkinWeights")==0)){
SkinnedMeshFlag=true;
}
}
if(SkinnedMeshFlag){//スキンメッシュアニメーションなら
Init();
Size=size;
Load_SkinnedMesh(FileName,size);
}else{//階層メッシュアニメーションなら
Init();
Size=size;
this->Load_Hierarchy(FileName);
}
}
//ボーン描画
void SKINNEDMESH::Draw_Bone(MATRIX& mat1,MATRIX& mat2){
glColor4f(0.0f,1.0f,1.0f,1.0f);
glPushMatrix();
glTranslatef(mat1._41,mat1._42,mat1._43);
float
length=-sqrt((mat1._41-mat2._41)*(mat1._41-mat2._41)+(mat1._42-mat2._42)*(mat1._42-mat2._42)+(mat1._43-mat2._43)*(mat1._43-mat2._43));
if(mat1._41+mat1._42+mat1._43==0.0f)length=sqrt(mat2._41*mat2._41)+sqrt(mat2._42*mat2._42)+sqrt(mat2._43*mat2._43);
if(mat1._41+mat1._42+mat1._43!=0){
glRotatef(90.0f,0.0f,0.0f,1.0f);
glRotatef(-90.0f,mat2._41-mat1._41,mat2._42-mat1._42,mat2._43-mat1._43);
glutSolidCone(10.0f*Size, length, 4, 1);
}
glPopMatrix();
}
//ジョイント描画
void SKINNEDMESH::Draw_Joint(NODE& node,int Frame_Time,MATRIX&
mat){
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
MATRIX current=mat;
while(1){
if(node.isBone){
glPushMatrix();
mat=mat.Multiplication(node.FrameTransformMatrix);
glMultMatrixf(&mat.mat_16[0]);
//線形補間
for(int k=1;k<(signed)node.Anim.Key.size();k++){
int Length=node.Anim.Key[k]-node.Anim.Key[k-1];//キー間の長さ
int Current=Frame_Time-node.Anim.Key[k-1];//キー間の現在位置
float t=(float)Current/(float)Length;
if((node.Anim.Key[k-1]<=Frame_Time)&&(node.Anim.Key[k]>Frame_Time)){
MATRIX Linear =
Linear_Interpolation(node.Anim.Matrix[k-1],node.Anim.Matrix[k],t);
//mat=mat.Multiplication(Linear);
//glMultMatrixf(&mat.mat_16[0]);
//glMultMatrixf(&Linear.mat_16[0]);
}
}
glColor4f(1.0f,1.0f,0.0f,1.0f);
glutSolidSphere(5.0*Size,8,8);
glPopMatrix();
Draw_Bone(current,mat);
}
if(node.Node!=NULL)Draw_Joint(*node.Node,Frame_Time,mat);
if(node.Next!=NULL)Draw_Joint(*node.Next,Frame_Time,current);
return;
}
return;
glDisable(GL_COLOR_MATERIAL);
}
bool SKINNEDMESH::Load_SkinnedMesh(char *FileName, float size){
//Xファイルを開いて内容を読み込む
Back=-1;
int Hierarchy=0;
FILE* fp=NULL;
fopen_s(&fp,FileName,"rt");
//読み込み
fseek(fp,0,SEEK_SET);
Load_Frame(*fp,Root,Hierarchy);
//ボーンフラグセット
for(int i=0;i<(signed)Bone_Name.size();i++){
Find_Frame(Root,(char*)Bone_Name[i].c_str());
pNode->isBone=true;
pNode->BoneOfSet=bone_ofset[i];
}
Bone_Name.clear();
bone_ofset.clear();
fseek(fp,0,SEEK_SET);
this->Load_Animation(*fp);
fclose(fp);
return true;
}
//コンストラクタ
HIERARCHY::HIERARCHY(){
Init();
}
//コンストラクタ
HIERARCHY::HIERARCHY(char* FileName,float size){
Init();
Size=size;
Animation_MaxFrame=0;
Load_Hierarchy(FileName);
}
//初期化
void HIERARCHY::Init(){
Root.Node=NULL;
Root.Next=NULL;
Root.FrameName="Root";
Root.Mesh=NULL;
Root.isBone=false;
}
//球面線形補間
QUATERNION HIERARCHY::Spherical_Linear_Interpolation( QUATERNION& q1,
QUATERNION& q2, float t)
{
QUATERNION q;
if((q1.w==q2.w)&&(q1.x==q2.x)&&(q1.y==q2.y)&&(q1.z==q2.z)){
for(int i=0;i<4;i++){
q.Index[i] = q1.Index[i];
}
return q;
}
float qr = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
float ss = 1.0f - qr * qr;
if (ss == 0.0f) {
for(int i=0;i<4;i++){
q.Index[i] = q1.Index[i];
}
return q;
}else{
float sp = sqrt(ss);
float ph = acos(qr);
float pt = ph * t;
float t1 = sin(pt) / sp;
float t0 = sin(ph - pt) / sp;
for(int i=0;i<4;i++){
q.Index[i] = (q1.Index[i] * t0 + q2.Index[i] * t1);
}
return q;
}
}
//線形補間
MATRIX HIERARCHY::Linear_Interpolation(MATRIX& a,MATRIX& b,float
t){
MATRIX ret,r1,r2,r3;
QUATERNION q1,q2,q3;
Vector3f vec_A, vec_B, vec_R;
//平行移動
vec_A.x=a._41;
vec_A.y=a._42;
vec_A.z=a._43;
vec_B.x=b._41;
vec_B.y=b._42;
vec_B.z=b._43;
vec_R=vec_A*(1.0f-t) + vec_B*t;
ret._41=vec_R.x;
ret._42=vec_R.y;
ret._43=vec_R.z;
//スケーリング成分抜き出し
vec_A.x=sqrt(a._11*a._11+a._21*a._21+a._31*a._31);
vec_A.y=sqrt(a._12*a._12+a._22*a._22+a._32*a._32);
vec_A.z=sqrt(a._13*a._13+a._23*a._23+a._33*a._33);
vec_B.x=sqrt(b._11*b._11+b._21*b._21+b._31*b._31);
vec_B.y=sqrt(b._12*b._12+b._22*b._22+b._32*b._32);
vec_B.z=sqrt(b._13*b._13+b._23*b._23+b._33*b._33);
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
r1.mat_4x4[j][i]=a.mat_4x4[j][i];
r2.mat_4x4[j][i]=b.mat_4x4[j][i];
if(i==0){if(j<3){r1.mat_4x4[j][i]=a.mat_4x4[j][i]/vec_A.x;r2.mat_4x4[j][i]=b.mat_4x4[j][i]/vec_B.x;}}
if(i==1){if(j<3){r1.mat_4x4[j][i]=a.mat_4x4[j][i]/vec_A.y;r2.mat_4x4[j][i]=b.mat_4x4[j][i]/vec_B.y;}}
if(i==2){if(j<3){r1.mat_4x4[j][i]=a.mat_4x4[j][i]/vec_A.z;r2.mat_4x4[j][i]=b.mat_4x4[j][i]/vec_B.z;}}
}
}
//クォータニオンを補間
q1=r1.ToQuaternion();
q2=r2.ToQuaternion();
q3=Spherical_Linear_Interpolation(q1,q2,t);
r3=q3.ToMatrix();
vec_R=vec_A*(1.0f-t) + vec_B*t;
ret._11=r3._11*vec_R.x;
ret._21=r3._21*vec_R.x;
ret._31=r3._31*vec_R.x;
ret._12=r3._12*vec_R.y;
ret._22=r3._22*vec_R.y;
ret._32=r3._32*vec_R.y;
ret._13=r3._13*vec_R.z;
ret._23=r3._23*vec_R.z;
ret._33=r3._33*vec_R.z;
return ret;
}
//フレーム描画
void HIERARCHY::Draw_Frame(NODE& node,int Frame_Time,MATRIX& mat){
MATRIX current=mat;
while(1){
if(node.Mesh!=NULL){
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glPushMatrix();
glMultMatrixf(&mat.mat_16[0]);
//線形補間
for(int k=1;k<(signed)node.Anim.Key.size();k++){
int Length=node.Anim.Key[k]-node.Anim.Key[k-1];//キー間の長さ
int Current=Frame_Time-node.Anim.Key[k-1];//キー間の現在位置
float t=(float)Current/(float)Length;
if((node.Anim.Key[k-1]<=Frame_Time)&&(node.Anim.Key[k]>Frame_Time)){
MATRIX Linear =
Linear_Interpolation(node.Anim.Matrix[k-1],node.Anim.Matrix[k],t);
mat=mat.Multiplication(Linear);
glMultMatrixf(&Linear.mat_16[0]);
}
}
for(int i=0;i<(signed)node.Mesh->Material.size();i++){
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,(const GLfloat
*)&node.Mesh->Material[i].MaterialColor.ambient);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(const GLfloat
*)&node.Mesh->Material[i].MaterialColor.diffuse);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,(const GLfloat
*)&node.Mesh->Material[i].MaterialColor.specular);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,node.Mesh->Material[i].Shininess);
if(node.Mesh->Material[i].TexNo>0){
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,
node.Mesh->TexID[node.Mesh->Material[i].TexNo-1]);
}else{
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if(node.Mesh->Material[i].Tridata.size()>1){
glVertexPointer(3, GL_FLOAT,sizeof(Tri) ,
&node.Mesh->Material[i].Tridata[0].TriVer.x);
glNormalPointer(GL_FLOAT,sizeof(Tri),&node.Mesh->Material[i].Tridata[0].TriNor.x);
//if(node.Mesh->Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT,
sizeof(Tri), &node.Mesh->Material[i].Tridata[0].TriUV.u);
glDrawArrays(GL_TRIANGLES,0,node.Mesh->Material[i].Tridata.size());
}
if(node.Mesh->Material[i].Quaddata.size()>1){
glVertexPointer(3, GL_FLOAT,sizeof(Quad) ,
&node.Mesh->Material[i].Quaddata[0].QuadVer.x);
glNormalPointer(GL_FLOAT,sizeof(Quad),&node.Mesh->Material[i].Quaddata[0].QuadNor.x);
//if(node.Mesh->Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT,
sizeof(Quad), &node.Mesh->Material[i].Quaddata[0].QuadUV.u);
glDrawArrays(GL_QUADS,0,node.Mesh->Material[i].Quaddata.size());
}
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
if(node.Node!=NULL)Draw_Frame(*node.Node,Frame_Time,mat);
if(node.Next!=NULL)Draw_Frame(*node.Next,Frame_Time,current);
if(node.Node==NULL)return;
if(node.Next==NULL)return;
return;
}
}
//アニメーション描画
void HIERARCHY::Animation_Draw(int Animation_NO,int Frame){
MATRIX mat;
Draw_Frame(Root,Frame,mat);
}
//描画
void HIERARCHY::Draw(){
MATRIX mat;
Draw_Frame(Root,0,mat);
}
//フレームを探す
void HIERARCHY::Find_Frame(NODE& node,char* name){
while(1){
if(strcmp(node.FrameName.c_str(),name)==0){
pNode=&node;
return;
}
if(node.Node!=NULL)Find_Frame(*node.Node,name);
if(node.Next!=NULL)Find_Frame(*node.Next,name);
if(node.Node==NULL)return;
if(node.Next==NULL)return;
return;
}
return;
}
//アニメーション読み込み
bool HIERARCHY::Load_Animation(FILE& fp){
char buf[255];
char name[255];
char *next;
int hierarchy=0,count=0,key=0,dummy=0,x=0,y=0,z=0,w=0;
//合成行列
MATRIX mix;
//読み込み
while(!feof(&fp))
{
ZeroMemory(buf,sizeof(buf));
fscanf_s(&fp,"%s ",buf,sizeof(buf));
//テンプレート読み飛ばし
if(strcmp(buf,"template")==0){
while(strcmp(buf,"}")){
fscanf_s(&fp,"%s ",buf,sizeof(buf));
}
continue;
}
//AnimationSetを探す
if(strcmp(buf,"AnimationSet")==0){
while(!feof(&fp))
{
fgets(buf,sizeof(buf),&fp);
if((!strstr(buf,"Animation")==NULL)&&(strstr(buf,"Animation_")==NULL)){
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);
if((!strstr(buf,"{")==NULL)&&(!strstr(buf,"}")==NULL)){//名前の抽出
sscanf_s(buf," { %s } ",&name,sizeof(name));
strtok_s( name, "}" ,&next);
pNode=NULL;
Find_Frame(Root,name);
while(!feof(&fp)){
fgets(buf,sizeof(buf),&fp);
if(!strstr(buf,"AnimationKey")==NULL){
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);//キータイプ 4…行列タイプ]
if(strstr(buf,"4;")==NULL)printf("対応していません");
fgets(buf,sizeof(buf),&fp);//キー数
count=atoi(buf);
for(int i=0;i<count;i++){
fscanf_s(&fp,"%d;%d;",&key,&dummy);//キーの位置;データの数
if((count-1==i)&&(Animation_MaxFrame<key))Animation_MaxFrame=key;
pNode->Anim.Key.push_back(key);
if(dummy!=16)printf("対応していません");
fscanf_s(&fp,"%f,%f,%f,%f,",&mix.mat_16[0],&mix.mat_16[1],&mix.mat_16[2],&mix.mat_16[3]);
fscanf_s(&fp,"%f,%f,%f,%f,",&mix.mat_16[4],&mix.mat_16[5],&mix.mat_16[6],&mix.mat_16[7]);
fscanf_s(&fp,"%f,%f,%f,%f,",&mix.mat_16[8],&mix.mat_16[9],&mix.mat_16[10],&mix.mat_16[11]);
fscanf_s(&fp,"%f,%f,%f,%f;;",&mix.mat_16[12],&mix.mat_16[13],&mix.mat_16[14],&mix.mat_16[15]);
fgets(buf,sizeof(buf),&fp);
mix._41*=Size;
mix._42*=Size;
mix._43*=Size;
pNode->Anim.Matrix.push_back(mix);
}
}
}
}
}
}
}
}
return true;
}
//メッシュ読み込み
bool HIERARCHY::Load_Mesh(FILE& fp,NODE& node){
vector <Vector3f> Vertex;//頂点
vector <Vector3f> Normal;//法線
vector <UV> uv;//UV
vector <int> VertexIndex;
vector <int> NormalIndex;
vector <int> MaterialIndex;
vector <int> FaceIndex;
char key[255];
char buf[255];
int v1=0,v2=0,v3=0,v4=0;
int Count=0,matCount=0,Hierarchy=1;
string str="";
fscanf_s(&fp,"%s ",key,sizeof(key));
//読み込み
while(!feof(&fp))
{
//キーワード 読み込み
ZeroMemory(key,sizeof(key));
fscanf_s(&fp,"%s ",key,sizeof(key));
//階層+
if(strcmp(key,"{")==0){
Hierarchy++;
}
//階層-
if(strcmp(key,"}")==0){
Hierarchy--;
if(Hierarchy==0){
Count=0;
if(Vertex.size()>0){
//マテリアル毎のデータを作成
for(int i=0;i<(signed)MaterialIndex.size();i++){
if(FaceIndex[i]==3){
for(int j=0;j<3;j++){
Tri.TriVer=Vertex[VertexIndex[Count+j]];
Tri.TriNor=Normal[NormalIndex[Count+j]];
//Tri.TriUV=uv[VertexIndex[Count+j]];
if(MaterialIndex[i]>=(signed)node.Mesh->Material.size()){
mtl.MaterialName=this->OutSide_Mat[MaterialIndex[i]].MaterialName;
mtl.MaterialColor=this->OutSide_Mat[MaterialIndex[i]].MaterialColor;
mtl.Shininess=this->OutSide_Mat[MaterialIndex[i]].Shininess;
node.Mesh->Material.push_back(mtl);
}
node.Mesh->Material[MaterialIndex[i]].Tridata.push_back(Tri);
}
Count+=3;
}else{
for(int j=0;j<4;j++){
Quad.QuadVer=Vertex[VertexIndex[Count+j]];
Quad.QuadNor=Normal[NormalIndex[Count+j]];
//Quad.QuadUV=uv[VertexIndex[Count+j]];
node.Mesh->Material[MaterialIndex[i]].Quaddata.push_back(Quad);
}
Count+=4;
}
}
}else{
node.Mesh=NULL;
}
Vertex.clear();
Normal.clear();
uv.clear();
VertexIndex.clear();
NormalIndex.clear();
MaterialIndex.clear();
FaceIndex.clear();
return true;
}
}
if(strcmp(key,"Frame")==0){
Count=0;
if(Vertex.size()>0){
//マテリアル毎のデータを作成
for(int i=0;i<(signed)MaterialIndex.size();i++){
if(FaceIndex[i]==3){
for(int j=0;j<3;j++){
Tri.TriVer=Vertex[VertexIndex[Count+j]];
Tri.TriNor=Normal[NormalIndex[Count+j]];
//Tri.TriUV=uv[VertexIndex[Count+j]];
node.Mesh->Material[MaterialIndex[i]].Tridata.push_back(Tri);
}
Count+=3;
}else{
for(int j=0;j<4;j++){
Quad.QuadVer=Vertex[VertexIndex[Count+j]];
Quad.QuadNor=Normal[NormalIndex[Count+j]];
//Quad.QuadUV=uv[VertexIndex[Count+j]];
node.Mesh->Material[MaterialIndex[i]].Quaddata.push_back(Quad);
}
Count+=4;
}
}
}else{
node.Mesh=NULL;
}
Vertex.clear();
Normal.clear();
uv.clear();
VertexIndex.clear();
NormalIndex.clear();
MaterialIndex.clear();
FaceIndex.clear();
return true;
}
//頂点 読み込み
if(strcmp(key,"Mesh")==0)
{
node.Mesh =new MESH(msh);
Hierarchy++;
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);
Count=atoi(buf);
for(int i=0;i<Count ;i++)
{
fscanf_s(&fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);
Vertex.push_back(vec3d*(float)Size);
}
//頂点インデックス読み込み
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),&fp);}//空行対策
Count=atoi(buf);
for(int i=0;i<Count ;i++)
{
int dammy=0;
fgets(buf,sizeof(buf),&fp);
str=buf;
string::size_type first = str.find_first_not_of(' ');
string::size_type tab = str.find_first_not_of('\t');
string::size_type index = str.find("3;");
if(index-first-tab==0){
sscanf_s(buf,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);
VertexIndex.push_back(v1);
VertexIndex.push_back(v2);
VertexIndex.push_back(v3);
}
if(!(index-first-tab==0)){
sscanf_s(buf,"%d;%d,%d,%d,%d;,",&dammy,&v1,&v2,&v3,&v4);
VertexIndex.push_back(v1);
VertexIndex.push_back(v2);
VertexIndex.push_back(v3);
VertexIndex.push_back(v4);
}
FaceIndex.push_back(dammy);
}
}
//法線 読み込み
if(strcmp(key,"MeshNormals")==0)
{
Hierarchy++;
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);
Count=atoi(buf);
for(int i=0;i<Count ;i++)
{
fscanf_s(&fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);
Normal.push_back(vec3d);
}
//法線インデックス読み込み
fgets(buf,sizeof(buf),&fp);
fgets(buf,sizeof(buf),&fp);
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),&fp);}//空行対策
Count=atoi(buf);
for(int i=0;i<Count ;i++)
{
int dammy=0;
fgets(buf,sizeof(buf),&fp);
str=buf;
string::size_type first = str.find_first_not_of(' ');
string::size_type tab = str.find_first_not_of('\t');
string::size_type index = str.find("3;");
if(index-first-tab==0){
sscanf_s(buf,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);
NormalIndex.push_back(v1);
NormalIndex.push_back(v2);
NormalIndex.push_back(v3);
}
if(!(index-first-tab==0)){
sscanf_s(buf,"%d;%d,%d,%d,%d;,",&dammy,&v1,&v2,&v3,&v4);
NormalIndex.push_back(v1);
NormalIndex.push_back(v2);
NormalIndex.push_back(v3);
NormalIndex.push_back(v4);
}
}
}
//マテリアルリスト
if(strcmp(key,"MeshMaterialList")==0)
{
Hierarchy++;
fgets(buf,sizeof(buf),&fp);//空改行
fgets(buf,sizeof(buf),&fp);//マテリアル数
matCount=atoi(buf);
fgets(buf,sizeof(buf),&fp);//リスト要素数
Count=atoi(buf);
for(int i=0;i<Count;i++)
{
fgets(buf,sizeof(buf),&fp);
int test=atoi(buf);
MaterialIndex.push_back(test);
}
char *next;
for(int i=0;i<matCount;i++)
{
fgets(buf,sizeof(buf),&fp);
sscanf_s(buf," { %s } ",&buf,sizeof(buf));
strtok_s( buf, "}" ,&next);
for(int j=0;j<(signed)this->OutSide_Mat.size();j++){
if(strcmp(this->OutSide_Mat[j].MaterialName.c_str(),buf)==0)node.MatNo.push_back(j);
}
}
}
}
return false;
}
//フレーム読み込み
bool HIERARCHY::Load_Frame(FILE& fp,NODE& node,int& hierarchy){
char key[255];
char *next;
int begin=0,end=0;
int current=hierarchy;//現在の階層
int file_pos;
int count;
MATRIX dum;
while(!feof(&fp))
{
//キーワード 読み込み
ZeroMemory(key,sizeof(key));
fscanf_s(&fp,"%s ",key,sizeof(key));
//ヘッダー読み飛ばし
if(strcmp(key,"Header")==0){
while(strcmp(key,"}")){
fscanf_s(&fp,"%s ",key,sizeof(key));
}
continue;
}
//テンプレート読み飛ばし
if(strcmp(key,"template")==0){
while(strcmp(key,"}")){
fscanf_s(&fp,"%s ",key,sizeof(key));
}
continue;
}
//階層+
if(strcmp(key,"{")==0){
begin++;
}
//階層-
if(strcmp(key,"}")==0){
end++;
}
//マテリアル読み込み
if(strcmp(key,"Material")==0)
{
begin++;
fgets(key,sizeof(key),&fp);
strtok_s( key, "\n" ,&next);
outmtl.MaterialName=key;
fgets(key,sizeof(key),&fp);
//ディフューズ
fscanf_s(&fp,"%f;%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z,&vec4d.w);
outmtl.MaterialColor.diffuse=(const Color4 &)vec4d;
//SHININESS
fscanf_s(&fp,"%f;",&outmtl.Shininess);
//スペキュラー
fscanf_s(&fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);
outmtl.MaterialColor.specular=(const Color4 &)vec4d;
//エミッシブ
fscanf_s(&fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);
outmtl.MaterialColor.ambient=(const Color4 &)vec4d;
this->OutSide_Mat.push_back(outmtl);
}
//ボーン
if(strcmp(key,"SkinWeights")==0){
begin++;
fgets(key,sizeof(key),&fp);
fscanf_s(&fp,"%s;",key,sizeof(key));
sscanf_s(key,"\"%s\";",&key,sizeof(key));
strtok_s( key, "\"" ,&next);
Bone_Name.push_back(key);
fgets(key,sizeof(key),&fp);
fgets(key,sizeof(key),&fp);
count=atoi(key);
for(int i=0;i<count*2;i++){fgets(key,sizeof(key),&fp);}
fscanf_s(&fp,"%f,%f,%f,%f,",&dum.mat_16[0],&dum.mat_16[1],&dum.mat_16[2],&dum.mat_16[3]);
fscanf_s(&fp,"%f,%f,%f,%f,",&dum.mat_16[4],&dum.mat_16[5],&dum.mat_16[6],&dum.mat_16[7]);
fscanf_s(&fp,"%f,%f,%f,%f,",&dum.mat_16[8],&dum.mat_16[9],&dum.mat_16[10],&dum.mat_16[11]);
fscanf_s(&fp,"%f,%f,%f,%f;;",&dum.mat_16[12],&dum.mat_16[13],&dum.mat_16[14],&dum.mat_16[15]);
bone_ofset.push_back(dum);
}
//親フレームからのトランスフォーム行列
if(strcmp(key,"FrameTransformMatrix")==0){
begin++;
fgets(key,sizeof(key),&fp);
fscanf_s(&fp,"%f,%f,%f,%f,",&node.FrameTransformMatrix.mat_16[0],&node.FrameTransformMatrix.mat_16[1],&node.FrameTransformMatrix.mat_16[2],&node.FrameTransformMatrix.mat_16[3]);
fscanf_s(&fp,"%f,%f,%f,%f,",&node.FrameTransformMatrix.mat_16[4],&node.FrameTransformMatrix.mat_16[5],&node.FrameTransformMatrix.mat_16[6],&node.FrameTransformMatrix.mat_16[7]);
fscanf_s(&fp,"%f,%f,%f,%f,",&node.FrameTransformMatrix.mat_16[8],&node.FrameTransformMatrix.mat_16[9],&node.FrameTransformMatrix.mat_16[10],&node.FrameTransformMatrix.mat_16[11]);
fscanf_s(&fp,"%f,%f,%f,%f;;",&node.FrameTransformMatrix.mat_16[12],&node.FrameTransformMatrix.mat_16[13],&node.FrameTransformMatrix.mat_16[14],&node.FrameTransformMatrix.mat_16[15]);
node.FrameTransformMatrix._41*=Size;
node.FrameTransformMatrix._42*=Size;
node.FrameTransformMatrix._43*=Size;
}
//フレーム
if(strcmp(key,"Frame")==0){
fscanf_s(&fp,"%s ",key,sizeof(key));
if(((begin==0)&&(end==0))||(end-begin==-1)){//子ノード追加
node.Node=new NODE(nde);
node.Node->FrameName=key;
node.Node->isBone=false;
file_pos=ftell(&fp);
Load_Mesh(fp,*node.Node);
fseek( &fp, file_pos, SEEK_SET );
hierarchy++;
Load_Frame(fp,*node.Node,hierarchy);//再帰呼び出し
}
if(Back==current){//階層戻り先にきた場合、同一階層追加
Back=-1;
node.Next=new NODE(nde);
node.Next->FrameName=buffer;
node.Next->isBone=false;
file_pos=ftell(&fp);
Load_Mesh(fp,*node.Next);
fseek( &fp, file_pos, SEEK_SET );
Load_Frame(fp,*node.Next,current);//再帰呼び出し
}
if(end-begin>0){//"}"が"{"より多い時は階層を戻る
strcpy_s(buffer,255,key);
Back=current-(end-begin);
return true;
}
if((end-begin==0)&&((begin!=0)&&(end!=0))){//同一階層追加
node.Next=new NODE(nde);
node.Next->FrameName=key;
node.Next->isBone=false;
file_pos=ftell(&fp);
Load_Mesh(fp,*node.Next);
fseek( &fp, file_pos, SEEK_SET );
Load_Frame(fp,*node.Next,current);//再帰呼び出し
}
//階層を戻る
if((Back!=-1)&&(Back<current))return true;
}
}
return true;
}
//階層メッシュ読み込み
bool HIERARCHY::Load_Hierarchy(char* FileName){
//Xファイルを開いて内容を読み込む
Back=-1;
int Hierarchy=0;
FILE* fp=NULL;
fopen_s(&fp,FileName,"rt");
//読み込み
fseek(fp,0,SEEK_SET);
Load_Frame(*fp,Root,Hierarchy);
fseek(fp,0,SEEK_SET);
Load_Animation(*fp);
fclose(fp);
return true;
}
|