added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / libs / lib3ds / camera.c
1 /*
2  * The 3D Studio File Format Library
3  * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
4  * All rights reserved.
5  *
6  * This program is  free  software;  you can redistribute it and/or modify it
7  * under the terms of the  GNU Lesser General Public License  as published by 
8  * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
9  * your option) any later version.
10  *
11  * This  program  is  distributed in  the  hope that it will  be useful,  but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
14  * License for more details.
15  *
16  * You should  have received  a copy of the GNU Lesser General Public License
17  * along with  this program;  if not, write to the  Free Software Foundation,
18  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * $Id: camera.c,v 1.12 2004/11/16 07:41:44 efalk Exp $
21  */
22 #define LIB3DS_EXPORT
23 #include <lib3ds/camera.h>
24 #include <lib3ds/chunk.h>
25 #include <lib3ds/io.h>
26 #include <stdlib.h>
27 #include <math.h>
28 #include <string.h>
29 #ifdef WITH_DMALLOC
30 #include <dmalloc.h>
31 #endif
32
33
34 /*!
35  * \defgroup camera Cameras
36  *
37  * \author J.E. Hoffmann <je-h@gmx.net>
38  */
39
40
41 /*!
42  * Return a new Lib3dsCamera object.
43  *
44  * Object is initialized with the given name and fov=45.  All other
45  * values are 0.
46  *
47  * \param name Name of this camera.  Must not be NULL.  Must be < 64 characters.
48  *
49  * \return Lib3dsCamera object or NULL on failure.
50  *
51  * \ingroup camera
52  */
53 Lib3dsCamera*
54 lib3ds_camera_new(const char *name)
55 {
56   Lib3dsCamera *camera;
57
58   ASSERT(name);
59   ASSERT(strlen(name)<64);
60   
61   camera=(Lib3dsCamera*)calloc(sizeof(Lib3dsCamera), 1);
62   if (!camera) {
63     return(0);
64   }
65   strcpy(camera->name, name);
66   camera->fov=45.0f;
67   return(camera);
68 }
69
70
71 /*!
72  * Free a Lib3dsCamera object and all of its resources.
73  *
74  * \param camera Lib3dsCamera object to be freed.
75  *
76  * \ingroup camera 
77  */
78 void
79 lib3ds_camera_free(Lib3dsCamera *camera)
80 {
81   memset(camera, 0, sizeof(Lib3dsCamera));
82   free(camera);
83 }
84
85
86 /*!
87  * Dump information about a Lib3dsCamera object to stdout.
88  *
89  * \param camera Object to be dumped.
90  *
91  * \see lib3ds_file_dump_cameras
92  *
93  * \ingroup camera
94  */
95 void
96 lib3ds_camera_dump(Lib3dsCamera *camera)
97 {
98   ASSERT(camera);
99   printf("  name:       %s\n", camera->name);
100   printf("  position:   (%f, %f, %f)\n", 
101     camera->position[0], camera->position[1], camera->position[2]);
102   printf("  target      (%f, %f, %f)\n", 
103     camera->target[0], camera->target[1], camera->target[2]);
104   printf("  roll:       %f\n", camera->roll);
105   printf("  fov:        %f\n", camera->fov);
106   printf("  see_cone:   %s\n", camera->see_cone ? "yes" : "no");
107   printf("  near_range: %f\n", camera->near_range);
108   printf("  far_range:  %f\n", camera->far_range);
109   printf("\n");
110 }
111
112
113 /*!
114  * Read a camera definition from a file.
115  *
116  * This function is called by lib3ds_file_read(), and you probably
117  * don't want to call it directly.
118  *
119  * \param camera A Lib3dsCamera to be filled in.
120  * \param io A Lib3dsIo object previously set up by the caller.
121  *
122  * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
123  *
124  * \see lib3ds_file_read
125  *
126  * \ingroup camera
127  */
128 Lib3dsBool
129 lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io)
130 {
131   Lib3dsChunk c;
132   Lib3dsWord chunk;
133
134   if (!lib3ds_chunk_read_start(&c, LIB3DS_N_CAMERA, io)) {
135     return(LIB3DS_FALSE);
136   }
137   {
138     int i;
139     for (i=0; i<3; ++i) {
140       camera->position[i]=lib3ds_io_read_float(io);
141     }
142     for (i=0; i<3; ++i) {
143       camera->target[i]=lib3ds_io_read_float(io);
144     }
145   }
146   camera->roll=lib3ds_io_read_float(io);
147   {
148     float s;
149     s=lib3ds_io_read_float(io);
150     if (fabs(s)<LIB3DS_EPSILON) {
151       camera->fov=45.0;
152     }
153     else {
154       camera->fov=2400.0f/s;
155     }
156   }
157   lib3ds_chunk_read_tell(&c, io);
158   
159   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
160     switch (chunk) {
161       case LIB3DS_CAM_SEE_CONE:
162         {
163           camera->see_cone=LIB3DS_TRUE;
164         }
165         break;
166       case LIB3DS_CAM_RANGES:
167         {
168           camera->near_range=lib3ds_io_read_float(io);
169           camera->far_range=lib3ds_io_read_float(io);
170         }
171         break;
172       default:
173         lib3ds_chunk_unknown(chunk);
174     }
175   }
176   
177   lib3ds_chunk_read_end(&c, io);
178   return(LIB3DS_TRUE);
179 }
180
181
182 /*!
183  * Write a camera definition to a file.
184  *
185  * This function is called by lib3ds_file_write(), and you probably
186  * don't want to call it directly.
187  *
188  * \param camera A Lib3dsCamera to be written.
189  * \param io A Lib3dsIo object previously set up by the caller.
190  *
191  * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
192  *
193  * \see lib3ds_file_write
194  *
195  * \ingroup camera
196  */
197 Lib3dsBool
198 lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io)
199 {
200   Lib3dsChunk c;
201
202   c.chunk=LIB3DS_N_CAMERA;
203   if (!lib3ds_chunk_write_start(&c,io)) {
204     return(LIB3DS_FALSE);
205   }
206
207   lib3ds_io_write_vector(io, camera->position);
208   lib3ds_io_write_vector(io, camera->target);
209   lib3ds_io_write_float(io, camera->roll);
210   if (fabs(camera->fov)<LIB3DS_EPSILON) {
211     lib3ds_io_write_float(io, 2400.0f/45.0f);
212   }
213   else {
214     lib3ds_io_write_float(io, 2400.0f/camera->fov);
215   }
216
217   if (camera->see_cone) {
218     Lib3dsChunk c;
219     c.chunk=LIB3DS_CAM_SEE_CONE;
220     c.size=6;
221     lib3ds_chunk_write(&c, io);
222   }
223   {
224     Lib3dsChunk c;
225     c.chunk=LIB3DS_CAM_RANGES;
226     c.size=14;
227     lib3ds_chunk_write(&c, io);
228     lib3ds_io_write_float(io, camera->near_range);
229     lib3ds_io_write_float(io, camera->far_range);
230   }
231
232   if (!lib3ds_chunk_write_end(&c,io)) {
233     return(LIB3DS_FALSE);
234   }
235   return(LIB3DS_TRUE);
236 }
237
238
239 /*!
240
241 \typedef Lib3dsCamera
242   \ingroup camera
243   \sa _Lib3dsCamera
244
245 */