LINUX.ORG.RU

Парсинг 3ds файла -> добраться бы до OBJ_TRIMESH (0x4100)

 3ds,


0

1

Добрался до блока EDIT_OBJECT (0x4000), а дальше найти например блок OBJ_TRIMESH (0x4100) никак не получается, скачал уже 3 3ds файла и со всеми такая же проблема. Подскажите пожалуйста как дальше считывать файл в блоке EDIT_OBJECT (0x4000)? И еще один вопрос. За что отвечает блок 0x3d3e?

#include <stdio.h>

int main()
{
	unsigned short id_chunk = 0;
	unsigned int len_chunk = 0;
	FILE * file = NULL;
	if( (file = fopen("model1.3DS", "rb")) == NULL )
	{
		printf("He удается открыть файл.\n");
		return 1;
	}
	
  fread(&id_chunk, 2, 1, file);
  if( id_chunk != 0x4D4D )
  {	
	printf("Это не 3ds файл.\n");
	return 2;
  }
	
  fread(&len_chunk, 4, 1, file);
  printf("Длина текущего блока: %d\n", len_chunk);
  
  fread(&id_chunk, 2, 1, file);
  printf("Chunk_id: %#x\n", id_chunk);
  
  fread(&len_chunk, 4, 1, file);
  printf("Длина текущего блока: %d\n", len_chunk);
  
  fseek ( file , len_chunk - 6 , SEEK_CUR );
  fread(&id_chunk, 2, 1, file);
  printf("Chunk_id: %#x\n", id_chunk); //EDIT3DS  (0x3D3D)
  fread(&len_chunk, 4, 1, file);
  printf("Длина текущего блока: %d\n", len_chunk);
  
  fread(&id_chunk, 2, 1, file);
  printf("Chunk_id: %#x\n", id_chunk);	//Chunk_id: 0x3d3e
  fread(&len_chunk, 4, 1, file);
  printf("Длина текущего блока: %d\n", len_chunk);
    
  while( id_chunk != 0x4000 )
  {
     fseek ( file , len_chunk - 6 , SEEK_CUR );
     fread(&id_chunk, 2, 1, file);
     printf("Chunk_id: %#x\n", id_chunk);	
     fread(&len_chunk, 4, 1, file);
     printf("Длина текущего блока: %d\n", len_chunk); 
  }
       
  fread(&id_chunk, 2, 1, file);
  printf("Chunk_id: %#x\n", id_chunk);	
  fread(&len_chunk, 4, 1, file);
  printf("Длина текущего блока: %d\n", len_chunk);
    
}


примерно так:

#include <stdint.h>
#include <stdio.h>
#pragma pack (1)
typedef struct {
  uint16_t id; //2 bytes
  uint32_t next; //4 bytes
} Chunk3DS;
#pragma pack (4)
void skipChunk(char* name, FILE* file, Chunk3DS chunk) {
  printf("skip: %s (size=%i)\n", name, chunk.next-6);
  fseek(file, chunk.next-6, SEEK_CUR);
}
void readAscizz(char* name, FILE* file) {
  printf("%s", name);
  while(1) {
    int ch=fgetc(file);
    if(ch==EOF||ch==0) break;
    putchar(ch);
  }
  printf("\n");
}
int readInt(char* name, FILE* file, Chunk3DS chunk) {
  uint32_t value;
  if(chunk.next!=10) return -1;
  fread(&value, sizeof(uint32_t), 1, file);
  printf("%s %i\n", name, value);
  return 0;
}
int readFloat(char* name, FILE* file, Chunk3DS chunk) {
  float value;
  if(chunk.next!=10) return -1;
  fread(&value, sizeof(float), 1, file);
  printf("%s %f\n", name, value);
  return 0;
}

int parse(FILE* file)
{
  Chunk3DS chunk;
  if(feof(file)) return 0;
  fread(&chunk, sizeof(Chunk3DS), 1, file);
  switch(chunk.id)
  {
    case 0x0002: if(readInt  ("version:",      file, chunk)!=0) return -1; break;
    case 0x0100: if(readFloat("master scale:", file, chunk)!=0) return -1; break;
    case 0x3D3D: printf("object\n"); break;
    case 0x3D3E: if(readInt  ("mesh version:", file, chunk)!=0) return -1; break;
    case 0x4000: readAscizz  ("object block:", file); break;
    case 0x4D4D: printf("root chunk\n"); break;
    case 0xAFFF: skipChunk   ("CHK_MAT_ENTRY", file, chunk); break;
    default: printf("id=0x%4x, next=%i\n", chunk.id, chunk.next); return -2;
  }
  parse(file);
}
int main() {
  FILE * file = NULL;
  if( (file = fopen("model1.3DS", "rb")) == NULL ) {
    printf("He удается открыть файл.\n");
    return 1;
  }
  printf("result: %i\n", parse(file));
  fclose(file);
  return 0;
}

anonymous
()

Спасибо отписавшимся, разобрался, дело было в том что блок EDIT_OBJECT (0x4000) является не стандартным и содержит в себе еще и имя объекта + type(2). Структура его такова:

EDIT_OBJECT 0x4000 – именованный объект

magic(2)

size(4) – размер чанка.

name(20 включая нуль-символ) – название объекта.

type(2) – тип ( 0x4100 или 0x4600 ).

netang
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.