-
Notifications
You must be signed in to change notification settings - Fork 0
/
load_3ds.cpp
185 lines (164 loc) · 5.96 KB
/
load_3ds.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
* ---------------- www.spacesimulator.net --------------
* ---- Space simulators and 3d engine tutorials ----
*
* Author: Damiano Vitulli
*
* This program is released under the BSD licence
* By using this program you agree to licence terms on spacesimulator.net copyright page
*
*
* 3ds models loader
*
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <io.h>
#include "object.h"
#include "load_3ds.h"
/**********************************************************
*
* FUNCTION Load3DS(obj_type_ptr p_object, char *p_filename)
*
* This function loads a mesh from a 3ds file.
* Please note that we are loading only the vertices, polygons and mapping lists.
* If you need to load meshes with advanced features as for example:
* multi objects, materials, lights and so on, you must insert other chunk parsers.
*
* Input parameters: p_object = Pointer to the Object
* p_filename = Filename of the object to load
*
* Return value: (char) 1 if the object was loaded correctly, 0 otherwise
*
*********************************************************/
char Load3DS(obj_type_ptr p_object, char *p_filename)
{
int i; //Index variable
FILE *l_file; //File pointer
unsigned short l_chunk_id; //Chunk identifier
unsigned int l_chunk_length; //Chunk length
unsigned char l_char; //Char variable
unsigned short l_qty; //Number of elements in each chunk
unsigned short l_face_flags; //Flag that stores some face information
if (p_filename=='\0') return(0);
if ((l_file=fopen (p_filename, "rb"))== NULL)
{
MessageBox(NULL,"3DS file not found","Spacesim",MB_OK | MB_ICONERROR);
return (0);
}
while (ftell (l_file) < filelength (fileno (l_file))) //Loop to scan the whole file
{
//getche(); //Insert this command for debug (to wait for keypress for each chuck reading)
fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header
fread (&l_chunk_length, 4, 1, l_file); //Read the length of the chunk
switch (l_chunk_id)
{
//----------------- MAIN3DS -----------------
// Description: Main chunk, contains all the other chunks
// Chunk ID: 4d4d
// Chunk Length: 0 + sub chunks
//-------------------------------------------
case 0x4d4d:
break;
//----------------- EDIT3DS -----------------
// Description: 3D Editor chunk, objects layout info
// Chunk ID: 3d3d (hex)
// Chunk Length: 0 + sub chunks
//-------------------------------------------
case 0x3d3d:
break;
//--------------- EDIT_OBJECT ---------------
// Description: Object block, info for each object
// Chunk ID: 4000 (hex)
// Chunk Length: len(object name) + sub chunks
//-------------------------------------------
case 0x4000:
i=0;
do
{
fread (&l_char, 1, 1, l_file);
p_object->name[i]=l_char;
i++;
}while(l_char != '\0' && i<20);
break;
//--------------- OBJ_TRIMESH ---------------
// Description: Triangular mesh, contains chunks for 3d mesh info
// Chunk ID: 4100 (hex)
// Chunk Length: 0 + sub chunks
//-------------------------------------------
case 0x4100:
break;
//--------------- TRI_VERTEXL ---------------
// Description: Vertices list
// Chunk ID: 4110 (hex)
// Chunk Length: 1 x unsigned short (number of vertices)
// + 3 x float (vertex coordinates) x (number of vertices)
// + sub chunks
//-------------------------------------------
case 0x4110:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->vertices_qty = l_qty;
if (l_qty>MAX_VERTICES)
{
MessageBox(NULL,"Number of vertices too high","SpaceExplorer",MB_OK | MB_ICONERROR);
return (0);
}
for (i=0; i<l_qty; i++)
{
fread (&p_object->vertex[i].x, sizeof(float), 1, l_file);
fread (&p_object->vertex[i].y, sizeof(float), 1, l_file);
fread (&p_object->vertex[i].z, sizeof(float), 1, l_file);
}
break;
//--------------- TRI_FACEL1 ----------------
// Description: Polygons (faces) list
// Chunk ID: 4120 (hex)
// Chunk Length: 1 x unsigned short (number of polygons)
// + 3 x unsigned short (polygon points) x (number of polygons)
// + sub chunks
//-------------------------------------------
case 0x4120:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->polygons_qty = l_qty;
if (l_qty>MAX_POLYGONS)
{
MessageBox(NULL,"Number of polygons too high","SpaceExplorer",MB_OK | MB_ICONERROR);
return (0);
}
for (i=0; i<l_qty; i++)
{
fread (&p_object->polygon[i].a, sizeof (unsigned short), 1, l_file);
fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file);
fread (&p_object->polygon[i].c, sizeof (unsigned short), 1, l_file);
fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
}
break;
//------------- TRI_MAPPINGCOORS ------------
// Description: Vertices list
// Chunk ID: 4140 (hex)
// Chunk Length: 1 x unsigned short (number of mapping points)
// + 2 x float (mapping coordinates) x (number of mapping points)
// + sub chunks
//-------------------------------------------
case 0x4140:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
for (i=0; i<l_qty; i++)
{
fread (&p_object->mapcoord[i].u, sizeof (float), 1, l_file);
fread (&p_object->mapcoord[i].v, sizeof (float), 1, l_file);
}
break;
//----------- Skip unknow chunks ------------
//We need to skip all the chunks that currently we don't use
//We use the chunk length information to set the file pointer
//to the same level next chunk
//-------------------------------------------
default:
fseek(l_file, l_chunk_length-6, SEEK_CUR);
}
}
fclose (l_file); // Closes the file stream
return (1); // Returns ok
}