Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
blob: b5763841a960a24123776525e7649b3291c4d82c (plain)
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
   model/map.h
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2
*/

#ifndef __INCLUDED_MODEL_MAPFILE_H__
#define __INCLUDED_MODEL_MAPFILE_H__

#include <string>
#include <vector>

#include "model/material.h"
#include "model/model.h"
#include "model/face.h"
#include "model/primitives.h"
#include "model/trianglelist.h"
#include "filesystem/filestream.h"

namespace model
{

/// class to parse the .map file structure and load geometry data into a model
class MapFile
{

public:
	/**
	 * @brief load a .map file into a Model
	 * @param name	name of the model to be loaded, without .map extension or maps/ prefix
	 * If the file can not be read, load() returns the NULL-pointer
	 */
	static Model *load(std::string const &name);

private:
	MapFile();
	~MapFile();

	/// tpye definition for a per-material list of Primitives
	typedef std::map<Material *, Primitives *> Materials;

	/// open the file for reading
	/** the filename will get the "maps/" prefix and ".map" suffix
	 */
	bool open(std::string const & name);

	/// parse one line, returns false on end-of-file
	bool getline();

	bool read_patchdef();

	/// current classname
	inline std::string classname() const {
		return classname_current;
	}

	/// current key
	inline std::string key() const {
		return key_current;
	}

	/// current value
	inline std::string value() const {
		return value_current;
	}

	/// true if the last read line contained a new classname
	bool got_classname() const;

	/// true if we are inside the requested class
	bool in_class(const char *name) {
		return (classname_current.compare(name) == 0);
	}

	/// true if the last read line contained a class closing bracket
	inline bool got_classend() const {
		return last_read_was_classend;
	}

	/// true if the last read line contained the closing bracket for the requested class
	bool got_classend(const char*) const;

	/// true if the last read line contained a new classname
	bool got_classname(const char*) const;

	/// true if the last read statement was a key=value pair
	inline bool got_key() const {
		return last_read_was_key;
	}

	bool got_key(const char * keylabel);

	/// check if the last read key=value pair matches keylabel and store the value in valuestring
	bool got_key_string(const char * keylabel, std::string & valuestring);

	/// check if the last read key=value pair matches keylabel and store the value in color
	bool got_key_color(const char * keylabel, math::Color & color);

	/// check if the last read key=value pair matches keylabel and store the value in f
	bool got_key_float(const char * keylabel, float & f);

	/// check if the last read key=value pair matches keylabel and store the value in f
	bool got_key_int(const char * keylabel, unsigned int & u);

	/// check if the last read key=value pair matches keylabel and store the value in valuestring
	bool got_key_angle(const char * keylabel, float & f);

	bool got_key_vector3f(const char * keylabel, math::Vector3f & v);
	
	/// check if the last read key is one of the axis related keys (angle, angles, pitch, yaw, roll)
	bool got_key_axis(math::Axis &axis);


	/// return the number of lines read so far
	inline unsigned int line() const {
		return line_number;
	}

	/// return true of the map file is open for reading
	inline bool is_open() {
		return mapfile_ifs.is_open();
	}

	/// current filename
	inline std::string const & name() const {
		return mapfile_name;
	}
	
	inline const math::BoundingBox3f & box() const {
		return map_box;
	}
	
	inline bool collinear(const math::Vector3f & a, const math::Vector3f & b, const math::Vector3f & c)
	{
		if ((distance(a, b) + distance(b, c)) == distance(a, c))
			return true;
		else
			return false;
	}

	/// close the file
	void close();

	/// generate triangles for one plane in the plane list
	void make_brushface(Face *face);

	/// load parsed primitives into a FragmentGroup
	void load_fragmentgroup(Model *model, const FragmentGroup::Type class_type);

	/// clear the current list of per-material geometry
	void clear_materials();

	/// clear class bounding box
	void clear_bbox();

	/// print 'unkown class' warning message to the console
	void unknown_class() const;

	/// print 'unkown key' warning message to the console
	void unknown_key() const;

	/// print 'unkown value' warning message to the console
	void unknown_value() const;
	
	/// print 'depricated key' warning message to the console
	void warn_depricated() const;
	
	/// print a generic error message
	void unknown_error(const char *text = 0) const;
	
	/// print a generic error message
	void unknown_error(const std::string &text) const;

	/// list of planes for the current brush
	std::vector<Face *>	planes;


	std::string 		classname_current;
	std::string 		key_current;
	std::string 		value_current;

	bool 			last_read_was_key;
	bool 			last_read_was_classname;
	bool			last_read_was_classend;
	
	bool			map_load_clip;

	unsigned int		map_brushes;
	unsigned int		map_faces;
	unsigned int		map_faces_detail;

	unsigned int		parse_level;
	unsigned int 		line_number;
	filesystem::IFileStream	mapfile_ifs;
	std::string 		mapfile_name;

	math::BoundingBox3f	map_box;
	
	math::BoundingBox3f	class_box;
	math::Axis		class_axis;
	float			class_speed;
	float			class_distance;
	bool			class_engine;

	Materials		map_materials;
	TriangleList		map_collisiontriangles;

	bool			warning_q2brush;

	bool			in_patchdef;
};

}

#endif // __INCLUDED_MODEL_MAPFILE_H__