E D R , A S I H C RSS

Ase Parser By Jhs

RenameThisPage - 적저한 이름과 하는 일이 필요할것 같아서. 궁리중 --1002

~cpp 
//#define OBJECT_BEGIN		"*NODE_TM"
#define OBJECT_BEGIN		"*GEOMOBJECT"
#define OBJECT_NAME			"*NODE_NAME"
#define OBJECT_POS			"*TM_POS"			
#define NUM_VERTEX			"*MESH_NUMVERTEX"
#define NUM_FACES			"*MESH_NUMFACES"
#define NUM_TVERTEX			"*MESH_NUMTVERTEX"
#define NUM_TFACES			"*MESH_NUMTVFACES"
#define NUM_TEXTURE			"*MATERIAL_COUNT"
#define VERTEX_LIST			"*MESH_VERTEX_LIST"
#define VERTEX				"*MESH_VERTEX"
#define FACE_LIST			"*MESH_FACE_LIST"
#define FACE				"*MESH_FACE"
#define NORMALS				"*MESH_NORMALS"
#define FACE_NORMAL			"*MESH_FACENORMAL"
#define NVERTEX				"*MESH_VERTEXNORMAL"
#define TVERTEX				"*MESH_TVERT"
#define TFACE				"*MESH_TFACE"
#define TEXTURE				"*BITMAP"
#define TEXTURE_ID			"*MATERIAL_REF"


#define UTILE				"*UVW_U_TILING"
#define VTILE				"*UVW_V_TILING"
#define UOFFSET				"*UVW_U_OFFSET"
#define VOFFSET				"*UVW_V_OFFSET"
#define WIREFRAME_COLOR		"*WIREFRAME_COLOR"



//- 2002/01 추가.. ----------------------------------------------
#define OBJECT_PARENT		"*NODE_PARENT"
#define OBJECT_ROW0			"*TM_ROW0"
#define OBJECT_ROW1			"*TM_ROW1"
#define OBJECT_ROW2			"*TM_ROW2"
#define OBJECT_ROW3			"*TM_ROW3"
#define OBJECT_ROTAXIS		"*TM_ROTAXIS"
#define OBJECT_ROTANGLE		"*TM_ROTANGLE"

#define OBJECT_ANI			"*TM_ANIMATION"

#define OBJECT_ROT_EXIST	"*CONTROL_ROT_TRACK"
#define OBJECT_POS_EXIST	"*CONTROL_POS_TRACK"

#define OBJECT_ROT_SAMPLE	"*CONTROL_ROT_SAMPLE"
#define OBJECT_POS_SAMPLE	"*CONTROL_POS_SAMPLE"
//---------------------------------------------------------------

// - 피지크 관련 정보 -------------------------------------------
// pv : physique vertex 의 의미
#define PV_NUM				"*PHYSIQUE_NUMVERTEXASSIGNMENT" // 전체 PV 개수. 별로 의미 없다.. 본 개개에 할당된 PV수가 필요하므로..
#define PV_NONBLEND			"*PHYSIQUE_NONBLENDED_RIGIDTYPE"
#define PV_BLEND_ASSIGNMODE "*PHYSIQUE_BLENDED_RIGIDTYPE_LIST"
#define PV_BLEND_ASSIGN		"*PHYSIQUE_VERTEXASSIGNMENT_NODE"
//---------------------------------------------------------------


// a triangle in the model
typedef struct
{
	int	vertIndex[3];	// indicies for the verts that make up this triangle
	int coordIndex[3];	// indicies for the tex coords to texture this face
	vec3_t normal;		// face normal
} triangle_t;

// texture information for the model
typedef struct
{
	char texName[51];	// texture name
	int	texId;			// texture id
	vec_t uTile;		// u tiling of texture
	vec_t vTile;		// v tiling of    "
	vec_t uOffset;		// u offset of    "
	vec_t vOffset;		// v offset of    "
} texture_t;



