1 /*
2  * CRRCsim - the Charles River Radio Control Club Flight Simulator Project
3  *
4  *   Copyright (C) 2000, 2001 Jan Kansky (original author)
5  *   Copyright (C) 2004-2010 Jan Reucker
6  *   Copyright (C) 2005, 2008 Jens Wilhelm Wulf
7  *   Copyright (C) 2009 Joel Lienard
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2
11  * as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24 
25 #ifndef CRRC_SCENERY_H
26 #define CRRC_SCENERY_H
27 
28 #include <crrc_config.h>
29 
30 #include <vector>
31 #include <plib/sg.h>
32 #include <plib/ssg.h>
33 #include "../mod_math/vector3.h"
34 #include "../mod_misc/SimpleXMLTransfer.h"
35 #include "../mod_video/crrc_sky.h"
36 #include "../global_video.h"
37 
38 #define DEEPEST_HELL  -9999.0
39 
40 #define HEIGHTMAP_SIZE_X  (64)
41 #define HEIGHTMAP_SIZE_Z  (64)
42 
43 
44 typedef struct
45 {
46   float north;
47   float east;
48   float height;
49   std::string name;
50 } T_Position;
51 
52 typedef std::vector<T_Position> T_PosnArray;
53 
54 extern int calculate_wind(double  X_cg,      double  Y_cg,     double  Z_cg,
55                           double& Vel_north, double& Vel_east, double& Vel_down);
56 
57 
58 /** \brief Abstract base class for scenery classes
59  *
60  *  This base class defines the public interface common to
61  *  all scenery-drawing classes. It also reads common
62  *  information from the scenery file (sky initialization,
63  *  player and start positions, ...)
64  */
65 class Scenery
66 {
67   public:
68     /**
69      *  Initialization from XML description
70      */
71     Scenery(SimpleXMLTransfer *xml, int sky_variant = 0);
72 
73     /**
74      *  Destructor
75      */
76     virtual ~Scenery();
77 
78      /**
79      * Get pointeur on XML description section named "name"
80      *
81      */
82     SimpleXMLTransfer *getXMLsection(const char * name);
83 
84     /**
85      *  Draw the scenery
86      *
87      *  \param current_time current time in ms (for animation effects)
88      */
89     virtual void draw(double current_time) = 0;
90 
91     /**
92      *  Draw the shadows casted by scenery's objects
93      *
94      *  \param current_time current time in ms (for animation effects)
95      */
draw_shadows(double current_time)96     virtual void draw_shadows(double current_time) {};
97 
98     /**
99      *  Get player position
100      */
101     virtual CRRCMath::Vector3 getPlayerPosition(int num = 0);
102     virtual CRRCMath::Vector3 getStartPosition(int num = 0);
103     virtual CRRCMath::Vector3 getStartPosition(std::string);
104     virtual int getNumStartPosition();
105     virtual std::string *const getStartPositionName(int num = 0);
106 
107     /**
108      *  Get the height at a distinct point.
109      *  \param x x coordinate
110      *  \param z z coordinate
111      *  \return terrain height at this point in ft
112      */
113     virtual float getHeight(float x, float z) = 0;
114 
115     /**
116      *  Get the default wind direction specified in the scenery file.
117      */
getDefaultWindDirection(void)118     inline float getDefaultWindDirection(void) {return flDefaultWindDirection;};
119 
120     /**
121      *  Get the default wind speed specified in the scenery file.
122      */
getDefaultWindSpeed(void)123     inline float getDefaultWindSpeed(void) {return flDefaultWindSpeed;};
124 
125     /**
126      *  Get the ImposeWindDirection value specified in the scenery file.
127      */
getImposeWindDirection(void)128     inline int getImposeWindDirection(void) {return ImposeWindDirection;};
129 
130     /**
131      *  Get the default turbulence mode specified in the scenery file.
132      */
getDefaultTurbulence(void)133     inline float getDefaultTurbulence(void) {return wdDefaultTurbulence;};
134 
135     /**
136      *  Get the real altitude of scenery origin point
137      */
getOriginAltitude(void)138     inline float getOriginAltitude(void) {return OriginAltitude;};
139 
140     /**
141      *  Get height and plane equation at x|z
142      *  \param x x coordinate
143      *  \param z z coordinate
144      *  \param tplane this is where the plane equation will be stored
145      *  \return terrain height at this point in ft
146      */
147     virtual float getHeightAndPlane(float x, float z, float tplane[4]) = 0;
148 
149     /**
150      *  Get wind components at position X_cg, Y_cg, Z_cg
151      */
152     virtual int getWindComponents(double X_cg, double Y_cg, double Z_cg,
153                                   float *x_wind_velocity,
154                                   float *y_wind_velocity,
155                                   float *z_wind_velocity) = 0;
156 
157     /**
158      *  Draw wind vectors describing the wind field around model
159      *  mode == 1 color based on total wind speed
160      *  mode == 2 color based on vertical wind speed
161      */
162     void drawWindField(CRRCMath::Vector3 pos, int mode);
163 
164     /**
165      *  Get an ID code for this location or scenery type
166      */
167     virtual int getID() = 0;
168 
169     /**
170      *  Get the name of this location as specified in the
171      *  XML scenery description file.
172      *
173      *  \return scenery name
174      */
getName()175     inline const char *getName()  {return name.c_str();};
176 
177     /**
178      *  Get the index of the sky definition in the
179      *  XML scenery description file that is currently loaded.
180      *
181      *  \return sky variant index
182      */
getSkyVariant()183     inline int getSkyVariant()  {return nSkyVariant;};
184 
185     /**
186      *  Set the scenery's pointer to the sky.
187      *  (required by Video dialog which may regenerate the sky)
188      */
setSky(Video::SkyRenderer * sky)189     inline void setSky(Video::SkyRenderer *sky)  {theSky = sky;};
190 
191     /**
192      *  Get various info about the sky of current scenery.
193      */
getAmbientColor(sgVec4 clr)194     void getAmbientColor(sgVec4 clr) {theSky->getAmbientColor(clr);};
getSunPosition(sgVec3 pos)195     void getSunPosition(sgVec3 pos) {theSky->getSunPosition(pos);};
getSunColor(sgVec4 clr)196     void getSunColor(sgVec4 clr) {theSky->getSunColor(clr);};
getFogDensity()197     float getFogDensity() {return theSky->getFogDensity();};
getFogColor(sgVec4 clr)198     void getFogColor(sgVec4 clr) {theSky->getFogColor(clr);};
199 
200     /**
201      *  locations:
202      *  DAVIS          CRRC Davis flying field in Sudbry, Mass
203      *  MEDFIELD       CRRC Medfield flying site in Medfield, Mass
204      *  CAPE_COD       Slope Soaring at Cape Cod, Massachusetts
205      *  XML_HMAP       read from scenery file (old height-map format)
206      *  NULL_RENDERER  empty renderer
207      *
208      *  \todo Everything that depends on these constants should
209      *  get its information from the scenery file instead of
210      *  using hard-coded stuff. In the end these constants should
211      *  only be used as an argument to the ctor of BuiltinScenery.
212      */
213     enum { DAVIS=1, MEDFIELD=2, CAPE_COD=3, XML_HMAP=4, NULL_RENDERER=5,
214            MODEL_BASED=6, PHOTO=7 };
215 
216   protected:
217     float flDefaultWindSpeed;       ///< default wind speed from scenery file in ft/s
218     float flDefaultWindDirection;   ///< default wind direction from scenery file in degrees
219     int ImposeWindDirection;        ///< if true,  WindDirection is not modifiable
220     float wdDefaultTurbulence;      ///< default turbulence relaive intensity from scenery file
221     std::string name;               ///< name of this location, from XML description
222     float OriginAltitude;           ///< real altitude of scenery in ft (for air density)
223 
224   private:
225     /**
226      *  Read a set of positions into a position array
227      */
228     int parsePositions(SimpleXMLTransfer *tag, T_PosnArray& pa, bool default_on_empty = true);
229 
230     SimpleXMLTransfer *xml_description;
231     T_PosnArray views;
232     T_PosnArray starts;
233 
234     int nSkyVariant;                ///< index of the currently loaded sky variant
235     Video::SkyRenderer *theSky;     ///< copy of pointer to sky object
236 
237     /**
238      *  3D wind vectors drawing auxiliary routines
239      */
240     void setColorFromScale(float val, float min, float max, float alpha);
241 };
242 
243 
244 /**
245  *  Load a scenery from a file
246  */
247 Scenery* loadScenery(const char *fname, int sky_variant = 0);
248 
249 
250 /** \brief initial NULL renderer scenery
251  *
252  */
253 class SceneryNull : public Scenery
254 {
255   public:
Scenery(NULL,sky_variant)256     SceneryNull(int sky_variant = 0) : Scenery(NULL, sky_variant) {}
257 
getHeight(float x,float z)258     float getHeight(float x, float z){return 0;}
getHeightAndPlane(float x,float z,float tplane[4])259     float getHeightAndPlane(float x, float z, float tplane[4]){return 0;}
getID()260     int getID() {return 0;}
getWindComponents(double X_cg,double Y_cg,double Z_cg,float * x_wind_velocity,float * y_wind_velocity,float * z_wind_velocity)261     int getWindComponents(double X_cg,double Y_cg,double Z_cg,
262                           float *x_wind_velocity,
263                           float *y_wind_velocity,
264                           float *z_wind_velocity){return 1;}
draw(double current_time)265     void draw(double current_time){};
266 
getPlayerPosition(int num)267     CRRCMath::Vector3 getPlayerPosition(int num){return CRRCMath::Vector3(0.,0., 0.);}
getStartPosition(int num)268     CRRCMath::Vector3 getStartPosition(int num){return CRRCMath::Vector3(0.,0., 0.);}
getNumStartPosition()269     int getNumStartPosition(){return 0;}
270 };
271 
272 #endif  // CRRC_SCENERY_H
273