goat3dgfx

annotate src/curveload.cc @ 9:25b911c7c35c

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