~cpp 
class CHS_GObject 
{
protected:
	// -------------------------------------
public:
	/* 
	// 원래 STL 리스트로 전체 노드를 관리했는데 지금은 사용안함. 전체 노드 리스트는 이 모듈의  cpp 파일에 전역으로 선언.
	static StlLink	s_RootList;
	static StlLink	s_AllList;
	*/

	// -------------------------------------
	CHS_GObject();
	virtual ~CHS_GObject();

	virtual void Render (void* pArg) {};
	virtual void InitObject (void* pArg) {};


	// -------------------------------------
	// static member
	// -------------------------------------
	static vec_t GetFloatVal (FILE *s); // 파일에서 Float형 값을 하나 읽는다.

	static bool LoadAse (char* filename); // ASE 파일을 읽어들인다.
	static void ModelAlloc (CHS_GObject* pO); // 쓰이지 않음. j_ase 모듈에 있는 aseAllocate2CHS_Model을 사용
	static bool GetAseAllInfo (FILE *s); // 각 노드의 헤더정보와, 연결된 피지크 정점 개수를 카운트하고 에니메이션 키가 없는 노드의 에니메이션 키를 1로 초기화한다.
	static void GetAseAllData (FILE *s, DWORD *max_time); // 각 노드의 나머지 정보를 읽는다. 정점, 페이스, 노멀, 에니메이션 키(위치, 회전), 피지크의 weight  등등.
	static void ReleaseModels (); // s_AllList상의 모든 노드를 삭제한다.
	static void UpdatePickedPoint (int &cl_x, int &cl_y, int &width, int &height); // Picking을 위해 윈도우 상의 클릭된 점의 좌표가 월드 좌표계 상에서 얼마인지 계산한다.


	static vec3_t PickedPoint[2]; // 위의 함수에서 계산한 결과가 저장된다.
	
};

