// File: ticky[P]ps2iconsys/src/obj_loader.cpp
// Function: OBJ_FileLoader::ReadFile(std::basic_ifstream<char, std::char_traits<char>>&)
void OBJ_FileLoader::ReadFile(std::ifstream& f) 
{
	///@todo: only triangular polys supported; all vertices are assumed to have vertex, texture and normal data present;
	std::string buffer;
	if(m_MeshList.size() > 0) { 
		throw( Ghulbus::gbException( Ghulbus::gbException::GB_INVALIDCONTEXT,
			                         "The mesh list is not empty" ) );
	}
	char group_name[256];								///< buffer holding the current group name
	bool new_group_was_opened = false;					///< flag for mesh object maintenance
	OBJ_Mesh* mesh = new OBJ_Mesh("");					///< buffer mesh object
	double tmp[3];
	OBJ_Mesh::Face tmp_face;
	tmp_face.smoothing_group = -1;
	int vert_counter=0, normal_counter=0, texture_counter=0;
	int vert_base=0, normal_base=0, texture_base=0;
	
	while( std::getline(f, buffer) ) {
		//for each line of the file do:
		//first character determines what kind of data to expect:
		switch(buffer[0]) {
			case '#':
				//commentary
				// do nothing
				break;
			case 'v':
				//vertex data
				if(new_group_was_opened) {
					//if new group was opened since last vertex was read
					//the following data belongs to a new mesh
					OBJ_Mesh* newmesh = new OBJ_Mesh("");
					mesh->SetName(group_name);
					m_MeshList.push_back(mesh);
					mesh = newmesh;
					vert_base = vert_counter;			//save current indices
					normal_base = normal_counter;
					texture_base = texture_counter;
					new_group_was_opened = false;
				}
				//read and store vertex data:
				switch(buffer[1]) {
					case ' ':
						//geometry vertex
						sscanf(buffer.c_str(), "v %lf %lf %lf", &(tmp[0]), &(tmp[1]), &(tmp[2]));
						mesh->AddGeometry(tmp, 3);
						vert_counter++;
						break;
					case 't':
						//texture vertex
						sscanf(buffer.c_str(), "vt %lf %lf %lf", &(tmp[0]), &(tmp[1]), &(tmp[2]));
						mesh->AddTextureData(tmp, 3);
						texture_counter++;
						break;
					case 'n':
						//normal vertex
						sscanf(buffer.c_str(), "vn %lf %lf %lf", &(tmp[0]), &(tmp[1]), &(tmp[2]));
						mesh->AddNormals(tmp, 3);
						normal_counter++;
						break;
					case 'p':
						//parameter space vertex
						/// @todo
						break;
					default:
						break;
				}
				break;
			case 'f':
				//face
				//read and store face data:
				sscanf(buffer.c_str(), "f %d/%d/%d %d/%d/%d %d/%d/%d",
					    &(tmp_face.vert1), &(tmp_face.texture1), &(tmp_face.normal1),
						&(tmp_face.vert2), &(tmp_face.texture2), &(tmp_face.normal2),
						&(tmp_face.vert3), &(tmp_face.texture3), &(tmp_face.normal3) );
				//since obj's index counters are not reset between groups, we need to adjust indices manually:
				tmp_face.vert1 -= vert_base; tmp_face.vert2 -= vert_base; tmp_face.vert3 -= vert_base;
				tmp_face.normal1 -= normal_base; tmp_face.normal2 -= normal_base; tmp_face.normal3 -= normal_base; 
				tmp_face.texture1 -= texture_base; tmp_face.texture2 -= texture_base; tmp_face.texture3 -= texture_base;
				//beware! object file indices are 1-based; readjust:
				tmp_face.vert1--;    tmp_face.vert2--;    tmp_face.vert3--;
				tmp_face.texture1--; tmp_face.texture2--; tmp_face.texture3--;
				tmp_face.normal1--;  tmp_face.normal2--;  tmp_face.normal3--;
				mesh->AddFaceData(&tmp_face, 1);
				break;
			case 'g':
				//group
				if(sscanf(buffer.c_str(), "g %s", group_name) > 0) {
					//a new (named) group was opened;
					//in 3dsmax obj files this should only happen before a new faces block
					new_group_was_opened = true;
				}
				break;
			case 's':
				switch(buffer[1]) {
					case ' ':
						//smoothing group
						sscanf(buffer.c_str(), "s %d", &(tmp_face.smoothing_group));
						break;
					default:
						break;
				}
			default:
				break;
		}
	}
	if(mesh->GetNFaces() > 0) {
		mesh->SetName(group_name);
		m_MeshList.push_back(mesh);
	} else {
		delete mesh;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1d0(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x22a0
movq -0x1d0(%rbp), %rdi
callq 0x4bc0
cmpq $0x0, %rax
jbe 0x28bf
movl $0x18, %edi
callq 0x20f0
movq %rax, %rdi
movq %rdi, -0x1d8(%rbp)
leaq 0xe85f(%rip), %rdx      # 0x110e4
movl $0x4, %esi
callq 0xf0b0
movq -0x1d8(%rbp), %rdi
leaq 0x154f3(%rip), %rsi     # 0x17d90
leaq 0xc8ac(%rip), %rdx      # 0xf150
callq 0x2340
jmp 0x2f66
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2f54
movb $0x0, -0x151(%rbp)
movl $0x68, %edi
callq 0x21d0
movq %rax, -0x1e0(%rbp)
jmp 0x28d9
movq -0x1e0(%rbp), %rdi
leaq 0xf54d(%rip), %rsi      # 0x11e34
callq 0x46a0
jmp 0x28ee
movq -0x1e0(%rbp), %rax
movq %rax, -0x160(%rbp)
movl $0xffffffff, -0x184(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x1ac(%rbp)
movl $0x0, -0x1b0(%rbp)
movl $0x0, -0x1b4(%rbp)
movl $0x0, -0x1b8(%rbp)
movl $0x0, -0x1bc(%rbp)
movl $0x0, -0x1c0(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x2050
movq %rax, -0x1e8(%rbp)
jmp 0x2958
movq -0x1e8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x2250
movb %al, -0x1e9(%rbp)
jmp 0x2976
movb -0x1e9(%rbp), %al
testb $0x1, %al
jne 0x2985
jmp 0x2ec3
xorl %eax, %eax
movl %eax, %esi
leaq -0x38(%rbp), %rdi
callq 0x23d0
movq %rax, -0x1f8(%rbp)
jmp 0x299b
movq -0x1f8(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x1fc(%rbp)
subl $0x23, %eax
je 0x2a17
jmp 0x29b2
movl -0x1fc(%rbp), %eax
subl $0x66, %eax
je 0x2c75
jmp 0x29c3
movl -0x1fc(%rbp), %eax
subl $0x67, %eax
je 0x2e3c
jmp 0x29d4
movl -0x1fc(%rbp), %eax
subl $0x73, %eax
je 0x2e6b
jmp 0x29e5
movl -0x1fc(%rbp), %eax
subl $0x76, %eax
je 0x2a1c
jmp 0x2ebc
movq -0x1e0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0x68, %esi
callq 0x21e0
jmp 0x2f54
jmp 0x2ebe
testb $0x1, -0x151(%rbp)
je 0x2ae6
movl $0x68, %edi
callq 0x21d0
movq %rax, -0x208(%rbp)
jmp 0x2a3c
movq -0x208(%rbp), %rdi
leaq 0xf3ea(%rip), %rsi      # 0x11e34
callq 0x46a0
jmp 0x2a51
movq -0x208(%rbp), %rax
movq %rax, -0x1c8(%rbp)
movq -0x160(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x45f0
jmp 0x2a74
movq -0x1d0(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x4c00
jmp 0x2a89
movq -0x1c8(%rbp), %rax
movq %rax, -0x160(%rbp)
movl -0x1ac(%rbp), %eax
movl %eax, -0x1b8(%rbp)
movl -0x1b0(%rbp), %eax
movl %eax, -0x1bc(%rbp)
movl -0x1b4(%rbp), %eax
movl %eax, -0x1c0(%rbp)
movb $0x0, -0x151(%rbp)
jmp 0x2ae6
movq -0x208(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0x68, %esi
callq 0x21e0
jmp 0x2f54
leaq -0x38(%rbp), %rdi
movl $0x1, %esi
callq 0x23d0
movq %rax, -0x210(%rbp)
jmp 0x2afd
movq -0x210(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x214(%rbp)
subl $0x20, %eax
je 0x2b46
jmp 0x2b14
movl -0x214(%rbp), %eax
subl $0x6e, %eax
je 0x2c0b
jmp 0x2b25
movl -0x214(%rbp), %eax
subl $0x70, %eax
je 0x2c6c
jmp 0x2b36
movl -0x214(%rbp), %eax
subl $0x74, %eax
je 0x2baa
jmp 0x2c6e
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x178(%rbp), %rcx
leaq -0x170(%rbp), %r8
leaq 0xe598(%rip), %rsi      # 0x110ff
xorl %eax, %eax
leaq -0x180(%rbp), %rdx
movq %rdx, -0x220(%rbp)
callq 0x21b0
movq -0x220(%rbp), %rsi
movq -0x160(%rbp), %rdi
movl $0x3, %edx
callq 0x4cd0
jmp 0x2b96
movl -0x1ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ac(%rbp)
jmp 0x2c70
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x178(%rbp), %rcx
leaq -0x170(%rbp), %r8
leaq 0xe542(%rip), %rsi      # 0x1110d
xorl %eax, %eax
leaq -0x180(%rbp), %rdx
movq %rdx, -0x228(%rbp)
callq 0x21b0
movq -0x228(%rbp), %rsi
movq -0x160(%rbp), %rdi
movl $0x3, %edx
callq 0x4d00
jmp 0x2bfa
movl -0x1b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b4(%rbp)
jmp 0x2c70
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x178(%rbp), %rcx
leaq -0x170(%rbp), %r8
leaq 0xe4f0(%rip), %rsi      # 0x1111c
xorl %eax, %eax
leaq -0x180(%rbp), %rdx
movq %rdx, -0x230(%rbp)
callq 0x21b0
movq -0x230(%rbp), %rsi
movq -0x160(%rbp), %rdi
movl $0x3, %edx
callq 0x4d30
jmp 0x2c5b
movl -0x1b0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b0(%rbp)
jmp 0x2c70
jmp 0x2c70
jmp 0x2c70
jmp 0x2ebe
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x190(%rbp), %rcx
leaq -0x19c(%rbp), %r8
leaq -0x1a4(%rbp), %r9
leaq -0x18c(%rbp), %rdx
leaq -0x198(%rbp), %rsi
leaq -0x1a0(%rbp), %r10
leaq -0x188(%rbp), %r11
leaq -0x194(%rbp), %rbx
movq %rsp, %rax
movq %rbx, 0x20(%rax)
movq %r11, 0x18(%rax)
movq %r10, 0x10(%rax)
movq %rsi, 0x8(%rax)
movq %rdx, (%rax)
leaq 0xe455(%rip), %rsi      # 0x1112b
xorl %eax, %eax
leaq -0x1a8(%rbp), %rdx
movq %rdx, -0x238(%rbp)
callq 0x21b0
movq -0x238(%rbp), %rsi
movl -0x1b8(%rbp), %ecx
movl -0x1a8(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1a8(%rbp)
movl -0x1b8(%rbp), %ecx
movl -0x1a4(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1a4(%rbp)
movl -0x1b8(%rbp), %ecx
movl -0x1a0(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1a0(%rbp)
movl -0x1bc(%rbp), %ecx
movl -0x19c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x19c(%rbp)
movl -0x1bc(%rbp), %ecx
movl -0x198(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x198(%rbp)
movl -0x1bc(%rbp), %ecx
movl -0x194(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x194(%rbp)
movl -0x1c0(%rbp), %ecx
movl -0x190(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x190(%rbp)
movl -0x1c0(%rbp), %ecx
movl -0x18c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x18c(%rbp)
movl -0x1c0(%rbp), %ecx
movl -0x188(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x188(%rbp)
movl -0x1a8(%rbp), %eax
decl %eax
movl %eax, -0x1a8(%rbp)
movl -0x1a4(%rbp), %eax
decl %eax
movl %eax, -0x1a4(%rbp)
movl -0x1a0(%rbp), %eax
decl %eax
movl %eax, -0x1a0(%rbp)
movl -0x190(%rbp), %eax
decl %eax
movl %eax, -0x190(%rbp)
movl -0x18c(%rbp), %eax
decl %eax
movl %eax, -0x18c(%rbp)
movl -0x188(%rbp), %eax
decl %eax
movl %eax, -0x188(%rbp)
movl -0x19c(%rbp), %eax
decl %eax
movl %eax, -0x19c(%rbp)
movl -0x198(%rbp), %eax
decl %eax
movl %eax, -0x198(%rbp)
movl -0x194(%rbp), %eax
decl %eax
movl %eax, -0x194(%rbp)
movq -0x160(%rbp), %rdi
movl $0x1, %edx
callq 0x4670
jmp 0x2e37
jmp 0x2ebe
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x150(%rbp), %rdx
leaq 0xe2f2(%rip), %rsi      # 0x11148
movb $0x0, %al
callq 0x21b0
cmpl $0x0, %eax
jle 0x2e69
movb $0x1, -0x151(%rbp)
jmp 0x2ebe
leaq -0x38(%rbp), %rdi
movl $0x1, %esi
callq 0x23d0
movq %rax, -0x240(%rbp)
jmp 0x2e82
movq -0x240(%rbp), %rax
movb (%rax), %al
subb $0x20, %al
jne 0x2eb8
jmp 0x2e91
leaq -0x38(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq -0x1a8(%rbp), %rdx
addq $0x24, %rdx
leaq 0xe29e(%rip), %rsi      # 0x1114d
movb $0x0, %al
callq 0x21b0
jmp 0x2eba
jmp 0x2eba
jmp 0x2ebc
jmp 0x2ebe
jmp 0x2942
movq -0x160(%rbp), %rdi
callq 0x45d0
movl %eax, -0x244(%rbp)
jmp 0x2ed7
movl -0x244(%rbp), %eax
cmpl $0x0, %eax
jle 0x2f0e
movq -0x160(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x45f0
jmp 0x2ef7
movq -0x1d0(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x4c00
jmp 0x2f0c
jmp 0x2f41
movq -0x160(%rbp), %rax
movq %rax, -0x250(%rbp)
cmpq $0x0, %rax
je 0x2f3f
movq -0x250(%rbp), %rdi
callq 0x4750
movq -0x250(%rbp), %rdi
movl $0x68, %esi
callq 0x21e0
jmp 0x2f41
leaq -0x38(%rbp), %rdi
callq 0x2120
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x2120
movq -0x40(%rbp), %rdi
callq 0x2370
nopw %cs:(%rax,%rax)