#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;
}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;
}vec4d;
//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 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;//メッシュ
ANIMATION Anim;//アニメーションデータ
}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,int size);
NODE Root;//ルートノード
int Size;//サイズ
int Animation_MaxFrame;//最大フレーム
private:
bool Load_Hierarchy(char* FileName); //階層メッシュ読み込み
void Find_Frame(NODE& node,char* name);//フレームを探す
bool Load_Frame(FILE& fp,NODE& node,int& hierarchy);
//フレーム読み込み
bool Load_Mesh(FILE& fp,NODE& node);//メッシュ読み込み
bool Load_Animation(FILE& fp);//アニメーション読み込み
MATRIX Linear_Interpolation(MATRIX& a,MATRIX& b,float t);//線形補間
QUATERNION Spherical_Linear_Interpolation( QUATERNION& q1, QUATERNION&
q2, float t);//球面線形補間
void Init();
char buffer[255];
int Back;//階層戻し
NODE* pNode;//ノードポインタ
};
//コンストラクタ
HIERARCHY::HIERARCHY(){
Init();
}
//コンストラクタ
HIERARCHY::HIERARCHY(char* FileName,int size){
Init();
Size=size;
Load_Hierarchy(FileName);
}
//初期化
void HIERARCHY::Init(){
Root.Node=NULL;
Root.Next=NULL;
Root.FrameName="Root";
Root.Mesh=NULL;
}
//球面線形補間
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];
vector <QUATERNION> Quaternion;
vector <Vector3f> Transform;
vector <Vector3f> Scaling;
vector <int> Key1;
vector <int> Key2;
vector <int> Key3;
int hierarchy=0,count=0,keyID,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));
//AnimationSetを探す
if(strcmp(buf,"AnimationSet")==0){
while(!feof(&fp))
{
fgets(buf,sizeof(buf),&fp);
if(strstr(buf,"AnimationKey")==NULL){
if((!strstr(buf,"{")==NULL)&&(!strstr(buf,"}")==NULL)){//名前の抽出
sscanf_s(buf," { %s } ",&name,sizeof(name));
pNode=NULL;
Find_Frame(Root,name);
pNode->Anim.Matrix.resize(Key3.size());
for(int i=0;i<(signed)Key3.size();i++){
if(Key1.size()==Key3.size()){
Quaternion[i].y=Quaternion[i].y*-1;
Quaternion[i].z=Quaternion[i].z*-1;
mix=Quaternion[i].ToMatrix();
}
if(Key2.size()==Key3.size()){
mix._11*=Scaling[i].x;
mix._21*=Scaling[i].x;
mix._31*=Scaling[i].x;
mix._12*=Scaling[i].y;
mix._22*=Scaling[i].y;
mix._32*=Scaling[i].y;
mix._13*=Scaling[i].z;
mix._23*=Scaling[i].z;
mix._33*=Scaling[i].z;
}
mix._41=Transform[i].x*Size;
mix._42=Transform[i].y*Size;
mix._43=Transform[i].z*Size;
pNode->Anim.Key.push_back(Key3[i]);
for(int
j=0;j<16;j++)pNode->Anim.Matrix[i].mat_16[j]=mix.mat_16[j];
}
Animation_MaxFrame=Key3[Key3.size()-1];
Quaternion.clear();
Scaling.clear();
Transform.clear();
Key1.clear();
Key2.clear();
Key3.clear();
}
}else{
fgets(buf,sizeof(buf),&fp);//キー 0 回転 , 1 拡大縮小 , 2 平行移動
keyID=atoi(buf);
fgets(buf,sizeof(buf),&fp);//キーデータの個数
count=atoi(buf);
switch (keyID){
case 0:
for(int i=0;i<count;i++){
fscanf_s(&fp,"%d;%d;%f,%f,%f,%f;;,",&key,&dummy,&qua.w,&qua.x,&qua.y,&qua.z);
Key1.push_back(key);
Quaternion.push_back(qua);
}
break;
case 1:
for(int i=0;i<count;i++){
fscanf_s(&fp,"%d;%d;%f,%f,%f;;,",&key,&dummy,&vec3d.x,&vec3d.y,&vec3d.z);
Key2.push_back(key);
Scaling.push_back(vec3d);
}
break;
case 2:
for(int i=0;i<count;i++){
fscanf_s(&fp,"%d;%d;%f,%f,%f;;,",&key,&dummy,&vec3d.x,&vec3d.y,&vec3d.z);
Key3.push_back(key);
Transform.push_back(vec3d);
}
break;
default:
break;
}
}
}
}
}
Animation_MaxFrame=pNode->Anim.Key[pNode->Anim.Key.size()-1];
Quaternion.clear();
Scaling.clear();
Transform.clear();
Key1.clear();
Key2.clear();
Key3.clear();
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,Hierarchy=1;
string str="";
fscanf_s(&fp,"%s ",key,sizeof(key));
node.Mesh =new MESH(msh);
//読み込み
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;
//マテリアル毎のデータを作成
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;
}
}
Vertex.clear();
Normal.clear();
uv.clear();
VertexIndex.clear();
NormalIndex.clear();
MaterialIndex.clear();
FaceIndex.clear();
return true;
}
}
if(strcmp(key,"Frame")==0){
Count=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;
}
}
Vertex.clear();
Normal.clear();
uv.clear();
VertexIndex.clear();
NormalIndex.clear();
MaterialIndex.clear();
FaceIndex.clear();
return true;
}
//頂点 読み込み
if(strcmp(key,"Mesh")==0)
{
Hierarchy++;
fgets(buf,sizeof(buf),&fp);//データは2行下にあると推定 改行する
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);//データは2行下にあると推定 改行する
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);//データは2行下にあると推定 改行する
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);//データは2行下にあると推定 改行する
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);//マテリアル数
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);
}
}
//マテリアル読み込み
if(strcmp(key,"Material")==0)
{
Hierarchy++;
fgets(buf,sizeof(buf),&fp);//直後の行にあると推定 改行する
//ディフューズ
fscanf_s(&fp,"%f;%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z,&vec4d.w);
mtl.MaterialColor.diffuse=(const Color4 &)vec4d;
//SHININESS
fscanf_s(&fp,"%f;",&mtl.Shininess);
//スペキュラー
fscanf_s(&fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);
mtl.MaterialColor.specular=(const Color4 &)vec4d;
//エミッシブ
fscanf_s(&fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);
mtl.MaterialColor.ambient=(const Color4 &)vec4d;
node.Mesh->Material.push_back(mtl);
}
}
return false;
}
//フレーム読み込み
bool HIERARCHY::Load_Frame(FILE& fp,NODE& node,int& hierarchy){
char key[255];
int begin=0,end=0;
int current=hierarchy;//現在の階層
int file_pos;
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,"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;
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;
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;
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;
}
|