~cpp 
// static function
/*
	Func - LoadAse
	Desc - 지정된 Ase 파일을 읽어들이고 그 파일의 월드 좌표계상으로 저장된 정점들을 로컬 좌표계로 변환하며 
			각 노드마다 자신의 상위 노드에 좌표계에 기준해서 자신의 좌표계로 이동시켜주는 메트릭스를 생성한다.( -> AniTM)
*/
bool CHS_GObject::LoadAse (char* filename)
{
	FILE *s;
	DWORD max_time = 0;
	bool	bResult;
	if (!(s = fopen (filename, "r")))	{
		char ds[255];
		sprintf (ds, "# %s not found\n", filename);
		OutputDebugString (ds);
		return false;
	}
	else
		bResult = GetAseAllInfo (s);

	// 0번 모델을 스키닝 통짜 모델이라 가정
	pNodeList [0]->bIsSkinModel = TRUE; 

	// 모델의 메모리 할당.
	for (int i=0; i<nNodeNum; i++)
	{
		//pNodeList [i]->ModelAlloc ();
		aseAllocate2CHS_Model (pNodeList [i]);
	}


	// 하이어라키 정보 생성 -----------------------------------------------
	// : 루트 리스트에 트리 구조로이루어진 모델들을 링크 한다.
	for (int i1=0; i1<nNodeNum; i1++)
	{
		if (strcmp (pNodeList [i1]->ParentName, "")) {
			for (int i2=0; i2<nNodeNum; i2++)
			{
				if (pNodeList [i1] != pNodeList [i2] && 
					!strcmp (pNodeList [i1]->ParentName, pNodeList [i2]->Name))
				{
					pNodeList [i1]->SetParent (pNodeList [i2]); // 자식에게 부모가 누구인지 지정

					pNodeList [i2]->AddChildNum (); // 부모의 자식수 카운트를 1 늘림
					CHS_Model** pChildTmp = pNodeList [i2]->GetChildPointer (); // 임시 보관
					CHS_Model** pDest = new CHS_Model* [pNodeList [i2]->GetChildNum ()]; // 새 메모리 할당
					memcpy (pDest, pChildTmp, sizeof (CHS_Model*) * (pNodeList [i2]->GetChildNum ()-1)); // 복사
					pDest[pNodeList [i2]->GetChildNum ()-1] = pNodeList [i1]; // 부모에게 추가된 새 자식 저장
					pNodeList [i2]->SetChildPointer (pDest); // 새 메모리를 자식 포인터로 지정

					delete [] pChildTmp; // 임시 보관 장소 삭제
				}
			}
		}
	}
	// 정점 데이타 읽기 ---------------------------------------------------
	CHS_GObject::GetAseAllData (s, &max_time);


	// 정점을 wcs -> lcs로 변환 -------------------------------------------
	// ani_tm 최초 update -------------------------------------------------
	for (i=0; i<nNodeNum; i++) {
		pNodeList[i]->InitObject (0);
		if (i!=0) pNodeList[i]->MulMatInverse (FALSE);
//		pNodeList[i]->MulMatInverse (FALSE);
		pNodeList[i]->UpdateAniTM (FALSE);

		// BoundingVolumn 계산
		pNodeList[i]->CreateVolumn (pNodeList[i]->verts, pNodeList[i]->numVertex);
	}

	// 텍스쳐 데이타 읽기 -------------------------------------------------
	// : 미구현

	// 루트 노드 리스트 갱신 ----------------------------------------------
	// : 루트 노드만 가지고 있는 리스트를 만든다.

//	StlLink* pRL = &(s_RootList);
//	for(StlListItor itorAll = pSL->begin (); itorAll!= pSL->end (); ++itorAll) {
	for (i=0; i<nNodeNum; i++) {
		CHS_Model*	pTmp = pNodeList[i];
		if (!strcmp(pTmp->ParentName, ""))	{
			//pRL->push_back ((void*)pTmp);
			pTmp->SetTimeSkip (800);
			pTmp->SetMaxTime (max_time);

			pRootList [nRootNum] = pTmp;
			nRootNum++;

			char debug_buf[255];
			sprintf (debug_buf,"\n#ROOT NODE: %s", pTmp->Name);
			OutputDebugString (debug_buf);
		}
	}

	fclose (s);

	return true;
}
// static function 
// 픽킹을 위해 클릭 된 점의 좌표를 계산한다.
// 입력값: 마우스 클릭된 포인트
void CHS_GObject::UpdatePickedPoint (int &cl_x, int &cl_y, int &width, int &height)
{

	// 시점 계산
	PickedPoint [0][0] = float(cl_x)*2.0f/float(width) - 1.0f;
	PickedPoint [0][1] = float(cl_y)*2.0f/float(height) - 1.0f;
	PickedPoint [0][1] = -PickedPoint [0][1];
	PickedPoint [0][2] = 5.0f;

	mat44_t mat_mv, inv_mat_mv;
	glGetFloatv (GL_PROJECTION_MATRIX, mat_mv);
	matrix44_inverse (inv_mat_mv, mat_mv);

	vectorCopy (PickedPoint[0], PickedPoint[1]);
	PickedPoint[1][2] -= 10.0;

	matrixMultiplyVector3 (inv_mat_mv, PickedPoint[0]);
	matrixMultiplyVector3 (inv_mat_mv, PickedPoint[1]);




}

