~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);
		}
	}
}