goat3dgfx

annotate src/curveload.cc @ 0:1873dfd13f2d

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 14 Nov 2013 05:27:09 +0200
parents
children 7bd5ebec3b6f
rev   line source
nuclear@0 1 #include <string>
nuclear@0 2 #include <assert.h>
nuclear@0 3 #include <stdint.h>
nuclear@0 4 #include "curveload.h"
nuclear@0 5 #include "3dschunks.h"
nuclear@0 6 #include "logger.h"
nuclear@0 7
nuclear@0 8 static uint32_t read_counter;
nuclear@0 9
nuclear@0 10 struct ChunkHeader {
nuclear@0 11 ChunkID id;
nuclear@0 12 uint32_t size;
nuclear@0 13 };
nuclear@0 14
nuclear@0 15 #define HEADER_SIZE 6
nuclear@0 16
nuclear@0 17 // local function prototypes
nuclear@0 18 static uint8_t read_byte(FILE *file);
nuclear@0 19 static uint16_t read_int16(FILE *file);
nuclear@0 20 static uint32_t read_int32(FILE *file);
nuclear@0 21 static float read_float(FILE *file);
nuclear@0 22 static Vector3 read_vector(FILE *file, bool flip_yz = false);
nuclear@0 23 static std::string read_string(FILE *file);
nuclear@0 24 static ChunkHeader read_chunk_header(FILE *file);
nuclear@0 25 static void skip_chunk(FILE *file, const ChunkHeader &chunk);
nuclear@0 26 static Curve *read_curve(FILE *file, const ChunkHeader &ch);
nuclear@0 27
nuclear@0 28 static bool eof;
nuclear@0 29
nuclear@0 30 bool load_curves(Scene *scn, const char *fname)
nuclear@0 31 {
nuclear@0 32 FILE *file = fopen(fname, "rb");
nuclear@0 33 if(!file) {
nuclear@0 34 error_log("failed to open curves scene file: %s\n", fname);
nuclear@0 35 return false;
nuclear@0 36 }
nuclear@0 37 eof = false;
nuclear@0 38
nuclear@0 39 ChunkHeader chunk;
nuclear@0 40
nuclear@0 41 chunk = read_chunk_header(file);
nuclear@0 42 if(chunk.id != Chunk_3DSMain) {
nuclear@0 43 fclose(file);
nuclear@0 44 return false;
nuclear@0 45 }
nuclear@0 46
nuclear@0 47 while(!eof) {
nuclear@0 48 chunk = read_chunk_header(file);
nuclear@0 49
nuclear@0 50 Curve *curve;
nuclear@0 51
nuclear@0 52 switch(chunk.id) {
nuclear@0 53 case Chunk_Main_3DEditor:
nuclear@0 54 break; // dont skip
nuclear@0 55
nuclear@0 56 case Chunk_Edit_Object:
nuclear@0 57 if((curve = read_curve(file, chunk))) {
nuclear@0 58 scn->curves.push_back(curve);
nuclear@0 59 }
nuclear@0 60 break;
nuclear@0 61
nuclear@0 62 default:
nuclear@0 63 skip_chunk(file, chunk);
nuclear@0 64 }
nuclear@0 65 }
nuclear@0 66
nuclear@0 67 fclose(file);
nuclear@0 68 return true;
nuclear@0 69 }
nuclear@0 70
nuclear@0 71 static uint8_t read_byte(FILE *fp) {
nuclear@0 72 uint8_t v;
nuclear@0 73 if(fread(&v, 1, 1, fp) <= 0) {
nuclear@0 74 eof = true;
nuclear@0 75 return 0;
nuclear@0 76 }
nuclear@0 77 read_counter++;
nuclear@0 78 return v;
nuclear@0 79 }
nuclear@0 80
nuclear@0 81 static uint16_t read_int16(FILE *fp) {
nuclear@0 82 uint16_t v;
nuclear@0 83 if(fread(&v, 2, 1, fp) <= 0) {
nuclear@0 84 eof = true;
nuclear@0 85 return 0;
nuclear@0 86 }
nuclear@0 87 read_counter += 2;
nuclear@0 88 return v;
nuclear@0 89 }
nuclear@0 90
nuclear@0 91 static uint32_t read_int32(FILE *fp) {
nuclear@0 92 uint32_t v;
nuclear@0 93 if(fread(&v, 4, 1, fp) <= 0) {
nuclear@0 94 eof = true;
nuclear@0 95 return 0;
nuclear@0 96 }
nuclear@0 97 read_counter += 4;
nuclear@0 98 return v;
nuclear@0 99 }
nuclear@0 100
nuclear@0 101 static float read_float(FILE *fp)
nuclear@0 102 {
nuclear@0 103 int32_t tmp = read_int32(fp);
nuclear@0 104 return *((float*)&tmp);
nuclear@0 105 }
nuclear@0 106
nuclear@0 107 static Vector3 read_vector(FILE *file, bool flip_yz)
nuclear@0 108 {
nuclear@0 109 Vector3 vector;
nuclear@0 110 vector.x = read_float(file);
nuclear@0 111 if(!flip_yz) vector.y = read_float(file);
nuclear@0 112 vector.z = read_float(file);
nuclear@0 113 if(flip_yz) vector.y = read_float(file);
nuclear@0 114 return vector;
nuclear@0 115 }
nuclear@0 116
nuclear@0 117 static std::string read_string(FILE *file)
nuclear@0 118 {
nuclear@0 119 std::string str;
nuclear@0 120 char c;
nuclear@0 121 while((c = (char)read_byte(file))) {
nuclear@0 122 str.push_back(c);
nuclear@0 123 }
nuclear@0 124 read_counter++;
nuclear@0 125
nuclear@0 126 return str;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 static ChunkHeader read_chunk_header(FILE *file)
nuclear@0 130 {
nuclear@0 131 ChunkHeader chunk;
nuclear@0 132 chunk.id = (ChunkID)read_int16(file);
nuclear@0 133 chunk.size = read_int32(file);
nuclear@0 134 return chunk;
nuclear@0 135 }
nuclear@0 136
nuclear@0 137 static void skip_chunk(FILE *file, const ChunkHeader &chunk)
nuclear@0 138 {
nuclear@0 139 if(eof) return;
nuclear@0 140 fseek(file, chunk.size - HEADER_SIZE, SEEK_CUR);
nuclear@0 141 read_counter += chunk.size - HEADER_SIZE;
nuclear@0 142 }
nuclear@0 143
nuclear@0 144 static Curve *read_curve(FILE *file, const ChunkHeader &ch)
nuclear@0 145 {
nuclear@0 146 read_counter = HEADER_SIZE; // reset the global read counter
nuclear@0 147
nuclear@0 148 std::string name = read_string(file);
nuclear@0 149
nuclear@0 150 ChunkHeader chunk;
nuclear@0 151 chunk = read_chunk_header(file);
nuclear@0 152 if(chunk.id == Chunk_Obj_TriMesh) {
nuclear@0 153 // object is a trimesh... load it
nuclear@0 154 Vector3 *varray = 0;
nuclear@0 155 uint32_t vertex_count = 0;
nuclear@0 156
nuclear@0 157 uint32_t obj_chunk_size = ch.size;
nuclear@0 158
nuclear@0 159 while(read_counter < obj_chunk_size) { // make sure we only read subchunks of this object chunk
nuclear@0 160 chunk = read_chunk_header(file);
nuclear@0 161
nuclear@0 162 switch(chunk.id) {
nuclear@0 163 case Chunk_TriMesh_VertexList:
nuclear@0 164 vertex_count = (uint32_t)read_int16(file);
nuclear@0 165 varray = new Vector3[vertex_count];
nuclear@0 166
nuclear@0 167 for(uint32_t i=0; i<vertex_count; i++) {
nuclear@0 168 varray[i] = read_vector(file);
nuclear@0 169 }
nuclear@0 170
nuclear@0 171 break;
nuclear@0 172
nuclear@0 173 case Chunk_TriMesh_FaceDesc:
nuclear@0 174 // it is a real object not a curve since it has triangles
nuclear@0 175 delete [] varray;
nuclear@0 176 varray = 0;
nuclear@0 177 break;
nuclear@0 178
nuclear@0 179 default:
nuclear@0 180 skip_chunk(file, chunk);
nuclear@0 181 }
nuclear@0 182 }
nuclear@0 183
nuclear@0 184 if(varray) {
nuclear@0 185 Curve *curve = new Curve;
nuclear@0 186 curve->set_name(name.c_str());
nuclear@0 187 for(uint32_t i=0; i<vertex_count; i++) {
nuclear@0 188 curve->add_point(varray[i]);
nuclear@0 189 }
nuclear@0 190 return curve;
nuclear@0 191 }
nuclear@0 192 }
nuclear@0 193
nuclear@0 194 return 0;
nuclear@0 195 }