// static function 
// s_AllList상의 모든 노드를 삭제한다.
void CHS_GObject::ReleaseModels ()
{
	/*
	StlLink* pSL = &(CHS_GObject::s_AllList);
	for(StlListItor itor=pSL->begin (); itor!=pSL->end ();++itor) {
		delete (*itor);
		itor = pSL->erase(itor);
	}
	*/
	for (int i=0; i<nNodeNum; i++)
	{
		delete pNodeList[i];
	}
}
// static function
bool CHS_GObject::GetAseAllInfo (FILE *s)
{
	char data[255];

	rewind (s); //파일포인터를 맨 앞으로..

	CHS_Model* pM;
	while (!feof (s)) //파일 스트림이 끝났는지 check!
	{
		fscanf (s, "%s", &data);

		if (!strcmp (data, OBJECT_BEGIN))
		{
			pM = new CHS_Model;
			//pLink->AddTail(pModel);
			//CHS_GObject::s_AllList.push_back ((void*)pM);
			pNodeList [nNodeNum] = pM;
			nNodeNum++;
		}
		else if (!strcmp (data, OBJECT_NAME))
		{	// 자기 노드 이름
			char temp[128];

			int c_index = 0;

			while (fgetc (s) != '"') {}
			while (1)	{
				temp [c_index++] = (char) fgetc (s);
				if (temp [c_index-1] == '"') {
					temp [c_index-1] = '\0';
					break;
				}
			}
			memcpy (pM->Name, temp, strlen(temp));
		}
		else if (!strcmp (data, OBJECT_PARENT))
		{ // 부모 노드 이름
			char temp[128];

			int c_index = 0;

			while (fgetc (s) != '"') {}
			while (1)	{
				temp [c_index++] = (char) fgetc (s);
				if (temp [c_index-1] == '"') {
					temp [c_index-1] = '\0';
					break;
				}
			}
			memcpy (pM->ParentName, temp, strlen(temp));
		}
		else if (!strcmp (data, OBJECT_POS)) 
		{
			// 일반적인 ascii export plug in을 사용했을 경우
			// 이 pos 값은 월드 좌표로 계산되어 지는듯함. *MESH에 들어있는 vertex 좌표들은 
			// 모두 월드 좌표들이었습니다. 모델 각각의 위치로 Translate 나 Rotate를 
			// 할 필요는 없었음.

			fscanf (s, "%f %f %f", &pM->Pos[0]
								 , &pM->Pos[2]
								 , &pM->Pos[1]);
			pM->Pos[2] = -pM->Pos[2];

		}
		else if (!strcmp (data, OBJECT_ROTAXIS))
		{

			fscanf (s, "%f %f %f", &pM->Axis[0]
								 , &pM->Axis[2]
								 , &pM->Axis[1]);
			pM->Axis[2] = -pM->Axis[2];

		}
		else if (!strcmp (data, OBJECT_ROTANGLE)) {
			vec_t x;
			fscanf (s, "%f", &x);
//			pM->Angle = -x;
			pM->Angle = x;
	
			matrix_t tmp_trans, tmp_rot;
			matrixIdentity (tmp_trans);
			matrixIdentity (tmp_rot);
			matrixIdentity (pM->tm);
			matrixTranslate (tmp_trans, pM->Pos);
			AngleAxis2Matrix (tmp_rot, pM->Axis, pM->Angle);
			matrixMultiply (tmp_rot, tmp_trans, pM->tm);

			matrix44_inverse (pM->inv_tm, pM->tm);
		}
		else if (!strcmp (data, OBJECT_ROW0))
		{

			fscanf (s, "%f %f %f", &pM->tm[0]
								 , &pM->tm[2]
								 , &pM->tm[1]);
			pM->tm[2] = -pM->tm[2];
			pM->tm[3] = 0.0f;

		}
		else if (!strcmp (data, OBJECT_ROW1))
		{
			fscanf (s, "%f %f %f", &pM->tm[8]
								 , &pM->tm[10]
								 , &pM->tm[9]);
			pM->tm[10] = -pM->tm[10];
			pM->tm[11] = 0.0f;



		}
		else if (!strcmp (data, OBJECT_ROW2))
		{

			fscanf (s, "%f %f %f", &pM->tm[4]
								 , &pM->tm[6]
								 , &pM->tm[5]);
			pM->tm[6] = -pM->tm[6];
			pM->tm[7] = 0.0f;

		}
		else if (!strcmp (data, OBJECT_ROW3))
		{

			fscanf (s, "%f %f %f", &pM->tm[12]
								 , &pM->tm[14]
								 , &pM->tm[13]);
			pM->tm[14] = -pM->tm[14];
			pM->tm[15] = 1.0f;

//			matrix44_inverse (pM->inv_tm, pM->tm);
		}
		else if (!strcmp (data, NUM_VERTEX))
			fscanf (s, "%d", &pM->numVertex);
		else if (!strcmp (data, NUM_FACES))
			fscanf (s, "%d", &pM->numFaces);
		else if (!strcmp (data, NUM_TVERTEX)) //texture mapped vertex?
		{
			fscanf (s, "%d", &pM->numTexVertex);
			pM->bTexture_on = 1;	//만약 텍스쳐 버텍스들이 존재한다면 모델객체의 텍스쳐 플래그 온
		}
		else if (!strcmp (data, NUM_TFACES)) //texture mapped face?
			fscanf (s, "%d", &pM->numTexFaces);
		else if (!strcmp (data, NUM_TEXTURE))
		{
			// 일단 텍스쳐 정보 부분은 삭제
			/*
			int n = (int) aseGetFloatVal(s);
			pTex = new char*[n]; //pTex 는 이중 포인터
			app_con.numTex = n;
			*/
		}
		else if (!strcmp (data, NORMALS))
			pM->bNormals = true;
		else if (!strcmp (data, TEXTURE))
		{
			// 일단 텍스쳐 정보 부분은 삭제
			/*
			aseGetTextureName1 (s);
			*/
		}
		else if (!strcmp (data, OBJECT_ANI))
		{ // rotate sample이 존재함을 표시.
			//pM->bRotKey = TRUE;
		}
		else if (!strcmp (data, OBJECT_ROT_EXIST))
		{
			pM->bRotKey = TRUE;
		}
		else if (!strcmp (data, OBJECT_POS_EXIST))
		{
			pM->bPosKey = TRUE;
		}
		else if (!strcmp (data, OBJECT_ROT_SAMPLE))
		{ 
//			pM->AddKeyNum (); // == pM->keyNum++
			pM->rotkeyNum++;
		}
		else if (!strcmp (data, OBJECT_POS_SAMPLE))
		{
			pM->poskeyNum++;
		}
		else
			fgets (data, sizeof (data), s);
	}
	// 각각의 본에 할당되는 PV의 개수 count
	rewind (s);
	while (!feof (s)) //파일 스트림이 끝났는지 check!
	{
		int x;
		vec_t w;
		char tmp_name[255];
		char name[255];

		fscanf (s, "%s", &data);
		if (!strcmp (data, PV_NONBLEND)) {
			fscanf (s, "%d ", &x);
			int c_index = 0;
			while (fgetc (s) != '"') {}
			while (1)	{
				tmp_name [c_index++] = (char) fgetc (s);
				if (tmp_name [c_index-1] == '"') {
					tmp_name [c_index-1] = '\0';
					break;
				}
			}

			memcpy (name, tmp_name, strlen(tmp_name)+1);

			for (int i=0;i<nNodeNum;i++) {
				if (!strcmp (pNodeList [i]->Name, name)) 
					pNodeList [i]->GetPSQInfo()->nPVertexCount++;
			}
		}
		else if (!strcmp (data, PV_BLEND_ASSIGN)) {

			fscanf (s, "%d %f ", &x, &w);
			int c_index = 0;
			while (fgetc (s) != '"') {}
			while (1)	{
				tmp_name [c_index++] = (char) fgetc (s);
				if (tmp_name [c_index-1] == '"') {
					tmp_name [c_index-1] = '\0';
					break;
				}
			}

			memcpy (name, tmp_name, strlen(tmp_name)+1);

			for (int i=0;i<nNodeNum;i++) {
				if (!strcmp (pNodeList [i]->Name, name)) 
					pNodeList [i]->GetPSQInfo()->nPVertexCount++;
			}

		}
		else
			fgets (data, sizeof (data), s);
	}
	// 전체 키 설정
	for (int i=0;i<nNodeNum;i++) {
		pNodeList [i]->SetKeyNum (1);

		if (!pNodeList [i]->bPosKey)
			pNodeList [i]->poskeyNum = 1;
		if (!pNodeList [i]->bRotKey)
			pNodeList [i]->rotkeyNum = 1;

		if (pNodeList [i]->rotkeyNum > 1)
			pNodeList [i]->SetKeyNum (pNodeList [i]->rotkeyNum);
		if (pNodeList [i]->poskeyNum > pNodeList [i]->rotkeyNum) 
			pNodeList [i]->SetKeyNum (pNodeList [i]->poskeyNum);
	}

	return true;
}
// 모델에 메모리 할당.
void CHS_GObject::ModelAlloc (CHS_GObject* pO)
{

}

