2013-01-04 2 views
3

obj 모델을 내 OpenGL 프로그램으로 가져오고 싶습니다. 웨이브 프런트 obj 파일 형식을 구문 분석

class CustomVertex : public IVtxFmt 
{ 
public: 
    float m_Position[3];  // x, y, z  offset 0, size = 3*sizeof(float)  
    float m_Normal[3];  // nx, ny, nz; offset 3 
    float m_TexCoords[2];  // u, v   offset 6 
    float m_Colour[4];  // r, g, b, a offset 8 
    float m_Tangent[3];  // r, g, b  offset 12 
    float m_Bitangent[3];  // r, g, b  offset 15 
}; 

그래서 내가 인터넷에서 다운로드 한 통나무 집의 모델로 일하고 있어요 : 나는 쉐이더로 데이터를 전달하는 데 사용하는 속성 클래스/데이터 형식을 가지고있다.

로그 캐빈에는 여러 정점, 법선 및 텍스처 좌표 정의가 있으며 그 뒤에 얼굴 정의 목록이옵니다.

그래서 내 첫 번째 본능은 OBJ 파일을 구문 분석하고 정의 (210 개) 정점, 100 개 텍스 좌표 80 법선이있을 수 있으므로, 내 CustomVertex 형식으로 변환하는 간단하지의

vector<vertex> 
vector<Normal> 
vector<TexCoord> 

로 끝날 것이 었습니다 파일. 이 형식 ~ 390면의 목록 후

:

f 83/42/1 67/46/1 210/42/1 

나는 파일에 다음 발생 :

# 
# object tile00 
# 

더 정점 정의 하였다.

그래서이 모델은 여러 얼굴로 정의 된 여러 하위 개체로 구성 될 수 있다고 추측했습니다. 각면은 3 x 정점/보통/texcoord 색인 값으로 정의됩니다.

그래서 CustomVertex의 벡터에 도착하기 위해, 나는 다음을 수행 할 필요가 있다고 생각 해요 :

만들고 채우는 :

vector <vertex> 
vector <normal> 
vector <texcoord> 

vector <indices> 

내가 각각에 대한 CustomVertex을 작성해야 고유 한 v/vn/vt는 얼굴 정의에서 세 번 나타납니다.

std::vector<CustomVertex> and 
std::map< nHashId, CustomVertex_index > 

그래서 내 생각은 내가 직면 각 V/VN/VT를 들어, 내가 예를 들어,이 문자열의 해시를 만들 것을 :

그래서 나는지도를 만드는 방법에 대해 생각 nHashId = hash ("80/50/1") * 및지도에서 해시를 검색합니다. 존재하지 않으면 CustomVertex를 만들어 벡터에 추가 한 다음 새로 만든 해시와 CustomVertex_index를 맵에 추가합니다.

* : v/vn/vt 문자열의 해시를 생성하면 해당 문자열에 해당하는 고유 한 숫자 값을 생성합니다.이 문자열은지도에서 검색/비교하는 것이 더 빠릅니다. 동등한 텍스트.

해시와 일치하는 항목이 발견되면 customvertex가 이미 존재하며 새 CustomVertex를 만드는 대신 CustomVertex_index 항목을 색인 벡터에 추가하고 계속 이동하는 것으로 간주합니다.

계산이 비싸기 때문에, 매번 obj 파일을 구문 분석하는 대신 나중에 CustomVertex 배열 (및 해당 색인 배열)을 디스크에 덤핑하여 나중에 검색 할 것입니다.

질문을하기 전에 시간 제약으로 인해 Vbo 클래스 (평범하지 않은 작업)를 다시 디자인하고 싶지 않을 수 있음을 지적 할 수 있습니다. CustomVertex 형식이 붙어 있습니다. 별도의 배열에있는 속성을 쉐이더에 제공하기 위해 CustomVertex와 같이 데이터를 인터리빙하여 읽으면 성능을 향상시킬 수 있습니다.

내 질문에 : 1. 내 방법이 좋지 않거나 미친 것처럼 보입니까? 미친 짓이라면 내가 잘못하고있는 곳을 지적 해주세요.

  1. 잠재적 인 문제점을 발견 할 수 있습니까?

  2. 누구나 이전에 해본 적이 있고 내가 시도한 것을 달성하는 더 간단한 방법을 추천 할 수 있습니까?

+2

해시 할 수 있다면 왜 'unordered_map'을 사용하지 않는 것이 좋을까요? 그렇지 않으면 당신의 방법은 잘 보이고 지나치게 복잡하지 않습니다. – pmr

+0

v/vn/vt 문자열의 해시를 작성하여 해당 문자열에 해당하는 고유 한 숫자 값을 생성합니다.이 값은 해당 텍스트보다 맵에서 검색/비교가 더 빠를 것으로 기대됩니다. – fishfood

+0

@lapin : "시기 상조 최적화"라고합니다. 단지 색인을 비교하십시오 (텍스트가 아닌 * 숫자 *와 같음). 프로파일 링이 느린 것으로 판명되면 해결하십시오. –

답변

0

당신은 잠재적 인 문제를 발견 할 수 있습니까?

해시 충돌 이외에도 의미가 있습니까? 알고리즘을 처리하는 부분이 보이지 않기 때문입니다.

전 누구도이 작업을 수행했으며 내가 시도한 것을 달성하는 더 간단한 방법을 권장 할 수 있습니까?

훨씬 간단한 방법이 있습니다. 색인을 비교하고 해시를 사용하지 마십시오.

0

"v/vn/vt"라는 문자열 해시를 만드는 대신 v를 정수로만 해시하는 것입니다. 그 후에 동일한 v 색인을 공유하는 모든 "v/vn/vt"조합을 포함하는 양동이를 얻습니다.

해시 충돌이 발생하면 (충돌 발생시) 충돌 한 조합을 버킷의 충돌 비교 결과와 비교하여 실제로 복제되었는지 확인합니다. 그렇지 않은 경우 충돌 한 조합을 양동이에 추가해야합니다.