// static
vec_t CHS_GObject::GetFloatVal (FILE *s)
{
	vec_t v;
	fscanf (s, " %f", &v);
	return v;
}
// 모델에 정점 정보 입력
void CHS_GObject::GetAseAllData (FILE *s, DWORD *max_time)
{
	char data[255];	
	int	count	= 0;
	int pv_count[50] = {0,};
	int nBlendAssignIndex;
	CHS_Model* pM = 0;

//	StlListItor itor = s_AllList.begin ();
//	pM = (CHS_Model*)*itor;
	pM = pNodeList[0];

	rewind (s);

	while (!feof (s))
	{
		fscanf (s, "%s", &data);
		if (strcmp (data, OBJECT_BEGIN) == 0)
		{
			if (count == 0)
				//itor = CHS_GObject::s_AllList.begin ();
				pM = pNodeList [0];
			else 
				//itor++;
				pM = pNodeList [count];
			count++;
			//pM = (CHS_Model*)*itor;

		}
		else if (strcmp (data, VERTEX) == 0)
		{
			//CHS_GObject::GetVertex (s, pM);
			int index;
			fscanf (s, "%d", &index);
			// swap y and z cause 3dsm likes too
			fscanf (s, "%f %f %f",
				&pM->verts[index][0],
				&pM->verts[index][2],
				&pM->verts[index][1]);
			// in 3dsm negative z goes out of the screen, we want it to go in
			pM->verts[index][2]	=	-(pM->verts[index][2]);
		}
		else if (strcmp (data, TVERTEX) == 0)
		{
			//CHS_GObject::GetTVertex (s, pM);
			int index;
			fscanf (s, "%d", &index);
			fscanf (s, "%f %f", &pM->texVerts[index][0], &pM->texVerts[index][1]);
		}
		else if (strcmp (data, NVERTEX) == 0)
		{
			//CHS_GObject::GetNVertex (s, pM);
			int	index;
			fscanf (s, "%d", &index);
			fscanf (s, "%f %f %f",
				&pM->vertNorms[index][0],
				&pM->vertNorms[index][2],
				&pM->vertNorms[index][1]);
			pM->vertNorms[index][2] = -pM->vertNorms[index][2];
		}
		else if (strcmp (data, FACE_NORMAL) == 0)
		{
			//CHS_GObject::GetFaceNormal (s, pM);
			int	index;
			fscanf (s, "%d", &index);
			fscanf (s, "%f %f %f",
				&pM->faces[index].normal[0],
				&pM->faces[index].normal[2],
				&pM->faces[index].normal[1]);
			pM->faces[index].normal[2] = -pM->faces[index].normal[2];
		}
		else if (strcmp (data, FACE) == 0)
		{
			//CHS_GObject::GetFace (s, pM);
			int index;
			fscanf (s, "%d:", &index);
			fscanf (s, "\tA:\t%d B:\t%d C:\t%d",
				&pM->faces[index].vertIndex[0],
				&pM->faces[index].vertIndex[1],
				&pM->faces[index].vertIndex[2]);
/*				&pM->faces[index].vertIndex[2],
				&pM->faces[index].vertIndex[1]);*/
		}
		else if (strcmp (data, TFACE) == 0)
		{
			//CHS_GObject::GetTFace (s, pM);
			int index;
			fscanf (s, "%d:", &index);
			fscanf (s, "%d %d %d",
				&pM->faces[index].coordIndex[0],
				&pM->faces[index].coordIndex[1],
				&pM->faces[index].coordIndex[2]);
		}
		/*
		else if (strcmp (data, TEXTURE) == 0)
		{
			aseGetTextureName (s, p); //모델t 구조체에 들어가는 텍스쳐 네임은 사용x
									  //textureLink 에 들거나는 네임 사용
		}
		*/
		else if (!strcmp (data, OBJECT_ROT_SAMPLE))
		{ 
			// animation - rotate sampling
			static int nTmpCount = 0;
			vec3_t v;
			vec_t t;
			// 파싱한 angular displacement?? 로 추정되는 것을.. 
//			fscanf (s, "%d", &(pM->pRotKey[nTmpCount].time));			fgetchar ();
//			fscanf (s, "%f", &v[0]);			fgetchar ();
//			fscanf (s, "%f", &v[2]);			fgetchar ();
//			fscanf (s, "%f", &v[1]);			fgetchar ();
//			fscanf (s, "%f", &t);

			fscanf (s, "%d", &(pM->pRotKey[nTmpCount].time));			fgetchar ();
			fscanf (s, "%f", &v[0]);			fgetchar ();
			fscanf (s, "%f", &v[2]);			fgetchar ();
			fscanf (s, "%f", &v[1]);			fgetchar ();
			fscanf (s, "%f", &t);
			
			// max_time 값 업데이트
			if (pM->pRotKey[nTmpCount].time > *max_time) *max_time = pM->pRotKey[nTmpCount].time;

			v[2] = -v[2];


			// -----------------------------------------------------------
			// 180도 이상되는 회전각을 가진 키에 대한 처리
			// : 회전축을 뒤집고 회전각은 '각 = 360-각'으로 처리해준다.
			// -----------------------------------------------------------
			if (t >= degToRad(180)) {
				t = degToRad(360) - t;
				vectorScale (v, -1.0);
			}

			// 쿼터니언으로 변환해서 저장.
			// !! 여기서.. angle은 왼손 좌표계를 기준으로 한다고 함.. 
			// 오픈지엘은 오른손 좌표계이므로 부호를 반대로.. (-t)
//			AngleAxis2Quat (&pM->pRotKey[nTmpCount].q, v, -t);
			AngleAxis2Quat (&pM->pRotKey[nTmpCount].q, v, t);
			nTmpCount++;

			if (nTmpCount == pM->rotkeyNum)
				nTmpCount = 0;

		}
		else if (!strcmp (data, OBJECT_POS_SAMPLE))
		{ 
			// animation - position sampling
			static int nTmpCount2 = 0;
			vec3_t p;
			fscanf (s, "%d", &(pM->pPosKey[nTmpCount2].time));			fgetchar ();
			fscanf (s, "%f", &p[0]);			fgetchar ();
			fscanf (s, "%f", &p[2]);			fgetchar ();
			fscanf (s, "%f", &p[1]);

			p[2] = -p[2];
			// max_time 값 업데이트
			if (pM->pPosKey[nTmpCount2].time > *max_time) *max_time = pM->pPosKey[nTmpCount2].time;

			
			memcpy (&pM->pPosKey[nTmpCount2].p, p, sizeof (vec3_t));
			nTmpCount2++;

			if (nTmpCount2 == pM->poskeyNum)
				nTmpCount2 = 0;
		
		}
		else if (!strcmp (data, PV_NONBLEND))
		{
			int index;
			char tmp_name[255];
			char name[255];

			fscanf (s, "%d ", &index);

			int c_index = 0;
			while (fgetc (s) != '"') {}
			while (1)	{
				tmp_name [c_index++] = (char) fgetc (s);
				if (tmp_name [c_index-1] == '"') {
					tmp_name [c_index-1] = '\0';
					break;
				}
			}

//			memcpy (name, tmp_name+1, strlen(tmp_name)-2);
			memcpy (name, tmp_name, strlen(tmp_name)+1);
//			name [strlen(tmp_name)-2] = '\0';


			for (int i=0;i<nNodeNum;i++) {
				if (!strcmp (pNodeList [i]->Name, name)) 
				{
					pNodeList [i]->GetPSQInfo()->pV[pv_count[i]].nVIndex = index;
					pNodeList [i]->GetPSQInfo()->pV[pv_count[i]].weight = 1.0;
					pv_count[i]++;
				}
			}
		}
		else if (!strcmp (data, PV_BLEND_ASSIGNMODE))
		{
			fscanf (s, "%d", &nBlendAssignIndex);
		}
		else if (!strcmp (data, PV_BLEND_ASSIGN))
		{
			int index;
			vec_t w;
			char tmp_name[255];
			char name[255];

			//fscanf (s, "%d %f %s", &index, &w, &tmp_name);
			fscanf (s, "%d %f ", &index, &w);
			int c_index = 0;
			while (fgetc (s) != '"') {}
			while (1)	{
				tmp_name [c_index++] = (char) fgetc (s);
				if (tmp_name [c_index-1] == '"') {
					tmp_name [c_index-1] = '\0';
					break;
				}
			}
			memcpy (name, tmp_name, strlen(tmp_name)+1);

//			memcpy (name, tmp_name+1, strlen(tmp_name)-2);
//			name [strlen(tmp_name)-2] = '\0';

			for (int i=0;i<nNodeNum;i++) {
				if (!strcmp (pNodeList [i]->Name, name)) 
				{
					pNodeList [i]->GetPSQInfo()->pV[pv_count[i]].nVIndex = nBlendAssignIndex;
					pNodeList [i]->GetPSQInfo()->pV[pv_count[i]].weight = w;
					pv_count[i]++;
				}
			}
		}
		else if (strcmp (data, TEXTURE_ID) == 0)
		{
			pM->texture.texId = (int) GetFloatVal (s);
		}
		// 아래 부분은 없애두 될듯.. 그리고 texture는 모델과는 별도로 관리하는 것이 좋을 것 같다. 
		// 모델에는 텍스쳐의 참조 번호 정도만 저장하면 될 것 같다.
		else if (strcmp (data, UTILE) == 0)
		{
			pM->texture.uTile = GetFloatVal (s);
		}
		else if (strcmp (data, VTILE) == 0)
		{
			pM->texture.vTile = GetFloatVal (s);
		}
		else if (strcmp (data, UOFFSET) == 0)
		{
			pM->texture.uOffset = GetFloatVal (s);
		}
		else if (strcmp (data, VOFFSET) == 0)
		{
			pM->texture.vOffset = GetFloatVal (s);
		}
		else 
			fgets (data, sizeof (data), s);
	}


	
	mat44_t parent_inv, tmp_out;
	for (int i=0;i<nNodeNum;i++) {

		if (!pNodeList [i]->bPosKey) {
			matrixIdentity (parent_inv);
			matrixIdentity (tmp_out);

			pNodeList[i]->pPosKey[0].time = 0;

			// 하이어라키 정보를 생성한 후이므로..
			if (pNodeList [i]->RetParent ()) matrix44_inverse (parent_inv, pNodeList [i]->RetParent ()->tm);
			matrixMultiply (pNodeList [i]->tm, parent_inv, tmp_out);

			pNodeList[i]->pPosKey[0].p[0] = tmp_out[12];
			pNodeList[i]->pPosKey[0].p[1] = tmp_out[13];
			pNodeList[i]->pPosKey[0].p[2] = tmp_out[14];

		}
		if (!pNodeList [i]->bRotKey) {
			pNodeList[i]->pRotKey[0].time = 0;
			AngleAxis2Quat (&pNodeList[i]->pRotKey[0].q, pNodeList[i]->Axis, pNodeList[i]->Angle);
		}



	}

}

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:32
Processing time 0.0813 sec