Compare commits

..

113 Commits

Author SHA1 Message Date
curt
d915ccec6e Updates for the official 0.3.4 version. 2003-10-22 19:21:24 +00:00
ehofman
ea1b70191c Shoot, I was trying to hunt down a bug that wasn't even caused by the sstream implementation! Back out some of the previous patches 2003-10-20 19:53:35 +00:00
ehofman
19815c3bce And don't forget to free up the used memory. 2003-10-20 19:38:27 +00:00
ehofman
66fb6b5a1c Make it easy on myself (and make it work as a bonus) 2003-10-20 19:32:50 +00:00
ehofman
94ac87f4f5 Last fixes 2003-10-20 12:14:10 +00:00
ehofman
79d5bf66a7 Safety updates 2003-10-20 09:41:26 +00:00
ehofman
a4535c92c3 fixes and updates for fgrun 2003-10-20 09:06:13 +00:00
ehofman
cecdb15692 Fix a problem which was introduced in the previous patch 2003-10-16 14:53:14 +00:00
ehofman
3c08eae85b Fix a problem where older IRIX compilers needed a typecast for certain opperations 2003-10-16 12:51:47 +00:00
curt
db928ea1ae Various updates for the upcoming 0.3.4 release. 2003-10-15 20:15:29 +00:00
curt
bb002356b4 Fix a stragling left over reference to metakit. 2003-10-15 20:01:41 +00:00
ehofman
431e78cf09 Add the ability to set three levels of detail for static scenery using the property tree 2003-09-28 08:38:48 +00:00
ehofman
81b9ec50b0 Fix a dependency problem 2003-09-25 08:22:40 +00:00
curt
e0ba803ca9 A couple changes to allow separate handling of VASI/PAPI lights which
generally are turned on all the time.
2003-09-24 19:56:51 +00:00
ehofman
7ae57483f3 Fix a problem where the compiler would mix up two function declarations because the one wich has SGSubsystem in it's options list expected a const SGSubsystem, but it was called with a plain SGSubsystem 2003-09-24 19:06:59 +00:00
ehofman
d22640ef4e Move FGEventMgr and FGSubsystemMgr over to SimGear, add SGEventMgr to FlightGear's globals structre and some small code cleanups 2003-09-24 17:19:22 +00:00
curt
f3eeeb760f Various tweaks to handling taxiway lighting. 2003-09-23 23:06:50 +00:00
ehofman
695e112039 Fix a problem where the upper cloud layers are drawn with the sun punch through value 2003-09-23 08:42:20 +00:00
ehofman
133e67adb8 Fix a problem where the cloud layers suddenly change color when looking towards the sun 2003-09-22 12:32:03 +00:00
ehofman
6079cd3df8 Initialize some variables before using them 2003-09-17 17:59:28 +00:00
ehofman
6f4fd2dc6e Frederic Bouvier:
This patch is there to correct a problem that prevent to load static objects when specifying a relative fg-root or a different, relative, fg-scenery. It appears that there is a mix between fg-root, fg-scenery and PLIB's model-dir.
It has been reported on the list that users are not able to see the buildings, especially those running the win32 builds because they run 'runfgfs.bat' that set FG_ROOT=./DATA.

I decided not to use model-dir because it just add confusion and to build a valid path earlier.
2003-09-13 11:45:47 +00:00
ehofman
b30eb9c00c Add support for win32-pthreads in MSVC.NET 2003-09-13 11:33:49 +00:00
ehofman
1236d8be19 Fix a problem for systems with older headers 2003-09-12 21:24:52 +00:00
ehofman
cb35ecb4b0 Use default OpenGL material colors 2003-09-09 14:33:29 +00:00
ehofman
54550aa002 Change the defaults color specifications 2003-09-08 13:11:19 +00:00
ehofman
d3db963dce Add a blend animation 2003-09-05 12:36:01 +00:00
ehofman
1dde23a0c9 Update some light parameters 2003-09-02 09:11:21 +00:00
ehofman
5feccc73c7 Fix the box like cloud layer appearance 2003-08-31 09:23:48 +00:00
curt
1cf13a7c1a Fix some lighting values. 2003-08-31 03:12:27 +00:00
ehofman
7289ac645a New automake, new problems. Use $base_LIBS where $LIBS was automatically added before 2003-08-29 07:35:55 +00:00
curt
699909f808 Remove metakit from src-libs, remove metakit check from configure script,
remove README.metakit.
2003-08-29 04:19:56 +00:00
ehofman
344610e24b Actually use the calculated position in the layer list. This prevents the use of glDepthMask(). Clean up the code some. 2003-08-22 16:58:01 +00:00
ehofman
092901b9ea Clouds3D crashes because there is no Light 2003-08-22 16:18:33 +00:00
ehofman
3ac6b34f4b Disable depth buffer writes while drawing the layers and some cosmetic updates 2003-08-22 09:48:49 +00:00
ehofman
d56b961c47 A patch from Frederic Bouvier which performs z-buffer ordering of the cloud layers to prevent transparency problems with other (se mi) transparent objects. Good work Frederic! 2003-08-22 08:07:21 +00:00
ehofman
858a73e187 Adjust the layer span and amount of curving based on the eleveation of the layer 2003-08-19 12:04:15 +00:00
ehofman
1623aee1e0 MacOS X fixes 2003-08-19 08:25:16 +00:00
curt
c0a633ea1d Give calc_tex_coords() a more conformant name: sgCalcTexCoords() 2003-08-19 02:08:16 +00:00
ehofman
5628c85b51 Frederic Bouvier:
This patch was inspired by Norman. Otherwise there is a segfault on Linux because the global variable tries to access OGL before a valid context is initialized.
2003-08-16 12:30:25 +00:00
ehofman
2e1accc0f3 Don't use glGet because of performance issues 2003-08-15 17:44:36 +00:00
ehofman
93b747f1ba Add support for NVidia cards with a broken OpenGL implementation 2003-08-15 17:19:22 +00:00
ehofman
21c16b4a51 A small update to the fog punch through code 2003-08-14 12:32:58 +00:00
ehofman
e5e1e165b9 Adjust the fog punch through effect for oursun 2003-08-14 09:58:48 +00:00
ehofman
8ae39ae8d4 MSVC fixes 2003-08-12 19:26:03 +00:00
curt
110e01a861 Remove extraneous/unneeded dependencies on glut. SimGear should no longer
have any glut dependies.
2003-08-11 21:16:53 +00:00
curt
578e774778 Remove "glut" dependency.
- SkyContext.[ch]pp needs to query the window size, but apparently doesn't
  do anything with it.  We can hard wire a size and the cloud code seems to
  behave fine.

- SkyLight.[ch]pp depends on glut_shapes so I copied over the code so it
  can access those routines locally.  (The routines that are used are
  simply combining calls to libGLU.a
2003-08-11 21:14:48 +00:00
curt
d7d13e458c Oops, it doesn't do much good to declare a function as "static" in the .hxx 2003-08-11 19:42:08 +00:00
curt
0bf579cf27 Only use the ";" delimiter under WIN32 2003-08-09 02:54:15 +00:00
curt
77cefa924c Add a routines that takes a search path (separated by sgSearchPathSep) and
seperates them into a vector of strings which it then returns.
2003-08-08 19:54:49 +00:00
ehofman
1fe26901af Go back to a function that actually does check wheter endian swapping needs to be done 2003-08-07 14:11:35 +00:00
ehofman
0dd50cf3d8 Add support for using textures as a basis for cloud fields. This is not yet completely finished. The orientation is not right. 2003-08-07 12:34:23 +00:00
ehofman
54b3c711c3 Add support for rgba textures 2003-08-07 12:31:16 +00:00
ehofman
f404161d23 Improve endian awareness somehwat. Still not therer though 2003-08-06 17:54:19 +00:00
ehofman
5a13068aaa Melchior FRANZ: Make the clouds3d code valgrind clean 2003-08-05 18:59:58 +00:00
curt
32067b9adf Changed "GL/glut.h" to <GL/glut.h> 2003-08-05 14:45:42 +00:00
ehofman
ea2f5f0035 Put clouds3d back in the build proces after (hopefully) fixing all the build problems 2003-08-04 17:29:30 +00:00
ehofman
ea6540ef90 Add dynamic glMultiTextureARB detection 2003-08-04 17:10:52 +00:00
ehofman
1d5c1de5d3 Add a safety precausion 2003-08-04 17:05:12 +00:00
ehofman
4b11d87a22 Add runtime detection of glActiveTextureARB 2003-08-04 12:54:57 +00:00
ehofman
c2149f9ea6 Pre-initialize the variables driving the external force 2003-08-04 12:07:04 +00:00
ehofman
73a4994cac Norman Vine:
Note that SSG and OpenGL use different representations
of Matrices.

1) SSG is row major and OpenGL is column major

2) SSG uses a Z is up whereas conventionally OpenGL uses
   Z is pointing into the screen
   ie this just requires swapping the Y and the Z axis < columns >
   and negating the new Y column

3) Now since SSG eventually calls OpenGL SSG must do this
   for us behind the scenes or else things just wouldn't work
   so inorder to get Clouds3D to render in the proper location
   we should just need to use the Matrix that SSG uses for a Camera
   Matrix and pass this directly to the Clouds3D Camers
2003-08-03 21:23:21 +00:00
ehofman
c9a4a6975c Hide an obvious mistake by defining our own ulEndianLittleDouble function for now 2003-08-03 08:25:26 +00:00
ehofman
1a1aa37a0e Adjust the fog according to visibillity 2003-08-01 14:20:20 +00:00
ehofman
7d3abdc512 Add cloud movement direction and speed 2003-07-31 14:46:24 +00:00
ehofman
db4c2243e3 Keep the stack clean 2003-07-31 09:04:32 +00:00
curt
6dc243e1af Actually commit the code changes which impliment a "scale" animation type. 2003-07-25 14:48:02 +00:00
ehofman
adb5fb3bee MSVC warning fixes 2003-07-23 09:59:39 +00:00
ehofman
7955319771 Jim Wilson:
Fixed texture translation so step and scroll values work with interpolation tables as well.  Moved step/scroll calculation to utility function to improve code readability.
2003-07-21 08:37:22 +00:00
ehofman
3da76522f8 Fix a typo 2003-07-16 11:32:08 +00:00
ehofman
c9ac1b5a06 Don't bother other develoers with problems caused by MipsPro (version < 7.3) compilers 2003-07-13 12:34:52 +00:00
ehofman
51dff6b537 Don't check for OpenGL libraries without at least including -lm 2003-07-12 09:18:54 +00:00
curt
1f4b55e98e Attempt to get these files back to a compilable state. 2003-07-11 17:50:32 +00:00
ehofman
229ea27050 Don't use floats where ints are more appropriate 2003-07-11 10:55:17 +00:00
ehofman
505b4c434d Allow removing of the texture data after it is sent to OpenGL 2003-07-11 09:57:28 +00:00
ehofman
12ab6872ec Sync he configure script with that one from FLightGear by splitting the LIBS cariable into a base_LIBS, opengl_LIBS, network_LIBS and thread_LIBS variable 2003-07-10 10:02:10 +00:00
ehofman
4c78e887e1 Jim Wilson:
This update adds the ability to do multiple texture transforms (Steve B. thinks supporting them at the plib level would be inefficient, which is probably true).

Removed units (e.g. "_m") from texture translation property and variable names since the texture translation values are dimensionless.

Added the ability to specify a scroll factor for stepped texture animation that needs to scroll smoothly when approaching the step interval (e.g. odometer movement).
2003-07-10 09:49:29 +00:00
ehofman
8871655a9b Don't delete the texture data after sending it to OpenGL. 2003-07-10 09:14:34 +00:00
curt
db1966c156 A couple more sanity checking tweaks for texture freeing. 2003-07-09 20:58:39 +00:00
ehofman
d4c0c8940b Prevent deleting the texture data for a second time in the destructor 2003-07-09 20:51:04 +00:00
ehofman
d4134195ea Fix a silly bug where is tested against the wrong variable 2003-07-09 19:46:04 +00:00
ehofman
a8fd1b4c16 Leave the clouds3d commented out for now 2003-07-09 14:46:30 +00:00
ehofman
086473c8eb A first attempt at making the clouds3d endian aware. Almost there. 2003-07-09 14:43:53 +00:00
ehofman
5642ef61ca Back out a patch that never went in CVS ... 2003-07-09 13:40:06 +00:00
ehofman
fec7c62b17 Don't link agains OpenGL libraries when it's not needed 2003-07-07 11:27:10 +00:00
ehofman
e046b1bfdb Clean up, and make more flexible and prevent unnessecary library includes 2003-07-06 17:13:25 +00:00
ehofman
01007986dc Solaris updates 2003-07-02 12:25:08 +00:00
ehofman
ad56ba1bfa Add a function which might return whether a texture is in video memory, delete the texture buffer after sending it to OpenGL and comment out the set/get_pixel functions 2003-07-01 09:49:45 +00:00
ehofman
54c2d5a6cc MSVC fixes 2003-06-28 21:43:41 +00:00
ehofman
25ad84e5cb Put the refference to fast_log() back in after checkit it actually works as expected 2003-06-28 13:43:09 +00:00
ehofman
dcdf8a4d5c Fix some problems 2003-06-28 12:58:59 +00:00
ehofman
5d24be8c51 Add some fast math functions 2003-06-28 12:06:09 +00:00
ehofman
fa42efcf91 Do some math omtimizations as pointed out by Norman 2003-06-27 21:36:05 +00:00
curt
7f4f778bb1 Explicitely initialize planets. 2003-06-26 17:13:27 +00:00
ehofman
8a2e5cace8 Use the dlsym based approach on all unices and depreciate the glXGetProcAddressARB function 2003-06-24 08:22:33 +00:00
ehofman
23c66b6cfe cygwin and mingw fixes 2003-06-22 11:49:19 +00:00
ehofman
b65fe814a0 Cross platform fixsimgear/screen/extensions.hxx 2003-06-20 20:05:52 +00:00
ehofman
e74c8587bd Increase the maximum number of simultanious audio streams to the maximum defined by plib 2003-06-20 19:44:41 +00:00
ehofman
ab34b86574 Mac OS X fix 2003-06-20 19:32:04 +00:00
ehofman
011ecd980d MSVC and Apple OS X fixes 2003-06-19 07:40:54 +00:00
ehofman
9ca1c6666e Add our own function to check whether a certain OpenGL extension is supported 2003-06-18 09:06:54 +00:00
ehofman
ba5316ca8e Add an OpenGL extension query function which should be cross platform 2003-06-17 16:55:21 +00:00
ehofman
f957227576 Don't make the sun imune for fog 2003-06-13 19:56:05 +00:00
curt
70f763dbe0 - Tweaks to doxygen main page.
- Added documentation for SGCloudLayer
- Updated the SGSky interface a bit to make it more sensible, flexible,
  and generic.  This requires a code tweak on the FlightGear side as well.
2003-06-11 18:55:36 +00:00
curt
f8201e6478 Make sky dome scaling values sensible (i.e. the sky dome will now fill up
the dimensions provided.)  We draw the sky dome before everything else
  and draw it with depth buffer off so it really doesn't matter, but it just
  makes a little more sense this way.
Updated a few doxygen comments.
2003-06-09 20:19:52 +00:00
ehofman
e053941467 Add the ability to include stepped texture translations for things like digital displays in 3D model animation. 2003-06-09 09:11:20 +00:00
ehofman
17e2478522 Jim Wilson:
1. Added support for defining arbitrary rotation axes using (x1,y1,z1), (x2,y2,z2).  The center is calculated automatically (midpoint on line) or you may specify an alternate "center" using the current scheme.  This makes it about  100 times easier to animate flaps, ailerons, etc.

2. Added support for plib's ssgTexTrans.  This will allow more sophisticated 3D instrument features by allowing the texture mapping itself to be animated. Included function for "texrotate" and "textranslate".  They configure the same as the geometry, except the arbitrary axis definition is not necessary (textures are flat).
2003-06-08 13:19:34 +00:00
ehofman
17df7141ae Remove some now depreciated lighting code 2003-06-07 10:35:20 +00:00
ehofman
5167dee0e3 Remove an unused variable 2003-06-03 19:37:21 +00:00
ehofman
a1a596b02a Add some more descriptive comments 2003-06-03 19:35:20 +00:00
curt
27f98d24eb Various 0.3.3 last minute tweaks. 2003-06-03 18:48:49 +00:00
curt
51ef4568dd Various documentation tweaks and additions. 2003-06-03 18:32:51 +00:00
curt
4c731de8b7 Tweaks to doxygen comments. 2003-06-03 18:22:10 +00:00
ehofman
fc692cb540 compiler fixes 2003-06-03 13:30:07 +00:00
107 changed files with 5537 additions and 1055 deletions

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.3.2
PROJECT_NUMBER = 0.3.4
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
@@ -308,12 +308,14 @@ INPUT = \
simgear/magvar \
simgear/math \
simgear/misc \
simgear/props \
simgear/route \
simgear/scene \
simgear/screen \
simgear/serial \
simgear/sg_inlines.h \
simgear/sg_traits.hxx \
simgear/sound \
simgear/threads \
simgear/timing \
simgear/xml

View File

@@ -18,31 +18,66 @@
* Some of the functionality provide includes
*
* - Compiler and platform abstractions for many tricky differences.
* - A whole earth tiling/indexing scheme.
* (compiler.h)
*
* - A whole earth tiling/indexing scheme. (SGBucket)
*
* - A console debugging output scheme that tracks severity and
* category that can be completely compiled out for a final build release.
* - Code to manage "real" time and time zones.
* (logstream.hxx)
*
* - Code to manage "real" time (SGTime), time zones (SGTimeZone), and
* millesecond time differences (SGTimeStamp).
*
* - Code to calculate accurate positions of sun, moon, stars, and
* planets for a given time, date, season, earth location, etc.
* - Simple serial, file, and network I/O abstractions
* - Code to calculate magnetic variation.
* - A variety of coordinate conversion, vector, matrix type math routines.
* - An abstraction to hide platform dependent path naming schemes.
* (SGEphemeris)
*
* - Code to render a realistic sky dome, cloud layers, sun, moon,
* stars, and planets all with realistic day/night/sunset/sunrise
* effects. Includes things like correct moon phase, textured moon,
* sun halo, etc. (SGSky is built on top of SGCloudLayer ...)
*
* - Simple serial (SGSerial), file (SGFile), socket (SGSocket), and
* UDP socket (SGSocketUDP) I/O abstractions.
*
* - Code to calculate magnetic variation. (SGMagVar)
*
* - A variety of classes and functions for interpolation tables
* (SGInterpTable), least squares computation (leastsqs.hxx), 3D
* point/vectors (Point3D), 3D polar math and conversions (polar3d.hxx),
* WGS-84 math and conversions (sg_geodesy.hxx), random number abstraction
* (sg_random.h), STL conglomerates for common list types (sg_types.hxx),
* and other vector and linear algebra routines (vector.hxx)
*
* - An abstraction to hide platform dependent path naming schemes. (SGPath)
*
* - A C++ streams wrapper to handle compress input/output streams.
* (sg_gzifstream)
*
* - An optimized "property manager" which associates ascii property
* names with their corresponding value. This can be a great way to build
* loose linkages between modules, or build linkages/connections that can
* be determined from config files or at runtime.
* be determined from config files or at runtime. (SGPropertyNode)
* Also included is a set of functions to dump the property tree into a
* standard xml file and subsequently read/parse a standard xml file and
* rebuild the associated property tree. (props_io.hxx)
*
* - Scene management and drawing routines:
* - material property management
* - object management
* - terrain tile management and paging
* - sky dome rendering (with ephemeral objects)
* - Code to handle screen dumps (and ultra-hires tile rendered screen dumps)
* - A sound effects manager.
* - A threading abstraction.
*
* - Code to handle screen dumps (screen-dump.hxx) and ultra-hires
* tile rendered screen dumps (tr.h)
*
* - A sound effects manager. (SGSoundMgr, SGSimpleSound, SGSound)
*
* - A threading abstraction. (SGThread)
*
* - A simple but highly functional XML parser that interfaces nicely
* with the property manager.
* with the property manager. (easyxml.hxx)
* \section supports Supported Platforms
* SimGear has been built on the following platforms:
@@ -69,10 +104,5 @@
*
* SimGear is licensed under the terms of the LGPL
* \section install Installation
*
* \subsection step1 Step 1: Opening the box
*
* etc...
*/

View File

@@ -11,7 +11,7 @@ EXTRA_DIST = \
SUBDIRS = src-libs simgear
dist-hook:
(cd $(top_srcdir); $(HOME)/projects/FlightGear-0.7/admin/am2dsp.pl)
(cd $(top_srcdir); $(HOME)/projects/FlightGear-0.9/admin/am2dsp.pl)
#
# Rule to build RPM distribution package

33
NEWS
View File

@@ -1,3 +1,36 @@
New in 0.3.4
* October 22, 2003
* Removed Metakit, FlightGear no longer uses it.
* Removed all glut dependencies from SimGear.
* Moved FGEventMgr and FGSubsystemMgr over to SimGear.
* Some more incremental work on 3D clouds.
* Added some "fastmath" functions.
* Some lighting tweaks and fixes (especially for taxiways.)
* Added support for "blend" and "scale" and "texture" animations.
* Added support for animating rotations around an arbitrary axis (so the
aircraft designer isn't forced to figure out animations as a combination
of rotations around X, Y, and X axes.
* Updates to sky dome modeling and make cloud layers follow the curve
of the earth (sort of.)
* Updates to sky dome, cloud, and sunrise/sunset color and lighting
effects to make them more realistic and lifelike.
* Better support for detecting and using OpenGL extensions at run time.
* Add support for win32-pthreads in MSVC.NET
* Various MSVC fixes.
* Various Solaris fixes.
* Various cygwin/mingwin fixes.
* Various Mac OS X fixes.
* Various Irix fixes.
New in 0.3.3
* June 3, 2003
* Fix a compile problem for cygwin
* Updated/tweaked doxygen documentation in several areas
New in 0.3.2
* June 2, 2003

View File

@@ -1,285 +0,0 @@
For your convenience (and with the author's permission) a copy of the
MetaKit source is bundled with SimGear in $(top_srcdir)/src-libs/.
You must have metakit installed before you can build SimGear.
- Most linux distributions have a metakit package. For linux
developers, we recommend ysou install your distributions package
rather than building from source.
- For developers on most other platforms, you will have to build
metakit from source and install it yourself. For your convenience a
tar ball of the metakit source is included with the simgear source
distribution. Untar the metakit source, and follow the included
build and installation instructions.
Once metakit is installed you can return to configuring and building
Simgear.
=============================================================================
Potentially important build note:
Later on when you are linking programs with -lmk4 (i.e. FlightGear or one
of it's associated programs) if you come across an error similar to the
following:
c++ -Wall -O2 -L/usr/local/lib -o gensimple gensimple.o libAirports.a
-lsgdebug -lsgmisc -lmk4 -lz -lm
/usr/local/lib/libmk4.a(view.o)(.text+0x1c8):view.cpp: multiple definition
of `c4_View::~c4_View(void)'
libAirports.a(simple.o)(.text$_$_7c4_View+0x0):simple.cxx: first defined
here
collect2: ld returned 1 exit status
make[2]: *** [gensimple] Error 1
make[2]: Leaving directory `/home/curt/FlightGear-0.7.7/src/Airports'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/curt/FlightGear-0.7.7/src'
make: *** [all-recursive] Error 1
Then you need to come back and rebuild Metakit with the -DNDEBUG flag.
For unix/cygwin systems, modify the unix/Makefile file and add -DNDEBUG
to the CFLAGS line.
Now we return you to the official metakit readme ... :-)
The MetaKit Library 2.01 March 2000
==============================================================================
WHAT IT IS - MetaKit is an embeddable database which runs on Unix, Windows,
Macintosh, and other platforms. It lets you build applications which
store their data efficiently, in a portable way, and which will not need a
complex runtime installation. In terms of the data model, MetaKit takes
the middle ground between RDBMS, OODBMS, and flat-file databases - yet it
is quite different from each of them.
WHAT IT ISN'T - MetaKit is not: 1) multi-user/-threading, 2) scalable to
gigabytes, 3) proprietary software, 4) full of bugs, 5) just a toy.
TECHNOLOGY - Everything is stored variable-sized yet with efficient positional
row access. Changing an existing datafile structure is as simple as re-
opening it with that new structure. All changes are transacted. You can
mix and match software written in C++, Python, and Tcl. Things can't get
much more flexible...
CORE - The Metakit core library is written in C++. It has a code footprint of
just over 100 Kb on Windows. It can be used as DLL, or linked statically.
Debug builds include extensive assertion checks to catch problems early.
PYTHON - The binding for Python is called "Mk4py". It uses SCXX by Gordon
McMillan as C++ glue interface. The source is in directory "python/".
TCL/TK - The MK extension for Tcl is called "Mk4tcl". It is being used in a
number of commercial projects, for in-house use as well as in commercially
distributed products. The source is in directory "tcl/".
LICENSE AND SUPPORT - MetaKit 2.01 is distributed as open source software (the
X/MIT-style license is at the end of this document). Commercial support
is available through an Enterprise License, see the URL mentioned below.
DOCUMENTATION - All documentation uses HTML. The main page is "MetaKit.html",
which leads to the rest of the documentation in the "doc/" directory.
WEBSITE URLS - The main pages on the world wide web, for news and downloads:
Homepage: http://www.equi4.com/metakit/
Python news: http://www.equi4.com/metakit/python.html
Tcl/Tk news: http://www.equi4.com/metakit/tcl.html
License info: http://www.equi4.com/metakit/license.html
Contact info: http://www.equi4.com/contact.html
INSTALLATION
============
Starting with this release, all platform builds and language bindings are now
designed to work from a single common "builds/" directory. It turns out to
be impossible to keep build side-effects limited to *just* this directory
(CodeWarrior can't be told where to place its temp data, and Visual C++ still
alters a few files next to the project ".dsw" file, to name two offenders).
UNIX
It is no longer advised to build the Unix code in the "unix/" directory.
Instead, you should perform the following steps:
% cd builds
% ../unix/configure
% make
% make test
And optionally (this only installs the core lib, not script extensions):
% make install
By switching to the "builds/" directory, you will keep the distribution
directory tree 100% unaltered. All changes are made in this subdir, and
all final build results are left behind in this same subdir.
Nastiness: if you build Mk4tcl, please do a "make Mk4tcl.so" as well.
And if you intend to create the Python extension, do a "make Mk4py.so".
The "libmk4tcl.so.0.0.0" and "libMk4py.so.0.0.0" targets are bogus ones.
You will probably have to make changes in the makefile to locate the
proper includes and libs for Python (Tcl has been fixed, see "--with-tcl).
You probably only need to adjust "CXX_SWITCHES_PY" to find the headers.
To build with STL containers and strings, you can do the following:
make CXXFLAGS='-Dq4_STD' test # add -O3 etc, as needed
This passes the test suite on Linux RedHat 5.2 with gcc 2.95-2.
See below for some platform-specific build notes.
WINDOWS
There is a "win/" directory which contains subdirectories for a number of
compiler systems. MetaKit has been built with many different compilers
in the past (Microsoft, Borland, Watcom, Symantec, Metrowerks, Optima),
but to preserve my sanity (there are 12 configurations for MSVC6 alone!),
I am limiting myself to MSVC6, MWCW5, Borland C++ Builder 4, and Cygwin.
The MS Visual C++ 6.0 project is "win/msvc60/mksrc.dsw", with subprojects
for the C++ demo (mkdemo), building dll's (mkdll), static libs (mklib),
regression tests (mktest), as well as Tcl (mktcl) and Python (mkpython).
It has been set up to place all intermediate files and final results in
the "builds/" subdirectory, even though you'll launch it from "win/".
To build with STL containers and strings under MSVC, define "q4_STD".
To build with MFC containers and strings under MSVC, define "q4_MFC".
The Metrowerks Codewarrior project is in the "mac/" directory, and can be
used to build both Mac and Windows versions (on either Mac *or* Windows).
The core libraries are built with "mac/cw5.mcp", demos / tests are built
with "cw5apps.mcp", Tcl is "cw5tcl.mcp", and Python is "cw5python.mcp".
The Borland C++ Builder projects have not yet been incorporated in this
release, but the "KitViewer" application is an example of how to use BCB.
The Cygwin build (B20.1 / gcc 2.95.2) is different, because it uses the
unix autoconf system, and must be launched as described above for UNIX.
I have upgraded to the latest development of libtool to be able to build
DLL's with Cygwin. You can build the "-mno-cygwin" version by editing
the Makefile by hand and adding that option to CXXFLAGS.
Rob Bloodgood adds that the following GCC options are for maximum code
efficiency on x86 hardware: "-O2 -m486 -malign-loops=2 -malign-jumps=2".
I have not yet tried this myself, but am passing on the tip.
MACINTOSH
The Mac version requires Metrowerks CodeWarrior 5. See the info above
in the Windows section (MWCW is multi-platform). The projects are all
located in the "mac/" folder, which is also where MWCW will place its own
"... Data" folders with intermediate results. As with all other setups,
final results are made to end up in the "builds/" directory.
Static 68K builds appear to work fine, the 68K CFM variants will need
some more work (I couldn't get the libraries to export their symbols).
PLATFORM-SPECIFIC NOTES
=======================
* Linux RH 5.2 / gcc 2.95.2
Builds with gcc 2.95.2 work out of the box. The Tcl extension ends up as
".libs/libmk4tcl.so.0.0.0" (to please libtool), and should be renamed to
"Mk4tcl.so". Similarly, ".libs/libMk4py.so.0.0.0" is in fact the Python
extension, and *must* be renamed to "Mk4py.so" to call it from Python.
The core MK libs end up as ".libs/libmk4.a" and ".libs/libmk4.so.0.0.0".
* Solaris 2.6 / gcc 2.8.1
The Solaris builds are nasty for several reasons:
- I do not own such a machine, and often have to make arrangements
(or fight limited space on one of the machines I can telnet to).
- The gcc 2.8.1 optimizer appears to be buggy, I have had to turn off
the default "-O3" flag to prevent compiler crashes (several files).
This problems appears to be resolved with gcc 2.95.
- Locking on Solaris (especially w.r.t NFS) remains a mystery to me.
The Tcl and Python extensions both use locking (the core not yet).
See tcl/Mk4tcl.cpp around line 520, and python/PyStorage.cpp around
line 80 for details. It's all pretty messy, and not 100% correct.
Despite this, I'm doing my best to resolve these issues. Having a solid
build of the core *and* of Tcl / Python extensions is quite important.
* Other Unix systems
No further notes, though many systems will build fine out of the box.
* Windows
MSVC 6 builds MK as static lib and as DLL (universal config, I have not
yet created build versions with MFC or STL, mainly because MK can now be
used in all contexts regardless of how it was built). The Python and Tcl
extensions build as dynamic extensions (a static build is easy to add).
MWCW 5 builds MK as static lib and as DLL (interestingly enough, the DLL
is slightly smaller than MSVC 6 - 102 vs 108 Kb - when their runtimes are
linked in dynamically as well). I have not added Win builds for Tcl or
Python, since MSVC 6 has those already.
Cygwin B20.1, with gcc 2.95.2 ugrade, also builds MK as static lib and as
DLL. Both "pure" Cygwin (i.e. requiring cygwin1.dll) and mingw32 (using
the -mno-cygwin flag) build, but there are some hairy include issues when
it comes to choosing the right locking model for Tcl and Python. These
issues have not been resolved fully.
* Macintosh
MWCW 5 builds PPC shared libs, PPC static libs, and 68K static libraries.
Building 68K CFM libraries leads to a "MetaKit 68K.shlb" which comes out
of the linker without errors, but the result does not seem to have any
export symbols defined (despite the fact that the library is over 200 K).
Because of that, I've been unable to build apps or Mk4tcl/Mk4py so far.
The other three configurations build, but for some reason MK's regression
test stops at L03 (everything up to that point looks ok, i.e. over 90%).
The Mk4tcl PPC extension appears to work (quick manual test), and so does
the Python extension, "Mk4py.PPC.slb". I have not yet given these two
a serious workout, hoping to have a basic test harness in place soon.
* VMS, BeOS, ...
No news yet, please report your findings with any other platform builds.
WHAT'S MISSING HERE
===================
- a section on basic concepts (or maybe it doesn't belong here?)
- a section on getting started (C++, Python, Tcl all differ - point to
the respective intro pages)
- maybe a small sample for each of C++ / Tcl / Python, to give an idea
- mention TclKit, scripted docs (WiKit/Tequila?), VFS?
- I forgot... please tell me :)
LICENSE AND COPYRIGHT STATEMENT
===============================
Copyright (c) 1996-2000 Jean-Claude Wippler
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
==============================================================================
-- Jean-Claude Wippler <jcw@equi4.com>

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ dnl Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.3.2)
AM_INIT_AUTOMAKE(SimGear, 0.3.4)
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
@@ -42,19 +42,24 @@ dnl set the $host variable based on local machine/os
AC_CANONICAL_HOST
dnl Used on the Irix platform
AR="ar"
ARFLAGS="cru"
case "${host}" in
*-*-irix*)
if test "$CXX" = "CC"; then
AR="CC -ar"
if test "x$CXX" = "xCC" -o "x$CXX" = "xccache CC"; then
AR="$CXX -ar"
ARFLAGS="-o"
CXXFLAGS="$CXXFLAGS -I$(top_srcdir)/simgear/compatibility"
compatibility_DIR="compatibility"
fi
;;
*)
AR="ar"
ARFLAGS="cru"
compatibility_DIR=
;;
esac
AC_SUBST(AR)
AC_SUBST(ARFLAGS)
AC_SUBST(compatibility_DIR)
if echo $includedir | egrep "simgear$" > /dev/null; then
echo "includedir is" $includedir "libdir is" $libdir
@@ -134,15 +139,9 @@ esac
dnl Checks for libraries.
null_LIBS="$LIBS"
AC_CHECK_LIB(m, cos)
base_LIBS="$LIBS"
dnl Thread related checks
AC_CHECK_LIB(pthread, pthread_exit)
AC_CHECK_HEADER(pthread.h)
AC_CHECK_LIB(pthread, pthread_exit)
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
CFLAGS="$CFLAGS -D_REENTRANT"
@@ -158,31 +157,32 @@ if test "x$ac_cv_lib_pthread_pthread_exit" != "xyes" -a "x$ac_cv_header_pthread_
save_LIBS=$LIBS
AC_CHECK_LIB(c_r, pthread_exit)
if test "x$ac_cv_lib_c_r_pthread_exit" != "xyes"; then
CXXFLAGS=$save_CXXFLAGS
CFLAGS=$save_CFLAGS
CXXFLAGS=$save_CXXFLAGS
CFLAGS=$save_CFLAGS
else
dnl This is cheating a bit. pthread_exit comes with using -pthread, not -lpthread
ac_cv_lib_pthread_pthread_exit="yes"
dnl This is cheating a bit. pthread_exit comes with using -pthread, not
-lpthread
ac_cv_lib_pthread_pthread_exit="yes"
fi
LIBS=$save_LIBS
fi
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes")
AC_CHECK_LIB(socket, socket)
thread_LIBS="$LIBS"
LIBS=""
dnl check for glut location
AC_CHECK_HEADER(GL/glut.h)
if test "x$ac_cv_header_GL_glut_h" = "xyes"; then
AC_DEFINE([GLUT_H], "GL/glut.h", [Define as glut.h include location])
else
AC_CHECK_HEADER(GLUT/glut.h)
if test "x$ac_cv_header_GLUT_glut_h" = "xyes"; then
AC_DEFINE([GLUT_H], "GLUT/glut.h", [Define as glut.h include location])
else
echo "Neither GL/glut.h nor GLUT/glut.h found. Cannot continue"
exit
fi
fi
dnl search for network related libraries
AC_SEARCH_LIBS(inet_addr, xnet)
AC_SEARCH_LIBS(socket, socket)
network_LIBS="$LIBS"
LIBS=""
dnl check for some default libraries
AC_SEARCH_LIBS(cos, m)
base_LIBS="$LIBS"
dnl check for OpenGL related libraries
case "${host}" in
@@ -193,7 +193,7 @@ case "${host}" in
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
AC_DEFINE([NOMINMAX], 1, [Define for Win32 platforms])
LIBS="$LIBS -lglut32 -lglu32 -lopengl32"
LIBS="$LIBS -lglu32 -lopengl32"
LIBS="$LIBS -luser32 -lgdi32 -lwinmm"
dnl add -lwsock32 for mingwin
@@ -209,35 +209,28 @@ case "${host}" in
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework GLUT -framework OpenGL -framework Carbon -lobjc"
LIBS="$LIBS -framework OpenGL -framework Carbon -lobjc"
;;
*)
dnl X-Windows based machines
AC_CHECK_LIB(X11, XCreateWindow)
AC_CHECK_LIB(Xext, XShmCreateImage)
AC_CHECK_LIB(Xi, XGetExtensionVersion)
AC_CHECK_LIB(ICE, IceOpenConnection)
AC_CHECK_LIB(SM, SmcOpenConnection)
AC_CHECK_LIB(Xt, XtMalloc)
AC_CHECK_LIB(Xmu, XmuLookupStandardColormap)
AC_SEARCH_LIBS(XCreateWindow, X11)
AC_SEARCH_LIBS(XShmCreateImage, Xext)
AC_SEARCH_LIBS(XGetExtensionVersion, Xi)
AC_SEARCH_LIBS(IceOpenConnection, ICE)
AC_SEARCH_LIBS(SmcOpenConnection, SM)
AC_SEARCH_LIBS(XtMalloc, Xt)
AC_SEARCH_LIBS(XmuLookupStandardColormap, Xmu)
AC_CHECK_LIB(GLcore, glNewList)
if test "x$ac_cv_lib_GLcore_glNewList" = "xno" ; then
dnl if no GLcore, check for GL
AC_CHECK_LIB(GL, glNewList)
if test "x$ac_cv_lib_GL_glNewList" = "xno" ; then
dnl if no GL, check for MesaGL
AC_CHECK_LIB(MesaGL, glNewList)
fi
else
AC_SEARCH_LIBS(glNewList, [ GL GLcore MesaGL ])
if test "x$ac_cv_search_glNewList" = "x-lGLcore"; then
dnl if GLcore found, then also check for GL
AC_CHECK_LIB(GL, glXCreateContext)
AC_SEARCH_LIBS(glXCreateContext, GL)
fi
dnl if using mesa, check for xmesa.h
if test "x$ac_cv_lib_MesaGL_glNewList" = "xyes" ; then
if test "x$ac_cv_search_glNewList" = "x-lMesaGL"; then
AC_CHECK_HEADER(GL/fxmesa.h)
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
AC_DEFINE([XMESA], 1, [Define for fxmesa])
@@ -245,13 +238,7 @@ case "${host}" in
fi
fi
AC_CHECK_LIB(GLU, gluLookAt)
if test "x$ac_cv_lib_GLU_gluLookAt" = "xno" ; then
dnl if no GLU, check for MesaGLU
AC_CHECK_LIB(MesaGLU, gluLookAt)
fi
LIBS="$LIBS -lglut"
AC_SEARCH_LIBS(gluLookAt, [ GLU MesaGLU ])
;;
esac
@@ -261,6 +248,8 @@ LIBS="$base_LIBS"
AC_SUBST(base_LIBS)
AC_SUBST(opengl_LIBS)
AC_SUBST(thread_LIBS)
AC_SUBST(network_LIBS)
dnl Check for MS Windows environment
AC_CHECK_HEADER(windows.h)
@@ -307,54 +296,6 @@ int main() {
AC_MSG_RESULT(yes)
)
dnl Check for MetaKit
AC_CHECK_HEADER(mk4.h)
if test "x$ac_cv_header_mk4_h" != "xyes"; then
echo
echo "MetaKit library not found."
echo
echo "If your OS does not provide an installable package for MetaKit"
echo "you will have to compile and install it first yourself. A copy"
echo "of metakit-$(VERSION).tar.gz is included with SimGear. You will"
echo "have to untar this source code, and follow its included instructions"
echo "to compile and install on your system."
echo
echo "configure aborted."
exit
fi
AC_MSG_CHECKING([for metakit 2.4.3 or newer])
saved_LIBS="$LIBS"
LIBS="$saved_LIBS -lmk4"
AC_TRY_RUN([
#include <mk4.h>
#define MIN_MK4_VERSION 243
int main() {
int major, minor, micro;
if ( d4_MetaKitLibraryVersion < MIN_MK4_VERSION ) {
return -1;
}
return 0;
}
],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(wrong version);
AC_MSG_ERROR([
Install metakit 2.4.3 or later first.
Or, the compiler may not be finding your libmk4.so library.
Please check the config.log file for specific details of the
failure if you believe you have the correct metakit version.
Also, look up this issue in the FlightGear FAQ.])],
AC_MSG_RESULT(yes)
)
LIBS="$saved_LIBS"
AC_LANG_POP
@@ -421,10 +362,12 @@ AC_CONFIG_FILES([ \
simgear/scene/material/Makefile \
simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \
simgear/scene/sky/clouds3d/Makefile \
simgear/scene/tgdb/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sound/Makefile \
simgear/structure/Makefile \
simgear/threads/Makefile \
simgear/timing/Makefile \
simgear/xgl/Makefile \
@@ -448,13 +391,6 @@ fi
echo -n "Automake version: "
automake --version | head -1
if test "x$ac_cv_header_GL_glut_h" = "xyes"; then
echo "With GL/glut.h"
fi
if test "x$ac_cv_header_GLUT_glut_h" = "xyes"; then
echo "With GLUT/glut.h"
fi
if test "x$with_jpeg_factory" = "xyes"; then
echo "With JPEG Factory support"
else

View File

@@ -13,10 +13,11 @@ include_HEADERS = \
compiler.h constants.h sg_inlines.h sg_traits.hxx version.h
SUBDIRS = \
compatibility \
$(compatibility_DIR) \
xml \
debug \
misc \
structure \
bucket \
ephemeris \
io \
@@ -33,4 +34,4 @@ SUBDIRS = \
timing \
xgl
DIST_SUBDIRS = $(SUBDIRS)
DIST_SUBDIRS = $(SUBDIRS) compatibility metar threads

View File

@@ -0,0 +1,43 @@
#ifndef __SGI_HXX
#define __SGI_HXX
#include <string>
inline bool
operator!=( const std::string& lhs, const char* rhs)
{
return lhs.compare( rhs ) != 0;
}
inline bool
operator!=( const char* lhs, const std::string& rhs)
{
return rhs.compare( lhs ) != 0;
}
inline bool
operator==( const std::string& lhs, const char* rhs)
{
return lhs.compare( rhs ) == 0;
}
inline bool
operator==( const char* lhs, const std::string& rhs)
{
return rhs.compare( lhs ) == 0;
}
inline std::string
operator+(const std::string& lhs, const char* rhs)
{
return lhs + std::string(rhs);
}
inline std::string
operator+(const char* lhs, const std::string& rhs)
{
return std::string(lhs) + rhs;
}
#endif // !__SGI_HXX

View File

@@ -28,4 +28,6 @@ include_HEADERS = \
ctime \
iomanip \
new \
streambuf
streambuf \
\
IRIX

View File

@@ -6,6 +6,8 @@
namespace std {
using ::setw;
inline int setfill(int f) { ::setfill(f); }
};
#endif // !__SG_IOMANIP

View File

@@ -31,7 +31,20 @@
using ::ostream;
using ::dec;
using ::oct;
using ::hex;
enum { skipws=ios::skipws,
left=ios::left, right=ios::right, internal=ios::internal,
showbase=ios::showbase, showpoint=ios::showpoint,
uppercase=ios::uppercase, showpos=ios::showpos,
scientific=ios::scientific, fixed=ios::fixed,
unitbuf=ios::unitbuf, stdio=ios::stdio
#if _BOOL && __EDG_ABI_COMPATIBILITY_VERSION>227 /* bool support */
,boolalpha=ios::boolalpha
#endif /* bool support */
};
};
# endif

View File

@@ -2,11 +2,21 @@
#ifndef __SG_SSTREAM
#define __SG_SSTREAM 1
# include <iostream>
# include <strstream>
# include <string>
namespace std {
typedef ::ostrstream ostringstream;
typedef ::istrstream istringstream;
class ostringstream : public ostrstream {
public:
std::string str() { return string(ostrstream::str()); }
};
class istringstream : public istrstream {
};
};
#endif // !__SG_SSTREAM

View File

@@ -290,6 +290,8 @@
#if defined ( sgi ) && !defined( __GNUC__ )
# define SG_HAVE_NATIVE_SGI_COMPILERS
#include <simgear/compatibility/IRIX>
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_CLASS_PARTIAL_SPECIALIZATION
# define SG_NEED_AUTO_PTR

View File

@@ -4,7 +4,7 @@ lib_LIBRARIES = libsgephem.a
include_HEADERS = \
celestialBody.hxx \
ephemeris.hxx \
ephemeris.hxx \
jupiter.hxx \
mars.hxx \
mercury.hxx \

View File

@@ -23,6 +23,8 @@
// $Id$
#include <iostream>
#include "ephemeris.hxx"
@@ -37,6 +39,10 @@ SGEphemeris::SGEphemeris( const string &path ) {
saturn = new Saturn;
uranus = new Uranus;
neptune = new Neptune;
nplanets = 7;
for ( int i = 0; i < nplanets; ++i ) {
sgdSetVec3( planets[i], 0.0, 0.0, 0.0 );
}
stars = new SGStarData( SGPath(path) );
}

View File

@@ -31,8 +31,9 @@ tcp_server_LDADD = \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz
-lplibnet -lplibul -lz \
$(network_LIBS) \
$(base_LIBS)
tcp_client_SOURCES = tcp_client.cxx
@@ -41,18 +42,20 @@ tcp_client_LDADD = \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz
-lplibnet -lplibul -lz \
$(network_LIBS) \
$(base_LIBS)
socktest_SOURCES = socktest.cxx
socktest_LDADD = \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lplibnet -lplibul -lz
-lplibnet -lplibul -lz \
$(network_LIBS) \
$(base_LIBS)
lowtest_SOURCES = lowtest.cxx
@@ -63,8 +66,7 @@ decode_binobj_SOURCES = decode_binobj.cxx
decode_binobj_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/xml/libsgxml.a \
-lz
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(base_LIBS) -lz

View File

@@ -54,7 +54,7 @@ SGSocket::SGSocket( const string& host, const string& port_,
{
is_tcp = true;
}
else if ( style != (string)"udp" )
else if ( style != "udp" )
{
SG_LOG( SG_IO, SG_ALERT,
"Error: SGSocket() unknown style = " << style );

View File

@@ -12,6 +12,8 @@ noinst_PROGRAMS = testmagvar
testmagvar_SOURCES = testmagvar.cxx
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
testmagvar_LDADD = \
$(top_builddir)/simgear/magvar/libsgmagvar.a \
$(base_LIBS)
INCLUDES = -I$(top_srcdir)

View File

@@ -12,7 +12,8 @@ include_HEADERS = \
sg_memory.h \
sg_random.h \
sg_types.hxx \
vector.hxx
vector.hxx \
fastmath.hxx
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
@@ -22,6 +23,7 @@ libsgmath_a_SOURCES = \
polar3d.cxx \
sg_geodesy.cxx \
sg_random.c \
vector.cxx
vector.cxx \
fastmath.cxx
INCLUDES = -I$(top_srcdir)

65
simgear/math/fastmath.cxx Normal file
View File

@@ -0,0 +1,65 @@
/*
* \file fastmath.cxx
* fast mathematics routines.
*
* Refferences:
*
* A Fast, Compact Approximation of the Exponential Function
* Nicol N. Schraudolph
* IDSIA, Lugano, Switzerland
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
*
* Fast log() Function, by Laurent de Soras:
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
*
*/
/*
* $Id$
*/
#include "fastmath.hxx"
/**
* This function is on avarage 9 times faster than the system exp() function
* and has an error of about 1.5%
*/
static union {
double d;
struct {
#if BYTE_ORDER == BIG_ENDIAN
int i, j;
#else
int j, i;
#endif
} n;
} _eco;
double fast_exp(double val) {
const double a = 1048576/M_LN2;
const double b_c = 1072632447; /* 1072693248 - 60801 */
_eco.n.i = a*val + b_c;
return _eco.d;
}
/**
* While we're on the subject, someone might have use for these as well?
* Float Shift Left and Float Shift Right. Do what you want with this.
*/
void fast_BSL(float &x, register unsigned long shiftAmount) {
*(unsigned long*)&x+=shiftAmount<<23;
}
void fast_BSR(float &x, register unsigned long shiftAmount) {
*(unsigned long*)&x-=shiftAmount<<23;
}

69
simgear/math/fastmath.hxx Normal file
View File

@@ -0,0 +1,69 @@
/*
* \file fastmath.hxx
* fast mathematics routines.
*
* Refferences:
*
* A Fast, Compact Approximation of the Exponential Function
* Nicol N. Schraudolph
* IDSIA, Lugano, Switzerland
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
*
* Fast log() Function, by Laurent de Soras:
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
*
*/
/*
* $Id$
*/
#ifndef _SG_FMATH_HXX
#define _SG_FMATH_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>
double fast_exp(double val);
void fast_BSL(float &x, register unsigned long shiftAmount);
void fast_BSR(float &x, register unsigned long shiftAmount);
inline float fast_log2 (float val)
{
int * const exp_ptr = reinterpret_cast <int *> (&val);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
val = ((-1.0f/3) * val + 2) * val - 2.0f/3; // (1)
return (val + log_2);
}
/**
* This function is about 3 times faster than the system log() function
* and has an error of about 0.01%
*/
inline float fast_log (const float &val)
{
return (fast_log2 (val) * 0.69314718f);
}
inline float fast_log10 (const float &val)
{
return (fast_log2(val) / 3.321928095f);
}
#endif // !_SG_FMATH_HXX

View File

@@ -88,9 +88,18 @@ int geo_direct_wgs_84 ( const double& alt, const double& lat1,
double *az2 );
// given alt, lat1, lon1, lat2, lon2, calculate starting and ending
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
// distance in meters
/**
* Given an altitude and two sets of (lat, lon) calculate great circle
* distance between them as well as the starting and ending azimuths.
* @param alt (in) meters
* @param lat1 (in) degrees
* @param lon1 (in) degrees
* @param lat2 (in) degrees
* @param lon2 (in) degrees
* @param az1 (out) start heading degrees
* @param az2 (out) end heading degrees
* @param s (out) distance meters
*/
int geo_inverse_wgs_84( const double& alt, const double& lat1,
const double& lon1, const double& lat2,
const double& lon2, double *az1, double *az2,

View File

@@ -4165,7 +4165,7 @@ static bool isPtendency(char *string, Decoded_METAR *Mptr, int *NDEX)
if(strlen(string) != 5)
return FALSE;
else if(*string == '5' && ('0' <= *(string+1) <= '8') &&
else if(*string == '5' && ('0' <= *(string+1) && *(string+1) <= '8') &&
(nisdigit(string+2,3) || strncmp(string+2,"///",3)
== 0) )
{

View File

@@ -1096,8 +1096,8 @@ bool ccap2std(char *, Devaddr *, Diskaddr *);
bool std2ccap(Devaddr *, Diskaddr *, char *);
char *strupr(char *);
char *strlwr(char *);
//char *strupr(char *);
//char *strlwr(char *);
//char *strdup(char *);
//int strcmpi(char *, char *);

View File

@@ -3,8 +3,6 @@ includedir = @includedir@/misc
lib_LIBRARIES = libsgmisc.a
include_HEADERS = \
commands.hxx \
exception.hxx \
sg_path.hxx \
sgstream.hxx \
stopwatch.hxx \
@@ -14,8 +12,6 @@ include_HEADERS = \
zfstream.hxx
libsgmisc_a_SOURCES = \
commands.cxx \
exception.cxx \
sg_path.cxx \
sgstream.cxx \
strutils.cxx \

View File

@@ -23,12 +23,33 @@
// $Id$
#include <simgear/compiler.h>
#include <simgear_config.h>
#include <stdio.h>
#include "sg_path.hxx"
/**
* define directory path separators
*/
#if defined( macintosh )
static const char sgDirPathSep = ':';
static const char sgDirPathSepBad = '/';
#else
static const char sgDirPathSep = '/';
static const char sgDirPathSepBad = ':';
#endif
#if defined( WIN32 )
static const char sgSearchPathSep = ';';
#else
static const char sgSearchPathSep = ':';
#endif
// If Unix, replace all ":" with "/". If MacOS, replace all "/" with
// ":" it should go without saying that neither of these characters
// should be used in file or directory names. In windoze, allow the
@@ -44,8 +65,8 @@ SGPath::fix()
continue;
}
#endif
if ( path[i] == SG_BAD_PATH_SEP ) {
path[i] = SG_PATH_SEP;
if ( path[i] == sgDirPathSepBad ) {
path[i] = sgDirPathSep;
}
}
}
@@ -83,8 +104,8 @@ void SGPath::append( const string& p ) {
if ( path.size() == 0 ) {
path = p;
} else {
if ( p[0] != SG_PATH_SEP ) {
path += SG_PATH_SEP;
if ( p[0] != sgDirPathSep ) {
path += sgDirPathSep;
}
path += p;
}
@@ -106,7 +127,7 @@ void SGPath::concat( const string& p ) {
// Get the file part of the path (everything after the last path sep)
string SGPath::file() const {
int index = path.rfind(SG_PATH_SEP);
int index = path.rfind(sgDirPathSep);
if (index >= 0) {
return path.substr(index + 1);
} else {
@@ -117,7 +138,7 @@ string SGPath::file() const {
// get the directory part of the path.
string SGPath::dir() const {
int index = path.rfind(SG_PATH_SEP);
int index = path.rfind(sgDirPathSep);
if (index >= 0) {
return path.substr(0, index);
} else {
@@ -153,3 +174,25 @@ bool SGPath::exists() const {
fclose(fp);
return true;
}
string_list sgPathSplit( const string &search_path ) {
string tmp = search_path;
string_list result;
result.clear();
bool done = false;
while ( !done ) {
int index = tmp.find(sgSearchPathSep);
if (index >= 0) {
result.push_back( tmp.substr(0, index) );
tmp = tmp.substr( index + 1 );
} else {
result.push_back( tmp );
done = true;
}
}
return result;
}

View File

@@ -31,21 +31,13 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <simgear/math/sg_types.hxx>
SG_USING_STD(string);
#ifdef macintosh
# define SG_PATH_SEP ':'
# define SG_BAD_PATH_SEP '/'
#else
# define SG_PATH_SEP '/'
# define SG_BAD_PATH_SEP ':'
#endif
/**
* A class to hide path separator difference across platforms and assist
* in managing file system path names.
@@ -141,6 +133,12 @@ private:
};
/**
* Split a directory search path into a vector of individual paths
*/
string_list sgPathSplit( const string &search_path );
#endif // _SG_PATH_HXX

View File

@@ -18,17 +18,17 @@ int main (int ac, char ** av)
SGTabbedValues tv(string1);
if (tv[0] != string("Hello")) {
if (tv[0] != "Hello") {
cerr << "failed to read string at index 0" << endl;
return 1;
}
if (tv[1] != string("World")) {
if (tv[1] != "World") {
cerr << "failed to read string at index 1" << endl;
return 1;
}
if (tv[2] != string("34")) {
if (tv[2] != "34") {
cerr << "failed to read string at index 2" << endl;
return 1;
}
@@ -61,7 +61,7 @@ int main (int ac, char ** av)
return 3;
}
if (tv[5] != string("There Is No Spoon")) {
if (tv[5] != "There Is No Spoon") {
cerr << "failed to read string at index 5 (got [" << tv[5] << "]" << endl;
return 1;
}

View File

@@ -140,8 +140,15 @@ enter this in the official comments in case I forget again. :-)
*/
#include <simgear/compiler.h>
// #include STL_IOSTREAM
#include "texcoord.hxx"
// SG_USING_STD(cout);
// SG_USING_STD(endl);
#define FG_STANDARD_TEXTURE_DIMENSION 1000.0 // meters
#define MAX_TEX_COORD 8.0
@@ -149,9 +156,10 @@ enter this in the official comments in case I forget again. :-)
// return the basic unshifted/unmoded texture coordinate for a lat/lon
inline Point3D basic_tex_coord( const Point3D& p,
double degree_width, double degree_height,
double scale )
static inline Point3D basic_tex_coord( const Point3D& p,
double degree_width,
double degree_height,
double scale )
{
return Point3D( p.x() * ( degree_width * scale /
FG_STANDARD_TEXTURE_DIMENSION ),
@@ -163,7 +171,7 @@ inline Point3D basic_tex_coord( const Point3D& p,
// traverse the specified fan/strip/list of vertices and attempt to
// calculate "none stretching" texture coordinates
point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
point_list sgCalcTexCoords( const SGBucket& b, const point_list& geod_nodes,
const int_list& fan, double scale )
{
// cout << "calculating texture coordinates for a specific fan of size = "

View File

@@ -47,7 +47,7 @@
* @param scale (default = 1.0) scaling factor
* @return list of texture coordinates
*/
point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
point_list sgCalcTexCoords( const SGBucket& b, const point_list& geod_nodes,
const int_list& fan, double scale = 1.0 );

View File

@@ -10,7 +10,7 @@ include_HEADERS = \
libsgprops_a_SOURCES = \
condition.cxx \
props.cxx \
props_io.cxx
props_io.cxx
noinst_PROGRAMS = props_test
@@ -19,6 +19,7 @@ props_test_LDADD = \
$(top_builddir)/simgear/props/libsgprops.a \
$(top_builddir)/simgear/xml/libsgxml.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/debug/libsgdebug.a
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/structure/libsgstructure.a
INCLUDES = -I$(top_srcdir)

View File

@@ -13,10 +13,9 @@
// #include STL_IOSTREAM
#include <simgear/misc/exception.hxx>
#include <simgear/structure/exception.hxx>
#include "props.hxx"
#include "condition.hxx"
SG_USING_STD(istream);

View File

@@ -113,7 +113,7 @@ parse_name (const string &path, int &i)
name = ".";
}
if (i < max && path[i] != '/')
throw string(string("Illegal character after ") + name);
throw string("Illegal character after " + name);
}
else if (isalpha(path[i]) || path[i] == '_') {

View File

@@ -117,9 +117,9 @@ checkFlag (const char * flag, bool defaultState = true)
{
if (flag == 0)
return defaultState;
else if (string(flag) == "y")
else if (!strcmp(flag, "y"))
return true;
else if (string(flag) == "n")
else if (!strcmp(flag, "n"))
return false;
else {
string message = "Unrecognized flag value '";
@@ -137,7 +137,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
const char * attval;
if (_level == 0) {
if (string(name) != (string)"PropertyList") {
if (strcmp(name, "PropertyList")) {
string message = "Root element name is ";
message += name;
message += "; expected PropertyList";

View File

@@ -19,7 +19,7 @@ waytest_LDADD = \
$(top_builddir)/simgear/math/libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
$(base_LIBS) \
-lz
routetest_SOURCES = routetest.cxx
@@ -27,4 +27,5 @@ routetest_SOURCES = routetest.cxx
routetest_LDADD = \
$(top_builddir)/simgear/route/libsgroute.a \
$(top_builddir)/simgear/math/libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a
$(top_builddir)/simgear/debug/libsgdebug.a \
$(base_LIBS)

View File

@@ -127,27 +127,28 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
mipmap = props->getBoolValue("mipmap", true);
light_coverage = props->getDoubleValue("light-coverage", 0.0);
ambient[0] = props->getDoubleValue("ambient/r", 0.0);
ambient[1] = props->getDoubleValue("ambient/g", 0.0);
ambient[2] = props->getDoubleValue("ambient/b", 0.0);
ambient[3] = props->getDoubleValue("ambient/a", 0.0);
// Taken from default values as used in ac3d
ambient[0] = props->getDoubleValue("ambient/r", 0.2);
ambient[1] = props->getDoubleValue("ambient/g", 0.2);
ambient[2] = props->getDoubleValue("ambient/b", 0.2);
ambient[3] = props->getDoubleValue("ambient/a", 1.0);
diffuse[0] = props->getDoubleValue("diffuse/r", 0.0);
diffuse[1] = props->getDoubleValue("diffuse/g", 0.0);
diffuse[2] = props->getDoubleValue("diffuse/b", 0.0);
diffuse[3] = props->getDoubleValue("diffuse/a", 0.0);
diffuse[0] = props->getDoubleValue("diffuse/r", 0.8);
diffuse[1] = props->getDoubleValue("diffuse/g", 0.8);
diffuse[2] = props->getDoubleValue("diffuse/b", 0.8);
diffuse[3] = props->getDoubleValue("diffuse/a", 1.0);
specular[0] = props->getDoubleValue("specular/r", 0.0);
specular[1] = props->getDoubleValue("specular/g", 0.0);
specular[2] = props->getDoubleValue("specular/b", 0.0);
specular[3] = props->getDoubleValue("specular/a", 0.0);
specular[3] = props->getDoubleValue("specular/a", 1.0);
emission[0] = props->getDoubleValue("emissive/r", 0.0);
emission[1] = props->getDoubleValue("emissive/g", 0.0);
emission[2] = props->getDoubleValue("emissive/b", 0.0);
emission[3] = props->getDoubleValue("emissive/a", 0.0);
emission[3] = props->getDoubleValue("emissive/a", 1.0);
shininess = props->getDoubleValue("shininess", 0.0);
shininess = props->getDoubleValue("shininess", 1.0);
vector<SGPropertyNode_ptr> object_group_nodes =
((SGPropertyNode *)props)->getChildren("object-group");
@@ -174,9 +175,12 @@ SGMaterial::init ()
light_coverage = 0.0;
texture_loaded = false;
refcount = 0;
shininess = 0.0;
shininess = 1.0;
for (int i = 0; i < 4; i++) {
ambient[i] = diffuse[i] = specular[i] = emission[i] = 0.0;
ambient[i] = (i < 3) ? 0.2 : 1.0;
specular[i] = (i < 3) ? 0.0 : 1.0;
diffuse[i] = (i < 3) ? 0.8 : 1.0;
emission[i] = (i < 3) ? 0.0 : 1.0;
}
}
@@ -218,11 +222,6 @@ SGMaterial::build_ssg_state( bool defer_tex_load )
texture_loaded = false;
}
state->enable( GL_COLOR_MATERIAL );
#if 0
state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
#else
state->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
@@ -236,7 +235,6 @@ SGMaterial::build_ssg_state( bool defer_tex_load )
emission[0], emission[1],
emission[2], emission[3] ) ;
state->setShininess ( shininess );
#endif
}

View File

@@ -33,11 +33,11 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/gl.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/misc/exception.hxx>
#include <simgear/structure/exception.hxx>
#include <string.h>
#include STL_STRING
@@ -421,7 +421,7 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath ) {
= new SGMaterial( rwy_red_medium_lights );
// hard coded low intensity runway red light state
tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
rwy_red_low_lights->ref();
rwy_red_low_lights->disable( GL_LIGHTING );
@@ -475,7 +475,7 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath ) {
= new SGMaterial( rwy_green_medium_lights );
// hard coded low intensity runway green light state
tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
rwy_green_low_lights->ref();
rwy_green_low_lights->disable( GL_LIGHTING );
@@ -491,6 +491,8 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath ) {
rwy_green_low_lights->setTexture( tex_name );
matlib["RWY_GREEN_LOW_LIGHTS"]
= new SGMaterial( rwy_green_low_lights );
matlib["RWY_GREEN_TAXIWAY_LIGHTS"]
= new SGMaterial( rwy_green_low_lights );
// hard coded low intensity taxiway blue light state
tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );

View File

@@ -1,10 +1,11 @@
// animation.hxx - classes to manage model animation.
// animation.cxx - classes to manage model animation.
// Written by David Megginson, started 2002.
//
// This file is in the Public Domain, and comes with no warranty.
#include <string.h> // for strcmp()
#include <math.h>
#include <plib/sg.h>
#include <plib/ssg.h>
@@ -78,6 +79,71 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
sgMakeTransMat4(matrix, xyz);
}
/**
* Set up the transform matrix for a scale operation.
*/
static void
set_scale (sgMat4 &matrix, double x, double y, double z)
{
sgMakeIdentMat4( matrix );
matrix[0][0] = x;
matrix[1][1] = y;
matrix[2][2] = z;
}
/**
* Recursively process all kids to change the alpha values
*/
static void
change_alpha( ssgBase *_branch, float _blend )
{
int i;
for (i = 0; i < ((ssgBranch *)_branch)->getNumKids(); i++)
change_alpha( ((ssgBranch *)_branch)->getKid(i), _blend );
if ( strcmp("ssgLeaf", _branch->getTypeName()) &&
strcmp("ssgVtxTable", _branch->getTypeName()) &&
strcmp("ssgVTable", _branch->getTypeName()) )
return;
int num_colors = ((ssgLeaf *)_branch)->getNumColours();
for (i = 0; i < num_colors; i++)
{
float *color = ((ssgLeaf *)_branch)->getColour(i);
color[3] = _blend;
}
}
/**
* Modify property value by step and scroll settings in texture translations
*/
static double
apply_mods(double property, double step, double scroll)
{
double modprop;
if(step > 0) {
double scrollval = 0.0;
if(scroll > 0) {
// calculate scroll amount (for odometer like movement)
double remainder = step - fmod(fabs(property), step);
if (remainder < scroll) {
scrollval = (scroll - remainder) / scroll * step;
}
}
// apply stepping of input value
if(property > 0)
modprop = ((floor(property/step) * step) + scrollval);
else
modprop = ((ceil(property/step) * step) + scrollval);
} else {
modprop = property;
}
return modprop;
}
/**
* Read an interpolation table from properties.
@@ -148,19 +214,55 @@ SGNullAnimation::~SGNullAnimation ()
// Implementation of SGRangeAnimation
////////////////////////////////////////////////////////////////////////
SGRangeAnimation::SGRangeAnimation (SGPropertyNode_ptr props)
: SGAnimation(props, new ssgRangeSelector)
SGRangeAnimation::SGRangeAnimation (SGPropertyNode *prop_root,
SGPropertyNode_ptr props)
: SGAnimation(props, new ssgRangeSelector),
_min(0.0), _max(0.0)
{
float ranges[] = { props->getFloatValue("min-m", 0),
props->getFloatValue("max-m", 5000) };
float ranges[2];
SGPropertyNode_ptr node = props->getChild( "min-property" );
if (node != 0) {
_min_prop = (SGPropertyNode *)prop_root->getNode(node->getStringValue(), true);
ranges[0] = _min_prop->getFloatValue();
} else {
ranges[0] = _min = props->getFloatValue("min-m", 0);
}
node = props->getChild( "max-property" );
if (node != 0) {
_max_prop = (SGPropertyNode *)prop_root->getNode(node->getStringValue(), true);
ranges[1] = _max_prop->getFloatValue();
} else {
ranges[1] = _max = props->getFloatValue("max-m", 0);
}
((ssgRangeSelector *)_branch)->setRanges(ranges, 2);
}
SGRangeAnimation::~SGRangeAnimation ()
{
}
void
SGRangeAnimation::update()
{
float ranges[2];
bool upd = false;
if (_min_prop != 0) {
ranges[0] = _min_prop->getFloatValue();
upd = true;
} else {
ranges[0] = _min;
}
if (_max_prop != 0) {
ranges[1] = _max_prop->getFloatValue();
upd = true;
} else {
ranges[1] = _max;
}
if (upd)
((ssgRangeSelector *)_branch)->setRanges(ranges, 2);
}
////////////////////////////////////////////////////////////////////////
@@ -221,12 +323,34 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root,
_position_deg(props->getDoubleValue("starting-position-deg", 0)),
_last_time_sec( sim_time_sec )
{
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
_center[0] = 0;
_center[1] = 0;
_center[2] = 0;
if (props->hasValue("axis/x1-m")) {
double x1,y1,z1,x2,y2,z2;
x1 = props->getFloatValue("axis/x1-m");
y1 = props->getFloatValue("axis/y1-m");
z1 = props->getFloatValue("axis/z1-m");
x2 = props->getFloatValue("axis/x2-m");
y2 = props->getFloatValue("axis/y2-m");
z2 = props->getFloatValue("axis/z2-m");
_center[0] = (x1+x2)/2;
_center[1]= (y1+y2)/2;
_center[2] = (z1+z2)/2;
float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
_axis[0] = (x2-x1)/vector_length;
_axis[1] = (y2-y1)/vector_length;
_axis[2] = (z2-z1)/vector_length;
} else {
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
}
if (props->hasValue("center/x-m")) {
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
}
sgNormalizeVec3(_axis);
}
@@ -299,13 +423,35 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root,
_max_deg(props->getDoubleValue("max-deg")),
_position_deg(props->getDoubleValue("starting-position-deg", 0))
{
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
_center[0] = 0;
_center[1] = 0;
_center[2] = 0;
if (props->hasValue("axis/x1-m")) {
double x1,y1,z1,x2,y2,z2;
x1 = props->getFloatValue("axis/x1-m");
y1 = props->getFloatValue("axis/y1-m");
z1 = props->getFloatValue("axis/z1-m");
x2 = props->getFloatValue("axis/x2-m");
y2 = props->getFloatValue("axis/y2-m");
z2 = props->getFloatValue("axis/z2-m");
_center[0] = (x1+x2)/2;
_center[1]= (y1+y2)/2;
_center[2] = (z1+z2)/2;
float vector_length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
_axis[0] = (x2-x1)/vector_length;
_axis[1] = (y2-y1)/vector_length;
_axis[2] = (z2-z1)/vector_length;
} else {
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
}
if (props->hasValue("center/x-m")) {
_center[0] = props->getFloatValue("center/x-m", 0);
_center[1] = props->getFloatValue("center/y-m", 0);
_center[2] = props->getFloatValue("center/z-m", 0);
}
sgNormalizeVec3(_axis);
}
SGRotateAnimation::~SGRotateAnimation ()
@@ -329,6 +475,53 @@ SGRotateAnimation::update()
((ssgTransform *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGBlendAnimation
////////////////////////////////////////////////////////////////////////
SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTransform),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_offset(props->getDoubleValue("offset", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_table(read_interpolation_table(props)),
_has_min(props->hasValue("min")),
_min(props->getDoubleValue("min", 0.0)),
_has_max(props->hasValue("max")),
_max(props->getDoubleValue("max", 1.0)),
_prev_value(1.0)
{
}
SGBlendAnimation::~SGBlendAnimation ()
{
delete _table;
}
void
SGBlendAnimation::update()
{
double _blend;
if (_table == 0) {
_blend = 1.0 - (_prop->getDoubleValue() * _factor + _offset);
if (_has_min && (_blend < _min))
_blend = _min;
if (_has_max && (_blend > _max))
_blend = _max;
} else {
_blend = _table->interpolate(_prop->getDoubleValue());
}
if (_blend != _prev_value) {
_prev_value = _blend;
change_alpha( _branch, _blend );
}
}
////////////////////////////////////////////////////////////////////////
@@ -376,4 +569,289 @@ SGTranslateAnimation::update()
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGScaleAnimation
////////////////////////////////////////////////////////////////////////
SGScaleAnimation::SGScaleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTransform),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_x_factor(props->getDoubleValue("x-factor", 1.0)),
_y_factor(props->getDoubleValue("y-factor", 1.0)),
_z_factor(props->getDoubleValue("z-factor", 1.0)),
_x_offset(props->getDoubleValue("x-offset", 1.0)),
_y_offset(props->getDoubleValue("y-offset", 1.0)),
_z_offset(props->getDoubleValue("z-offset", 1.0)),
_table(read_interpolation_table(props)),
_has_min_x(props->hasValue("x-min")),
_has_min_y(props->hasValue("y-min")),
_has_min_z(props->hasValue("z-min")),
_min_x(props->getDoubleValue("x-min")),
_min_y(props->getDoubleValue("y-min")),
_min_z(props->getDoubleValue("z-min")),
_has_max_x(props->hasValue("x-max")),
_has_max_y(props->hasValue("y-max")),
_has_max_z(props->hasValue("z-max")),
_max_x(props->getDoubleValue("x-max")),
_max_y(props->getDoubleValue("y-max")),
_max_z(props->getDoubleValue("z-max"))
{
}
SGScaleAnimation::~SGScaleAnimation ()
{
delete _table;
}
void
SGScaleAnimation::update()
{
if (_table == 0) {
_x_scale = _prop->getDoubleValue() * _x_factor + _x_offset;
if (_has_min_x && _x_scale < _min_x)
_x_scale = _min_x;
if (_has_max_x && _x_scale > _max_x)
_x_scale = _max_x;
} else {
_x_scale = _table->interpolate(_prop->getDoubleValue());
}
if (_table == 0) {
_y_scale = _prop->getDoubleValue() * _y_factor + _y_offset;
if (_has_min_y && _y_scale < _min_y)
_y_scale = _min_y;
if (_has_max_y && _y_scale > _max_y)
_y_scale = _max_y;
} else {
_y_scale = _table->interpolate(_prop->getDoubleValue());
}
if (_table == 0) {
_z_scale = _prop->getDoubleValue() * _z_factor + _z_offset;
if (_has_min_z && _z_scale < _min_z)
_z_scale = _min_z;
if (_has_max_z && _z_scale > _max_z)
_z_scale = _max_z;
} else {
_z_scale = _table->interpolate(_prop->getDoubleValue());
}
set_scale(_matrix, _x_scale, _y_scale, _z_scale );
((ssgTransform *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexRotateAnimation
////////////////////////////////////////////////////////////////////////
SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_offset_deg(props->getDoubleValue("offset-deg", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_table(read_interpolation_table(props)),
_has_min(props->hasValue("min-deg")),
_min_deg(props->getDoubleValue("min-deg")),
_has_max(props->hasValue("max-deg")),
_max_deg(props->getDoubleValue("max-deg")),
_position_deg(props->getDoubleValue("starting-position-deg", 0))
{
_center[0] = props->getFloatValue("center/x", 0);
_center[1] = props->getFloatValue("center/y", 0);
_center[2] = props->getFloatValue("center/z", 0);
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
}
SGTexRotateAnimation::~SGTexRotateAnimation ()
{
delete _table;
}
void
SGTexRotateAnimation::update()
{
if (_table == 0) {
_position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
if (_has_min && _position_deg < _min_deg)
_position_deg = _min_deg;
if (_has_max && _position_deg > _max_deg)
_position_deg = _max_deg;
} else {
_position_deg = _table->interpolate(_prop->getDoubleValue());
}
set_rotation(_matrix, _position_deg, _center, _axis);
((ssgTexTrans *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexTranslateAnimation
////////////////////////////////////////////////////////////////////////
SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
_offset(props->getDoubleValue("offset", 0.0)),
_factor(props->getDoubleValue("factor", 1.0)),
_step(props->getDoubleValue("step",0.0)),
_scroll(props->getDoubleValue("scroll",0.0)),
_table(read_interpolation_table(props)),
_has_min(props->hasValue("min")),
_min(props->getDoubleValue("min")),
_has_max(props->hasValue("max")),
_max(props->getDoubleValue("max")),
_position(props->getDoubleValue("starting-position", 0))
{
_axis[0] = props->getFloatValue("axis/x", 0);
_axis[1] = props->getFloatValue("axis/y", 0);
_axis[2] = props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_axis);
}
SGTexTranslateAnimation::~SGTexTranslateAnimation ()
{
delete _table;
}
void
SGTexTranslateAnimation::update()
{
if (_table == 0) {
_position = (apply_mods(_prop->getDoubleValue(), _step, _scroll) + _offset) * _factor;
if (_has_min && _position < _min)
_position = _min;
if (_has_max && _position > _max)
_position = _max;
} else {
_position = _table->interpolate(apply_mods(_prop->getDoubleValue(), _step, _scroll));
}
set_translation(_matrix, _position, _axis);
((ssgTexTrans *)_branch)->setTransform(_matrix);
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGTexMultipleAnimation
////////////////////////////////////////////////////////////////////////
SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props )
: SGAnimation(props, new ssgTexTrans),
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true))
{
unsigned int i;
// Load animations
vector<SGPropertyNode_ptr> transform_nodes = props->getChildren("transform");
_transform = new TexTransform [transform_nodes.size()];
_num_transforms = 0;
for (i = 0; i < transform_nodes.size(); i++) {
SGPropertyNode_ptr transform_props = transform_nodes[i];
if (!strcmp("textranslate",transform_props->getStringValue("subtype", 0))) {
// transform is a translation
_transform[i].subtype = 0;
_transform[i].prop = (SGPropertyNode *)prop_root->getNode(transform_props->getStringValue("property", "/null"), true);
_transform[i].offset = transform_props->getDoubleValue("offset", 0.0);
_transform[i].factor = transform_props->getDoubleValue("factor", 1.0);
_transform[i].step = transform_props->getDoubleValue("step",0.0);
_transform[i].scroll = transform_props->getDoubleValue("scroll",0.0);
_transform[i].table = read_interpolation_table(transform_props);
_transform[i].has_min = transform_props->hasValue("min");
_transform[i].min = transform_props->getDoubleValue("min");
_transform[i].has_max = transform_props->hasValue("max");
_transform[i].max = transform_props->getDoubleValue("max");
_transform[i].position = transform_props->getDoubleValue("starting-position", 0);
_transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0);
_transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0);
_transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_transform[i].axis);
_num_transforms++;
} else if (!strcmp("texrotate",transform_nodes[i]->getStringValue("subtype", 0))) {
// transform is a rotation
_transform[i].subtype = 1;
_transform[i].prop = (SGPropertyNode *)prop_root->getNode(transform_props->getStringValue("property", "/null"), true);
_transform[i].offset = transform_props->getDoubleValue("offset-deg", 0.0);
_transform[i].factor = transform_props->getDoubleValue("factor", 1.0);
_transform[i].table = read_interpolation_table(transform_props);
_transform[i].has_min = transform_props->hasValue("min-deg");
_transform[i].min = transform_props->getDoubleValue("min-deg");
_transform[i].has_max = transform_props->hasValue("max-deg");
_transform[i].max = transform_props->getDoubleValue("max-deg");
_transform[i].position = transform_props->getDoubleValue("starting-position-deg", 0);
_transform[i].center[0] = transform_props->getFloatValue("center/x", 0);
_transform[i].center[1] = transform_props->getFloatValue("center/y", 0);
_transform[i].center[2] = transform_props->getFloatValue("center/z", 0);
_transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0);
_transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0);
_transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0);
sgNormalizeVec3(_transform[i].axis);
_num_transforms++;
}
}
}
SGTexMultipleAnimation::~SGTexMultipleAnimation ()
{
// delete _table;
delete _transform;
}
void
SGTexMultipleAnimation::update()
{
int i;
sgMat4 tmatrix;
sgMakeIdentMat4(tmatrix);
for (i = 0; i < _num_transforms; i++) {
if(_transform[i].subtype == 0) {
// subtype 0 is translation
if (_transform[i].table == 0) {
_transform[i].position = (apply_mods(_transform[i].prop->getDoubleValue(), _transform[i].step,_transform[i].scroll) + _transform[i].offset) * _transform[i].factor;
if (_transform[i].has_min && _transform[i].position < _transform[i].min)
_transform[i].position = _transform[i].min;
if (_transform[i].has_max && _transform[i].position > _transform[i].max)
_transform[i].position = _transform[i].max;
} else {
_transform[i].position = _transform[i].table->interpolate(apply_mods(_transform[i].prop->getDoubleValue(), _transform[i].step,_transform[i].scroll));
}
set_translation(_transform[i].matrix, _transform[i].position, _transform[i].axis);
sgPreMultMat4(tmatrix, _transform[i].matrix);
} else if (_transform[i].subtype == 1) {
// subtype 1 is rotation
if (_transform[i].table == 0) {
_transform[i].position = _transform[i].prop->getDoubleValue() * _transform[i].factor + _transform[i].offset;
if (_transform[i].has_min && _transform[i].position < _transform[i].min)
_transform[i].position = _transform[i].min;
if (_transform[i].has_max && _transform[i].position > _transform[i].max)
_transform[i].position = _transform[i].max;
} else {
_transform[i].position = _transform[i].table->interpolate(_transform[i].prop->getDoubleValue());
}
set_rotation(_transform[i].matrix, _transform[i].position, _transform[i].center, _transform[i].axis);
sgPreMultMat4(tmatrix, _transform[i].matrix);
}
}
((ssgTexTrans *)_branch)->setTransform(tmatrix);
}
// end of animation.cxx

View File

@@ -1,3 +1,4 @@
// animation.hxx - classes to manage model animation.
// Written by David Megginson, started 2002.
//
@@ -98,8 +99,15 @@ public:
class SGRangeAnimation : public SGAnimation
{
public:
SGRangeAnimation (SGPropertyNode_ptr props);
SGRangeAnimation (SGPropertyNode *prop_root,
SGPropertyNode_ptr props);
virtual ~SGRangeAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _min_prop;
SGPropertyNode_ptr _max_prop;
float _min;
float _max;
};
@@ -220,5 +228,155 @@ private:
sgVec3 _axis;
};
/**
* Animation to blend an object.
*/
class SGBlendAnimation : public SGAnimation
{
public:
SGBlendAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGBlendAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
SGInterpTable * _table;
double _prev_value;
double _offset;
double _factor;
bool _has_min;
double _min;
bool _has_max;
double _max;
};
/**
* Animation to scale an object.
*/
class SGScaleAnimation : public SGAnimation
{
public:
SGScaleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGScaleAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _x_factor;
double _y_factor;
double _z_factor;
double _x_offset;
double _y_offset;
double _z_offset;
SGInterpTable * _table;
bool _has_min_x;
bool _has_min_y;
bool _has_min_z;
double _min_x;
double _min_y;
double _min_z;
bool _has_max_x;
bool _has_max_y;
bool _has_max_z;
double _max_x;
double _max_y;
double _max_z;
double _x_scale;
double _y_scale;
double _z_scale;
sgMat4 _matrix;
};
/**
* Animation to rotate texture mappings around a center point.
*
* This animation rotates to a specific position.
*/
class SGTexRotateAnimation : public SGAnimation
{
public:
SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props );
virtual ~SGTexRotateAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _offset_deg;
double _factor;
SGInterpTable * _table;
bool _has_min;
double _min_deg;
bool _has_max;
double _max_deg;
double _position_deg;
sgMat4 _matrix;
sgVec3 _center;
sgVec3 _axis;
};
/**
* Animation to slide texture mappings along an axis.
*/
class SGTexTranslateAnimation : public SGAnimation
{
public:
SGTexTranslateAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGTexTranslateAnimation ();
virtual void update();
private:
SGPropertyNode_ptr _prop;
double _offset;
double _factor;
double _step;
double _scroll;
SGInterpTable * _table;
bool _has_min;
double _min;
bool _has_max;
double _max;
double _position;
sgMat4 _matrix;
sgVec3 _axis;
};
/**
* Classes for handling multiple types of Texture translations on one object
*/
class SGTexMultipleAnimation : public SGAnimation
{
public:
SGTexMultipleAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGTexMultipleAnimation ();
virtual void update();
private:
class TexTransform
{
public:
SGPropertyNode_ptr prop;
int subtype; // 0=translation, 1=rotation
double offset;
double factor;
double step;
double scroll;
SGInterpTable * table;
bool has_min;
double min;
bool has_max;
double max;
double position;
sgMat4 matrix;
sgVec3 center;
sgVec3 axis;
};
SGPropertyNode_ptr _prop;
TexTransform* _transform;
int _num_transforms;
};
#endif // _SG_ANIMATION_HXX

View File

@@ -17,13 +17,12 @@
#include <plib/ssg.h>
#include <plib/ul.h>
#include <simgear/misc/exception.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include "animation.hxx"
#include "model.hxx"
SG_USING_STD(vector);
@@ -108,7 +107,7 @@ sgMakeAnimation( ssgBranch * model,
if (!strcmp("none", type)) {
animation = new SGNullAnimation(node);
} else if (!strcmp("range", type)) {
animation = new SGRangeAnimation(node);
animation = new SGRangeAnimation(prop_root, node);
} else if (!strcmp("billboard", type)) {
animation = new SGBillboardAnimation(node);
} else if (!strcmp("select", type)) {
@@ -121,6 +120,16 @@ sgMakeAnimation( ssgBranch * model,
animation = new SGRotateAnimation(prop_root, node);
} else if (!strcmp("translate", type)) {
animation = new SGTranslateAnimation(prop_root, node);
} else if (!strcmp("scale", type)) {
animation = new SGScaleAnimation(prop_root, node);
} else if (!strcmp("texrotate", type)) {
animation = new SGTexRotateAnimation(prop_root, node);
} else if (!strcmp("textranslate", type)) {
animation = new SGTexTranslateAnimation(prop_root, node);
} else if (!strcmp("texmultiple", type)) {
animation = new SGTexMultipleAnimation(prop_root, node);
} else if (!strcmp("blend", type)) {
animation = new SGBlendAnimation(prop_root, node);
} else {
animation = new SGNullAnimation(node);
SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);
@@ -179,19 +188,16 @@ sgLoad3DModel( const string &fg_root, const string &path,
SGPropertyNode props;
// Load the 3D aircraft object itself
SGPath xmlpath;
SGPath modelpath = path;
if ( ulIsAbsolutePathName( path.c_str() ) ) {
xmlpath = modelpath;
}
else {
xmlpath = fg_root;
xmlpath.append(modelpath.str());
if ( !ulIsAbsolutePathName( path.c_str() ) ) {
SGPath tmp = fg_root;
tmp.append(modelpath.str());
modelpath = tmp;
}
// Check for an XML wrapper
if (xmlpath.str().substr(xmlpath.str().size() - 4, 4) == ".xml") {
readProperties(xmlpath.str(), &props);
if (modelpath.str().substr(modelpath.str().size() - 4, 4) == ".xml") {
readProperties(modelpath.str(), &props);
if (props.hasValue("/path")) {
modelpath = modelpath.dir();
modelpath.append(props.getStringValue("/path"));
@@ -204,7 +210,7 @@ sgLoad3DModel( const string &fg_root, const string &path,
// Assume that textures are in
// the same location as the XML file.
if (model == 0) {
ssgTexturePath((char *)xmlpath.dir().c_str());
ssgTexturePath((char *)modelpath.dir().c_str());
model = (ssgBranch *)ssgLoad((char *)modelpath.c_str());
if (model == 0)
throw sg_exception("Failed to load 3D model");

View File

@@ -1,6 +1,6 @@
includedir = @includedir@/scene/sky
# SUBDIRS = clouds3d
SUBDIRS = clouds3d
lib_LIBRARIES = libsgsky.a

View File

@@ -48,6 +48,8 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) :
layer_transition(0.0),
layer_coverage(SG_CLOUD_CLEAR),
scale(4000.0),
speed(0.0),
direction(0.0),
last_lon(0.0),
last_lat(0.0)
{
@@ -88,9 +90,16 @@ SGCloudLayer::getElevation_m () const
}
void
SGCloudLayer::setElevation_m (float elevation_m)
SGCloudLayer::setElevation_m (float elevation_m, bool set_span)
{
layer_asl = elevation_m;
if (set_span) {
if (elevation_m > 4000)
setSpan_m( elevation_m * 10 );
else
setSpan_m( 40000 );
}
}
float
@@ -185,6 +194,7 @@ SGCloudLayer::rebuild()
const float layer_scale = layer_span / scale;
const float mpi = SG_PI/4;
const float alt_diff = layer_asl * 0.8;
for (int i = 0; i < 4; i++)
{
@@ -198,7 +208,7 @@ SGCloudLayer::rebuild()
sgSetVec3( vertex, layer_span*(i-2)/2, -layer_span,
500 * (sin(i*mpi) - 2) );
alt_diff * (sin(i*mpi) - 2) );
sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] );
@@ -211,7 +221,7 @@ SGCloudLayer::rebuild()
for (int j = 0; j < 4; j++)
{
sgSetVec3( vertex, layer_span*(i-1)/2, layer_span*(j-2)/2,
500 * (sin((i+1)*mpi) + sin(j*mpi) - 2) );
alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2) );
sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
base[1] + layer_scale * j/4 );
@@ -226,7 +236,7 @@ SGCloudLayer::rebuild()
sgSetVec3( vertex, layer_span*(i-2)/2, layer_span*(j-1)/2,
500 * (sin(i*mpi) + sin((j+1)*mpi) - 2) );
alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2) );
sgSetVec2( tc, base[0] + layer_scale * i/4,
base[1] + layer_scale * (j+1)/4 );
@@ -240,7 +250,7 @@ SGCloudLayer::rebuild()
}
sgSetVec3( vertex, layer_span*(i-1)/2, layer_span,
500 * (sin((i+1)*mpi) - 2) );
alt_diff * (sin((i+1)*mpi) - 2) );
sgSetVec2( tc, base[0] + layer_scale * (i+1)/4,
base[1] + layer_scale );
@@ -285,7 +295,7 @@ bool SGCloudLayer::repaint( sgVec3 fog_color ) {
// spin specifies a rotation about the new Z axis (and orients the
// sunrise/set effects
bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
double alt )
double alt, double dt )
{
sgMat4 T1, LON, LAT;
sgVec3 axis;
@@ -343,15 +353,35 @@ bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
last_lat = lat;
}
if ( lon != last_lon || lat != last_lat ) {
double sp_dist = speed*dt;
if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) {
Point3D start( last_lon, last_lat, 0.0 );
Point3D dest( lon, lat, 0.0 );
double course, dist;
calc_gc_course_dist( dest, start, &course, &dist );
double course = 0.0, dist = 0.0;
if (dest != start) {
calc_gc_course_dist( dest, start, &course, &dist );
}
// cout << "course = " << course << ", dist = " << dist << endl;
double xoff = cos( course ) * dist / (2 * scale);
double yoff = sin( course ) * dist / (2 * scale);
// calculate cloud movement due to external forces
double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0;
if (dist > 0.0) {
ax = cos(course) * dist;
ay = sin(course) * dist;
}
if (sp_dist > 0) {
bx = cos(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
by = sin(-direction * SGD_DEGREES_TO_RADIANS) * sp_dist;
}
double xoff = (ax + bx) / (2 * scale);
double yoff = (ay + by) / (2 * scale);
const float layer_scale = layer_span / scale;
@@ -438,8 +468,10 @@ ssgSimpleState *sgCloudMakeState( const string &path ) {
state->enable( GL_TEXTURE_2D );
state->enable( GL_COLOR_MATERIAL );
state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
state->setMaterial( GL_EMISSION, 0.05, 0.05, 0.05, 0.0 );
state->setMaterial( GL_AMBIENT, 0.2, 0.2, 0.2, 0.0 );
state->setMaterial( GL_DIFFUSE, 0.5, 0.5, 0.5, 0.0 );
state->setMaterial( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
state->enable( GL_BLEND );
state->enable( GL_ALPHA_TEST );
state->setAlphaClamp( 0.01 );

View File

@@ -1,5 +1,8 @@
// cloud.hxx -- model a single cloud layer
//
/**
* \file cloud.hxx
* Provides a class to model a single cloud layer
*/
// Written by Curtis Olson, started June 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
@@ -33,10 +36,15 @@
SG_USING_STD(string);
/**
* A class layer to model a single cloud layer
*/
class SGCloudLayer {
public:
/**
* This is the list of available cloud coverages/textures
*/
enum Coverage {
SG_CLOUD_OVERCAST = 0,
SG_CLOUD_BROKEN,
@@ -47,48 +55,108 @@ public:
SG_MAX_CLOUD_COVERAGES
};
// Constructors
/**
* Constructor
* @param tex_path the path to the set of cloud textures
*/
SGCloudLayer( const string &tex_path );
// Destructor
/**
* Destructor
*/
~SGCloudLayer( void );
/** get the cloud span (in meters) */
float getSpan_m () const;
/**
* set the cloud span
* @param span_m the cloud span in meters
*/
void setSpan_m (float span_m);
/** get the layer elevation (in meters) */
float getElevation_m () const;
void setElevation_m (float elevation_m);
/**
* set the layer elevation. Note that this specifies the bottom
* of the cloud layer. The elevation of the top of the layer is
* elevation_m + thickness_m.
* @param elevation_m the layer elevation in meters
* @param set_span defines whether it is allowed to adjust the span
*/
void setElevation_m (float elevation_m, bool set_span = true);
/** get the layer thickness */
float getThickness_m () const;
/**
* set the layer thickness.
* @param thickness_m the layer thickness in meters.
*/
void setThickness_m (float thickness_m);
/**
* get the transition/boundary layer depth in meters. This
* allows gradual entry/exit from the cloud layer via adjusting
* visibility.
*/
float getTransition_m () const;
/**
* set the transition layer size in meters
* @param transition_m the transition layer size in meters
*/
void setTransition_m (float transition_m);
/** get coverage type */
Coverage getCoverage () const;
/**
* set coverage type
* @param coverage the coverage type
*/
void setCoverage (Coverage coverage);
// build the cloud object
/**
* set the cloud movement direction
* @param dir the cloud movement direction
*/
inline void setDirection(float dir) { direction = dir; }
/** get the cloud movement direction */
inline float getDirection() { return direction; }
/**
* set the cloud movement speed
* @param sp the cloud movement speed
*/
inline void setSpeed(float sp) { speed = sp; }
/** get the cloud movement speed */
inline float getSpeed() { return speed; }
/** build the cloud object */
void rebuild();
// repaint the cloud colors based on current value of sun_angle,
// sky, and fog colors. This updates the color arrays for
// ssgVtxTable.
// sun angle in degrees relative to verticle
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
/**
* repaint the cloud colors based on the specified fog_color
* @param fog_color the fog color
*/
bool repaint( sgVec3 fog_color );
// reposition the cloud layer at the specified origin and
// orientation
// lon specifies a rotation about the Z axis
// lat specifies a rotation about the new Y axis
// spin specifies a rotation about the new Z axis (and orients the
// sunrise/set effects
bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt );
/**
* reposition the cloud layer at the specified origin and
* orientation.
* @param p position vector
* @param up the local up vector
* @param lon specifies a rotation about the Z axis
* @param lat specifies a rotation about the new Y axis
* @param spin specifies a rotation about the new Z axis
* (and orients the sunrise/set effects)
* @param dt the time elapsed since the last call
*/
bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt,
double dt = 0.0 );
// draw the cloud layer
/** draw the cloud layer */
void draw();
private:
@@ -109,6 +177,8 @@ private:
float layer_transition;
Coverage layer_coverage;
float scale;
float speed;
float direction;
// for handling texture coordinates to simulate cloud movement
// from winds, and to simulate the clouds being tied to ground

View File

@@ -1,4 +1,4 @@
includedir = @includedir@/sky/clouds3d
includedir = @includedir@/scene/sky/clouds3d
# enable the following line once extgl.c get's added to the distro
EXTRA_DIST = extgl.c extgl.h
@@ -25,6 +25,7 @@ libsgclouds3d_a_SOURCES = \
plane.cpp plane.hpp \
camera.cpp camera.hpp \
camutils.cpp camutils.hpp \
glut_shapes.c glut_shapes.h \
minmaxbox.cpp minmaxbox.hpp \
SkyAABBTree.hpp \
SkyArchive.cpp SkyArchive.hpp \

View File

@@ -2,7 +2,7 @@
// File : SkyArchive.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
@@ -20,6 +20,8 @@
*
* Implementation of class SkyArchive.
*/
#include <plib/ul.h>
#include "SkyArchive.hpp"
#include <assert.h>
@@ -27,9 +29,9 @@
struct SkyArchiveEntry
{
SkyArchiveEntry() : type(0), pData(NULL), iDataSize(0) {}
unsigned char type;
void* pData;
unsigned int iDataSize;
unsigned char type;
unsigned char* pData;
unsigned int iDataSize;
};
struct SkyArchiveFileEntry
@@ -180,7 +182,7 @@ SKYRESULT SkyArchive::AddData(const char* pName,
}
else
{
pNewEntry->pData = (void*)pData;
pNewEntry->pData = (unsigned char*)pData;
}
char* pInternalName = new char[::strlen(pName)+1];
@@ -507,7 +509,7 @@ SKYRESULT SkyArchive::FindInt16(const char* pName, short* pInt16, unsigned int i
const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT16_TYPE);
if (pEntry)
{
short* pData = (short*)(pEntry->pData);
unsigned short* pData = (unsigned short*)(pEntry->pData);
*pInt16 = *pData;
return SKYRESULT_OK;
}
@@ -527,7 +529,7 @@ SKYRESULT SkyArchive::FindInt32(const char* pName, int* pInt32, unsigned int ind
const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT32_TYPE);
if (pEntry)
{
int* pData = (int*)(pEntry->pData);
unsigned int* pData = (unsigned int*)(pEntry->pData);
*pInt32 = *pData;
return SKYRESULT_OK;
}
@@ -1160,9 +1162,11 @@ SKYRESULT SkyArchive::_Load( FILE* pSrcFile)
// load the first record
SkyArchiveFileEntry thisItem;
size_t iNumItemsRead = fread((void*)&thisItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
if (1 > iNumItemsRead)
if (!iNumItemsRead)
FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read Archive header.");
thisItem.iDataSize = ulEndianLittle32(thisItem.iDataSize);
_pName = new char[::strlen(thisItem.pName)+1];
::strcpy( _pName, thisItem.pName);
@@ -1173,6 +1177,9 @@ SKYRESULT SkyArchive::_Load( FILE* pSrcFile)
iNumItemsRead = fread((void*)&embeddedItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
if (1 > iNumItemsRead)
FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read embedded archive item.");
embeddedItem.iDataSize = ulEndianLittle32(embeddedItem.iDataSize);
switch( embeddedItem.type)
{
@@ -1187,7 +1194,7 @@ SKYRESULT SkyArchive::_Load( FILE* pSrcFile)
break;
default:
{
void* pData = new unsigned char[embeddedItem.iDataSize];
unsigned char* pData = new unsigned char[embeddedItem.iDataSize];
iNumItemsRead = fread((void*)pData, embeddedItem.iDataSize, 1, pSrcFile);
if (1 > iNumItemsRead)
FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read item data.");

View File

@@ -25,6 +25,17 @@
// warning for truncation of template name for browse info
#pragma warning( disable : 4786)
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glu.h>
#include <plib/ul.h>
#include "SkyCloud.hpp"
#include "SkyRenderableInstance.hpp"
#include "SkyContext.hpp"
@@ -622,6 +633,102 @@ SkyMinMaxBox* SkyCloud::CopyBoundingVolume() const
return pBox;
}
SKYRESULT SkyCloud::Load(const unsigned char *data, unsigned int size,
float rScale, /* = 1.0f */
double latitude, double longitude )
{
unsigned int iNumParticles;
Vec3f vecCenter = Vec3f::ZERO;
//Vec3f vecCenter;
//float rRadius;
//_boundingBox.SetMin(vecCenter - Vec3f(rRadius, rRadius, rRadius));
//_boundingBox.SetMax(vecCenter + Vec3f(rRadius, rRadius, rRadius));
for (unsigned int i = 0; i < size*size*4; i += 4)
{
Vec3f pos;
Vec4f color;
float radius;
color.x = data[i]; // FIXME: Which unit?
color.y = data[i+1];
color.z = data[i+2];
color.w = data[i+3];
radius = (color.w/255) * rScale;
//radius = (color.x * color.y * color.z * color.w * rScale) / 4096;
pos.x = (i / (size*4)) * 10; // FIXME: Which unit?
pos.y = (i % (size*4)) * 10;
pos.z = radius / 2;
if (radius > 0)
{
SkyCloudParticle *pParticle = new SkyCloudParticle((pos + vecCenter) * rScale, radius * rScale, color);
_boundingBox.AddPoint(pParticle->GetPosition());
_particles.push_back(pParticle);
}
}
// this is just a bad hack to align cloud field from skyworks with local horizon at KSFO
// this "almost" works not quite the right solution okay to get some up and running
// we need to develop our own scheme for loading and positioning clouds
Mat33f R;
Vec3f moveit;
R.Set( 0, 1, 0,
1, 0, 0,
0, 0, 1);
// clouds sit in the y-z plane and x-axis is the vertical cloud height
Rotate( R );
// rotate the cloud field about the fgfs z-axis based on initial longitude
float ex = 1.0;
float ey = 1.0;
float ez = 1.0;
float phi = longitude / 57.29578;
float one_min_cos = 1 - cos(phi);
R.Set(
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
Rotate( R );
// okay now that let's rotate about a vector for latitude where longitude forms the
// components of a unit vector in the x-y plane
ex = sin( longitude / 57.29578 );
ey = -cos( longitude / 57.29578 );
ez = 0.0;
phi = latitude / 57.29578;
one_min_cos = 1 - cos(phi);
R.Set(
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
Rotate( R );
// need to calculate an offset to place the clouds at ~3000 feet MSL ATM this is an approximation
// to move the clouds to some altitude above sea level. At some locations this could be underground
// will need a better scheme to position clouds per user preferences
float cloud_level_msl = 3000.0f;
float x_offset = ex * cloud_level_msl;
float y_offset = ey * cloud_level_msl;
float z_offset = cloud_level_msl * 0.5;
moveit.Set( x_offset, y_offset, z_offset );
Translate( moveit );
return SKYRESULT_OK;
}
SKYRESULT SkyCloud::Load(const SkyArchive &archive,
float rScale, /* = 1.0f */
double latitude, double longitude )
@@ -637,8 +744,13 @@ SKYRESULT SkyCloud::Load(const SkyArchive &archive,
//_boundingBox.SetMax(vecCenter + Vec3f(rRadius, rRadius, rRadius));
archive.FindUInt32("CldNumParticles", &iNumParticles);
iNumParticles = ulEndianLittle32(iNumParticles);
//if (!bLocal)
archive.FindVec3f("CldCenter", &vecCenter);
vecCenter.x = ulEndianLittleFloat(vecCenter.x);
vecCenter.y = ulEndianLittleFloat(vecCenter.y);
vecCenter.z = ulEndianLittleFloat(vecCenter.z);
Vec3f *pParticlePositions = new Vec3f[iNumParticles];
float *pParticleRadii = new float[iNumParticles];
@@ -648,9 +760,21 @@ SKYRESULT SkyCloud::Load(const SkyArchive &archive,
archive.FindData("CldParticlePositions", ANY_TYPE, (void**const)&pParticlePositions, &iNumBytes);
archive.FindData("CldParticleRadii", ANY_TYPE, (void**const)&pParticleRadii, &iNumBytes);
archive.FindData("CldParticleColors", ANY_TYPE, (void**const)&pParticleColors, &iNumBytes);
for (unsigned int i = 0; i < iNumParticles; ++i)
{
pParticlePositions[i].x = ulEndianLittleFloat(pParticlePositions[i].x);
pParticlePositions[i].y = ulEndianLittleFloat(pParticlePositions[i].y);
pParticlePositions[i].z = ulEndianLittleFloat(pParticlePositions[i].z);
pParticleRadii[i] = ulEndianLittleFloat(pParticleRadii[i]);
pParticleColors[i].x = ulEndianLittleFloat(pParticleColors[i].x);
pParticleColors[i].y = ulEndianLittleFloat(pParticleColors[i].y);
pParticleColors[i].z = ulEndianLittleFloat(pParticleColors[i].z);
pParticleColors[i].w = ulEndianLittleFloat(pParticleColors[i].w);
SkyCloudParticle *pParticle = new SkyCloudParticle((pParticlePositions[i] + vecCenter) * rScale,
pParticleRadii[i] * rScale,
pParticleColors[i]);

View File

@@ -99,6 +99,7 @@ public:
SKYRESULT Save(SkyArchive &archive) const;
SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
SKYRESULT Load(const unsigned char *data, unsigned int size, float rScale = 1.0f,double latitude=0.0,double longitude=0.0);
void Rotate(const Mat33f& rot);
void Translate(const Vec3f& trans);

View File

@@ -28,9 +28,13 @@
# include <windows.h>
#endif
#include GLUT_H
// #include GLUT_H
#ifndef WIN32
#if defined (__APPLE__)
# include <OpenGL/OpenGL.h>
#endif
#if !defined (WIN32) && !defined(__APPLE__)
#include <GL/glx.h>
#endif
@@ -52,8 +56,10 @@
*/
SkyContext::SkyContext()
{
_iWidth = glutGet(GLUT_WINDOW_WIDTH);
_iHeight = glutGet(GLUT_WINDOW_HEIGHT);
// _iWidth = glutGet(GLUT_WINDOW_WIDTH);
// _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
_iWidth = 640;
_iHeight = 480;
// materials and structure classes
AddCurrentGLContext();
@@ -136,6 +142,8 @@ SkyMaterial* SkyContext::GetCurrentMaterial()
{
#ifdef WIN32
ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
#elif defined(__APPLE__)
ContextMaterialIterator cmi = _currentMaterials.find(CGLGetCurrentContext());
#else
ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
#endif
@@ -164,6 +172,8 @@ SkyTextureState* SkyContext::GetCurrentTextureState()
{
#ifdef WIN32
ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
#elif defined(__APPLE__)
ContextTextureStateIterator ctsi = _currentTextureState.find(CGLGetCurrentContext());
#else
ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
#endif
@@ -192,6 +202,8 @@ SKYRESULT SkyContext::AddCurrentGLContext()
SkyMaterial *pCurrentMaterial = new SkyMaterial;
#ifdef WIN32
_currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
#elif defined (__APPLE__)
_currentMaterials.insert(std::make_pair(CGLGetCurrentContext(), pCurrentMaterial));
#else
_currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
#endif
@@ -199,6 +211,8 @@ SKYRESULT SkyContext::AddCurrentGLContext()
SkyTextureState *pCurrentTS = new SkyTextureState;
#ifdef WIN32
_currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
#elif defined (__APPLE__)
_currentTextureState.insert(std::make_pair(CGLGetCurrentContext() , pCurrentTS));
#else
_currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
#endif

View File

@@ -36,7 +36,7 @@
#include <map>
#include GLUT_H
#include <GL/gl.h>
#include "SkyUtil.hpp"
#include "SkySingleton.hpp"

View File

@@ -28,7 +28,9 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/glu.h>
#include "glut_shapes.h"
#ifdef WIN32
# ifdef _MSC_VER

View File

@@ -33,7 +33,7 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/gl.h>
#include "vec4f.hpp"
#include "SkyUtil.hpp"

View File

@@ -29,7 +29,7 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/gl.h>
#include "SkyMinMaxBox.hpp"
#include "camutils.hpp"

View File

@@ -19,6 +19,17 @@
*
* Implementation of class SkyRenderableInstanceCloud.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glu.h>
#include "SkyUtil.hpp"
#include "SkyCloud.hpp"
#include "SkyMaterial.hpp"

View File

@@ -30,7 +30,7 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/gl.h>
#include "SkyRenderableInstanceGroup.hpp"
#include "SkySceneManager.hpp"

View File

@@ -49,7 +49,7 @@ Point3D origin;
Camera *pCam = new Camera();
// Need to add a light here until we figure out how to use the sun position and color
SkyLight::SkyLightType eType = SkyLight::SKY_LIGHT_DIRECTIONAL;
SkyLight *pLight = new SkyLight(eType);
SkyLight *pLight = 0;
// hack
sgMat4 my_copy_of_ssgOpenGLAxisSwapMatrix =
@@ -89,6 +89,55 @@ SkySceneLoader::~SkySceneLoader()
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneLoader::Load(std::string filename)
* @brief Loads a SkyWorks scene.
*
* This is a temporary fix, as it loads only limited scenes
* It can however, load any number of Cloud
+
*/
//bool SkySceneLoader::Load(std::string filepath)
bool SkySceneLoader::Load( unsigned char *data, unsigned int size, double latitude, double longitude )
{
if( !pLight)
pLight = new SkyLight(eType);
// Need to create the managers
cout << "GraphicsContext::Instantiate();" << endl;
GraphicsContext::Instantiate();
cout << " TextureManager::Instantiate();" << endl;
TextureManager::Instantiate();
cout << " DynamicTextureManager::Instantiate();" << endl;
DynamicTextureManager::Instantiate();
cout << " SceneManager::Instantiate();" << endl;
SceneManager::Instantiate();
float rScale = 40.0;
FAIL_RETURN(SceneManager::InstancePtr()->LoadClouds(data, size, rScale, latitude, longitude));
Vec3f dir(0, 0, 1);
pLight->SetPosition(Vec3f(0, 0, 17000));
pLight->SetDirection(dir);
pLight->SetAmbient(Vec4f( 0.0f, 0.0f, 0.0f, 0.0f));
pLight->SetDiffuse(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
//pLight->SetDiffuse(Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
//pLight->SetSpecular(Vec4f(1.0f, 1.0f, 1.0f, 0.0f));
// No attenuation
pLight->SetAttenuation(1.0f, 0.0f, 0.0f);
SceneManager::InstancePtr()->AddLight(pLight);
SceneManager::InstancePtr()->ShadeClouds();
return true;
}
//------------------------------------------------------------------------------
// Function : SkySceneLoader::Load
// Description :
@@ -128,6 +177,7 @@ bool SkySceneLoader::Load( SGPath filename, double latitude, double longitude )
unsigned int iNumFiles;
if (!SKYFAILED(archive.GetInfo("CloudFile", STRING_TYPE, &iNumFiles)))
{
iNumFiles = ulEndianLittle32(iNumFiles);
for (unsigned int i = 0; i < iNumFiles; ++i)
{
FAIL_RETURN(archive.FindString("CloudFile", &pFilename, i));
@@ -139,12 +189,18 @@ bool SkySceneLoader::Load( SGPath filename, double latitude, double longitude )
//FAIL_RETURN(archive.FindFloat32("CloudScale", &rScale, i));
float rScale = 40.0;
SkyArchive cloudArchive;
cout << "Calling cloudArchive.Load(FilePath)" << endl;
FAIL_RETURN(cloudArchive.Load(FilePath));
cout << "Calling SceneManager::InstancePtr()->LoadClouds" << endl;
FAIL_RETURN(SceneManager::InstancePtr()->LoadClouds(cloudArchive, rScale, latitude, longitude));
}
}
cout << "After Load Clouds" << endl;
Vec3f dir(0, 0, 1);
if( !pLight)
pLight = new SkyLight(eType);
pLight->SetPosition(Vec3f(0, 0, 17000));
pLight->SetDirection(dir);
pLight->SetAmbient(Vec4f( 0.0f, 0.0f, 0.0f, 0.0f));
@@ -154,9 +210,12 @@ bool SkySceneLoader::Load( SGPath filename, double latitude, double longitude )
// No attenuation
pLight->SetAttenuation(1.0f, 0.0f, 0.0f);
cout << "Before SceneManager::InstancePtr()->AddLight(pLight)" << endl;
SceneManager::InstancePtr()->AddLight(pLight);
cout << "Before SceneManager::InstancePtr()->ShadeClouds()" << endl;
SceneManager::InstancePtr()->ShadeClouds();
cout << "After SceneManager::InstancePtr()->ShadeClouds()" << endl;
return true;
}
@@ -197,54 +256,23 @@ void SkySceneLoader::Resize( double w, double h )
}
void SkySceneLoader::Draw( sgMat4 mat )
{/* need this if you want to look at FG matrix
if ( _ssgCurrentContext == NULL )
{
cout<< "ssg: No Current Context: Did you forgot to call ssgInit()?" ; char x; cin >> x;
}
ssgForceBasicState () ;
*/
sgMat4 test, m, *pm, viewmat, cameraMatrix;
pm = &m;
sgSetVec4(mat[3], cam_pos[0], cam_pos[1], cam_pos[2], SG_ONE);
// at this point the view matrix has the cloud camera position relative to cloud origin
// now transform to screen coordinates
sgTransposeNegateMat4 ( viewmat, mat ) ;
{
sgMat4 cameraMatrix;
sgCopyMat4 ( cameraMatrix, my_copy_of_ssgOpenGLAxisSwapMatrix ) ;
sgPreMultMat4 ( cameraMatrix, viewmat ) ;
// sgCopyMat4(cameraMatrix,mat);
// or just
ssgGetModelviewMatrix(cameraMatrix);
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
glLoadMatrixf( (float *) cameraMatrix );
//sgCopyMat4 ( test, cameraMatrix );
pCam->SetModelviewMatrix( (float *) cameraMatrix );
//printf( "\nSkyworks ViewModel matrix\n" );
//cout << test[0][0] << " " << test[1][0] << " " << test[2][0] << " " << test[3][0] << endl;
//cout << test[0][1] << " " << test[1][1] << " " << test[2][1] << " " << test[3][1] << endl;
//cout << test[0][2] << " " << test[1][2] << " " << test[2][2] << " " << test[3][2] << endl;
//cout << test[0][3] << " " << test[1][3] << " " << test[2][3] << " " << test[3][3] << endl;
SceneManager::InstancePtr()->Display(*pCam);
// this is the cameraview matrix used by flightgear to render scene
//_ssgCurrentContext->getModelviewMatrix( m );
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
glLoadMatrixf( (float *) cameraMatrix );
//sgCopyMat4( test, m );
pCam->SetModelviewMatrix( (float *) cameraMatrix );
//printf( "\nFG modelview matrix\n" );
//cout << test[0][0] << " " << test[1][0] << " " << test[2][0] << " " << test[3][0] << endl;
//cout << test[0][1] << " " << test[1][1] << " " << test[2][1] << " " << test[3][1] << endl;
//cout << test[0][2] << " " << test[1][2] << " " << test[2][2] << " " << test[3][2] << endl;
//cout << test[0][3] << " " << test[1][3] << " " << test[2][3] << " " << test[3][3] << endl;
SceneManager::InstancePtr()->Display(*pCam);
//pLight->Display(); // draw the light position to debug with sun position
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
//pLight->Display(); // draw the light position to debug with sun position
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
}

View File

@@ -48,6 +48,7 @@ public:
SkySceneLoader();
~SkySceneLoader();
bool Load( unsigned char *data, unsigned int size, double latitude, double longitude );
bool Load( SGPath fileroot, double latitude, double longitude );
void Set_Cloud_Orig( Point3D *posit );

View File

@@ -499,6 +499,29 @@ SKYRESULT SkySceneManager::ShadeClouds()
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale)
* @brief @todo <WRITE BRIEF SkySceneManager::LoadClouds DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkySceneManager::LoadClouds FUNCTION DOCUMENTATION>
*/
SKYRESULT SkySceneManager::LoadClouds(unsigned char *data, unsigned int size, float rScale, double latitude, double longitude)
{
SkyCloud *pCloud = new SkyCloud();
pCloud->Load(data, size, rScale, latitude, longitude);
SkyRenderableInstanceCloud *pInstance = new SkyRenderableInstanceCloud(pCloud, false);
AddCloud(pCloud);
AddCloudInstance(pInstance);
RebuildCloudBVTree();
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkySceneManager::LoadClouds
// Description :
@@ -513,6 +536,7 @@ SKYRESULT SkySceneManager::LoadClouds(SkyArchive& cloudArchive, float rScale, do
{
unsigned int iNumClouds = 0;
cloudArchive.FindUInt32("CldNumClouds", &iNumClouds);
iNumClouds = ulEndianLittle32(iNumClouds);
SkyArchive subArchive;
//iNumClouds = 5; //set this value to reduce cloud field for debugging

View File

@@ -104,6 +104,7 @@ public:
static void SortInstances(InstanceArray& instances, const Vec3f& vecSortPoint);
// load a set of clouds from an archive file.
SKYRESULT LoadClouds(unsigned char *data, unsigned int size, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
SKYRESULT LoadClouds(SkyArchive& cloudArchive, float rScale = 1.0f, double latitude=0.0, double longitude=0.0);
protected: // datatypes

View File

@@ -33,7 +33,7 @@
# include <windows.h>
#endif
#include GLUT_H
#include <GL/gl.h>
#define __glext_h_
#define __GLEXT_H_

View File

@@ -22,6 +22,16 @@
#pragma warning( disable : 4786)
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glu.h>
#include "SkyTextureManager.hpp"
#include "SkyContext.hpp"
//#include "glvu.hpp"

View File

@@ -24,6 +24,12 @@
#include "SkyTextureState.hpp"
//#include "glvu.hpp"
#include <simgear/screen/extensions.hxx>
glActiveTextureProc glActiveTexturePtr = 0;
bool glActiveTextureIsSupported = false;
//------------------------------------------------------------------------------
@@ -45,13 +51,19 @@ SkyTextureState::SkyTextureState()
if (0 == s_iNumTextureUnits)
{
int iNumTextureUnits = 0;
#ifdef GL_ARB_multitexture
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &iNumTextureUnits);
if (iNumTextureUnits > 0)
s_iNumTextureUnits = iNumTextureUnits;
else
s_iNumTextureUnits = 1;
#endif
if (SGIsOpenGLExtensionSupported("GL_ARB_multitexture")) {
glActiveTextureIsSupported = true;
glActiveTexturePtr = (glActiveTextureProc)
SGLookupFunction("glActiveTextureARB");
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &iNumTextureUnits);
if (iNumTextureUnits > 0)
s_iNumTextureUnits = iNumTextureUnits;
else
s_iNumTextureUnits = 1;
} else
s_iNumTextureUnits = 1;
}
_pTextureUnitState = new TexState[s_iNumTextureUnits];
@@ -89,10 +101,9 @@ SKYRESULT SkyTextureState::Activate()
//GLVU::CheckForGLError("SkyTextureState::Activate(8)");
for (unsigned int i = 0; i < s_iNumTextureUnits; ++i)
{
#ifdef GL_ARB_multitexture
if (s_iNumTextureUnits > 1)
glActiveTextureARB(GL_TEXTURE0_ARB + i);
#endif
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB + i);
bool bEnabled = IsTextureEnabled(i);
if (pCurrent->IsTextureEnabled(i) != bEnabled)
{
@@ -151,10 +162,8 @@ SKYRESULT SkyTextureState::Activate()
}
//GLVU::CheckForGLError("SkyTextureState::Activate()");
}
#ifdef GL_ARB_multitexture
if (s_iNumTextureUnits > 1)
glActiveTextureARB(GL_TEXTURE0_ARB);
#endif
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB);
}
return SKYRESULT_OK;
}
@@ -177,10 +186,9 @@ SKYRESULT SkyTextureState::Force()
//GLVU::CheckForGLError("SkyTextureState::Activate(8)");
for (unsigned int i = 0; i < s_iNumTextureUnits; ++i)
{
#ifdef GL_ARB_multitexture
if (s_iNumTextureUnits > 1)
glActiveTextureARB(GL_TEXTURE0_ARB + i);
#endif
if (glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB + i);
bool bEnabled = IsTextureEnabled(i);
FAIL_RETURN(pCurrent->EnableTexture(i, bEnabled));
//GLVU::CheckForGLError("SkyTextureState::Activate(7)");
@@ -221,10 +229,8 @@ SKYRESULT SkyTextureState::Force()
FAIL_RETURN(pCurrent->SetTextureParameter(i, GL_TEXTURE_MAG_FILTER, paramValue));
glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, paramValue);
#ifdef GL_ARB_multitexture
if (s_iNumTextureUnits > 1)
glActiveTextureARB(GL_TEXTURE0_ARB);
#endif
if(glActiveTextureIsSupported && (s_iNumTextureUnits > 1))
glActiveTexturePtr(GL_TEXTURE0_ARB);
}
return SKYRESULT_OK;
}

View File

@@ -20,9 +20,9 @@
//============================================================================
#include "camutils.hpp"
#include <plane.hpp>
#include <tri.hpp>
#include <minmaxbox.hpp>
#include "plane.hpp"
#include "tri.hpp"
#include "minmaxbox.hpp"
//----------------------------------------------------------------------------
// Given a camera's 8 corner vertices and its 6 side planes and a triangle ABC,

View File

@@ -0,0 +1,609 @@
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
/**
(c) Copyright 1993, Silicon Graphics, Inc.
ALL RIGHTS RESERVED
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that
both the copyright notice and this permission notice appear in
supporting documentation, and that the name of Silicon
Graphics, Inc. not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission.
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
PERFORMANCE OF THIS SOFTWARE.
US Government Users Restricted Rights
Use, duplication, or disclosure by the Government is subject to
restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
(c)(1)(ii) of the Rights in Technical Data and Computer
Software clause at DFARS 252.227-7013 and/or in similar or
successor clauses in the FAR or the DOD or NASA FAR
Supplement. Unpublished-- rights reserved under the copyright
laws of the United States. Contractor/manufacturer is Silicon
Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
94039-7311.
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <math.h>
#include <GL/glu.h>
#include "glut_shapes.h"
/* Some <math.h> files do not define M_PI... */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static GLUquadricObj *quadObj;
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
static void
initQuadObj(void)
{
quadObj = gluNewQuadric();
if (!quadObj)
/* __glutFatalError("out of memory.") */;
}
/* CENTRY */
void APIENTRY
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void APIENTRY
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void APIENTRY
glutWireCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
void APIENTRY
glutSolidCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
/* ENDCENTRY */
static void
drawBox(GLfloat size, GLenum type)
{
static GLfloat n[6][3] =
{
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static GLint faces[6][4] =
{
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3}
};
GLfloat v[8][3];
GLint i;
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
for (i = 5; i >= 0; i--) {
glBegin(type);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
/* CENTRY */
void APIENTRY
glutWireCube(GLdouble size)
{
drawBox(size, GL_LINE_LOOP);
}
void APIENTRY
glutSolidCube(GLdouble size)
{
drawBox(size, GL_QUADS);
}
/* ENDCENTRY */
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
/* CENTRY */
void APIENTRY
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
glPushAttrib(GL_POLYGON_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
doughnut(innerRadius, outerRadius, nsides, rings);
glPopAttrib();
}
void APIENTRY
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
doughnut(innerRadius, outerRadius, nsides, rings);
}
/* ENDCENTRY */
static GLfloat dodec[20][3];
static void
initDodecahedron(void)
{
GLfloat alpha, beta;
alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
/* *INDENT-OFF* */
dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
/* *INDENT-ON* */
}
#define DIFF3(_a,_b,_c) { \
(_c)[0] = (_a)[0] - (_b)[0]; \
(_c)[1] = (_a)[1] - (_b)[1]; \
(_c)[2] = (_a)[2] - (_b)[2]; \
}
static void
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
{
GLfloat p[3]; /* in case prod == v1 or v2 */
p[0] = v1[1] * v2[2] - v2[1] * v1[2];
p[1] = v1[2] * v2[0] - v2[2] * v1[0];
p[2] = v1[0] * v2[1] - v2[0] * v1[1];
prod[0] = p[0];
prod[1] = p[1];
prod[2] = p[2];
}
static void
normalize(GLfloat v[3])
{
GLfloat d;
d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (d == 0.0) {
/* __glutWarning("normalize: zero length vector"); */
v[0] = d = 1.0;
}
d = 1 / d;
v[0] *= d;
v[1] *= d;
v[2] *= d;
}
static void
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
{
GLfloat n0[3], d1[3], d2[3];
DIFF3(dodec[a], dodec[b], d1);
DIFF3(dodec[b], dodec[c], d2);
crossprod(d1, d2, n0);
normalize(n0);
glBegin(shadeType);
glNormal3fv(n0);
glVertex3fv(&dodec[a][0]);
glVertex3fv(&dodec[b][0]);
glVertex3fv(&dodec[c][0]);
glVertex3fv(&dodec[d][0]);
glVertex3fv(&dodec[e][0]);
glEnd();
}
static void
dodecahedron(GLenum type)
{
static int inited = 0;
if (inited == 0) {
inited = 1;
initDodecahedron();
}
pentagon(0, 1, 9, 16, 5, type);
pentagon(1, 0, 3, 18, 7, type);
pentagon(1, 7, 11, 10, 9, type);
pentagon(11, 7, 18, 19, 6, type);
pentagon(8, 17, 16, 9, 10, type);
pentagon(2, 14, 15, 6, 19, type);
pentagon(2, 13, 12, 4, 14, type);
pentagon(2, 19, 18, 3, 13, type);
pentagon(3, 0, 5, 12, 13, type);
pentagon(6, 15, 8, 10, 11, type);
pentagon(4, 17, 8, 15, 14, type);
pentagon(4, 12, 5, 16, 17, type);
}
/* CENTRY */
void APIENTRY
glutWireDodecahedron(void)
{
dodecahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidDodecahedron(void)
{
dodecahedron(GL_TRIANGLE_FAN);
}
/* ENDCENTRY */
static void
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
GLenum shadeType)
{
GLfloat q0[3], q1[3];
DIFF3(n1, n2, q0);
DIFF3(n2, n3, q1);
crossprod(q0, q1, q1);
normalize(q1);
glBegin(shadeType);
glNormal3fv(q1);
glVertex3fv(n1);
glVertex3fv(n2);
glVertex3fv(n3);
glEnd();
}
static void
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
GLenum shadeType)
{
int depth;
GLfloat w0[3], w1[3], w2[3];
GLfloat l;
int i, j, k, n;
depth = 1;
for (i = 0; i < depth; i++) {
for (j = 0; i + j < depth; j++) {
k = depth - i - j;
for (n = 0; n < 3; n++) {
w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
/ depth;
w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
/ depth;
}
l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
w0[0] /= l;
w0[1] /= l;
w0[2] /= l;
l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
w1[0] /= l;
w1[1] /= l;
w1[2] /= l;
l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
w2[0] /= l;
w2[1] /= l;
w2[2] /= l;
recorditem(w1, w0, w2, shadeType);
}
}
}
static void
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
GLenum shadeType)
{
GLfloat *x0, *x1, *x2;
x0 = data[ndx[i][0]];
x1 = data[ndx[i][1]];
x2 = data[ndx[i][2]];
subdivide(x0, x1, x2, shadeType);
}
/* octahedron data: The octahedron produced is centered at the
origin and has radius 1.0 */
static GLfloat odata[6][3] =
{
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static int ondex[8][3] =
{
{0, 4, 2},
{1, 2, 4},
{0, 3, 4},
{1, 4, 3},
{0, 2, 5},
{1, 5, 2},
{0, 5, 3},
{1, 3, 5}
};
static void
octahedron(GLenum shadeType)
{
int i;
for (i = 7; i >= 0; i--) {
drawtriangle(i, odata, ondex, shadeType);
}
}
/* CENTRY */
void APIENTRY
glutWireOctahedron(void)
{
octahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidOctahedron(void)
{
octahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* icosahedron data: These numbers are rigged to make an
icosahedron of radius 1.0 */
#define X .525731112119133606
#define Z .850650808352039932
static GLfloat idata[12][3] =
{
{-X, 0, Z},
{X, 0, Z},
{-X, 0, -Z},
{X, 0, -Z},
{0, Z, X},
{0, Z, -X},
{0, -Z, X},
{0, -Z, -X},
{Z, X, 0},
{-Z, X, 0},
{Z, -X, 0},
{-Z, -X, 0}
};
static int index[20][3] =
{
{0, 4, 1},
{0, 9, 4},
{9, 5, 4},
{4, 5, 8},
{4, 8, 1},
{8, 10, 1},
{8, 3, 10},
{5, 3, 8},
{5, 2, 3},
{2, 7, 3},
{7, 10, 3},
{7, 6, 10},
{7, 11, 6},
{11, 0, 6},
{0, 1, 6},
{6, 1, 10},
{9, 0, 11},
{9, 11, 2},
{9, 2, 5},
{7, 2, 11},
};
static void
icosahedron(GLenum shadeType)
{
int i;
for (i = 19; i >= 0; i--) {
drawtriangle(i, idata, index, shadeType);
}
}
/* CENTRY */
void APIENTRY
glutWireIcosahedron(void)
{
icosahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidIcosahedron(void)
{
icosahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* tetrahedron data: */
#define T 1.73205080756887729
static GLfloat tdata[4][3] =
{
{T, T, T},
{T, -T, -T},
{-T, T, -T},
{-T, -T, T}
};
static int tndex[4][3] =
{
{0, 1, 3},
{2, 1, 0},
{3, 2, 0},
{1, 2, 3}
};
static void
tetrahedron(GLenum shadeType)
{
int i;
for (i = 3; i >= 0; i--)
drawtriangle(i, tdata, tndex, shadeType);
}
/* CENTRY */
void APIENTRY
glutWireTetrahedron(void)
{
tetrahedron(GL_LINE_LOOP);
}
void APIENTRY
glutSolidTetrahedron(void)
{
tetrahedron(GL_TRIANGLES);
}
/* ENDCENTRY */

View File

@@ -0,0 +1,43 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/gl.h>
#define APIENTRY
#ifdef __cplusplus
extern "C" {
#endif
extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
;
extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks
);
extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices,
GLint stacks);
extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices,
GLint stacks);
extern void APIENTRY glutWireCube(GLdouble size);
extern void APIENTRY glutSolidCube(GLdouble size);
extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
extern void APIENTRY glutWireDodecahedron(void);
extern void APIENTRY glutSolidDodecahedron(void);
extern void APIENTRY glutWireTeapot(GLdouble size);
extern void APIENTRY glutSolidTeapot(GLdouble size);
extern void APIENTRY glutWireOctahedron(void);
extern void APIENTRY glutSolidOctahedron(void);
extern void APIENTRY glutWireTetrahedron(void);
extern void APIENTRY glutSolidTetrahedron(void);
extern void APIENTRY glutWireIcosahedron(void);
extern void APIENTRY glutSolidIcosahedron(void);
#ifdef __cplusplus
}
#endif

View File

@@ -33,7 +33,7 @@
#include <math.h>
#include GLUT_H
#include <GL/gl.h>
#include <plib/sg.h>
@@ -47,20 +47,20 @@
#endif
// in meters of course
static const float center_elev = 0.3125;
// proportions of max dimensions fed to the build() routine
static const float center_elev = 1.0;
static const float upper_radius = 0.6250;
static const float upper_elev = 0.2500;
static const float upper_radius = 0.6;
static const float upper_elev = 0.15;
static const float middle_radius = 0.8750;
static const float middle_elev = 0.1000;
static const float middle_radius = 0.9;
static const float middle_elev = 0.08;
static const float lower_radius = 0.8750;
static const float lower_elev = 0.0000;
static const float lower_radius = 1.0;
static const float lower_elev = 0.0;
static const float bottom_radius = 0.6250;
static const float bottom_elev = -0.0250;
static const float bottom_radius = 0.8;
static const float bottom_elev = -0.1;
// Set up dome rendering callbacks
@@ -105,7 +105,7 @@ SGSkyDome::~SGSkyDome( void ) {
ssgBranch * SGSkyDome::build( double hscale, double vscale ) {
sgVec4 color;
float theta;
double theta;
int i;
// set up the state
@@ -153,20 +153,20 @@ ssgBranch * SGSkyDome::build( double hscale, double vscale ) {
cos(theta) * upper_radius * hscale,
sin(theta) * upper_radius * hscale,
upper_elev * vscale );
sgSetVec3( middle_vertex[i],
cos((double)theta) * middle_radius * hscale,
sin((double)theta) * middle_radius * hscale,
cos(theta) * middle_radius * hscale,
sin(theta) * middle_radius * hscale,
middle_elev * vscale );
sgSetVec3( lower_vertex[i],
cos((double)theta) * lower_radius * hscale,
sin((double)theta) * lower_radius * hscale,
cos(theta) * lower_radius * hscale,
sin(theta) * lower_radius * hscale,
lower_elev * vscale );
sgSetVec3( bottom_vertex[i],
cos((double)theta) * bottom_radius * hscale,
sin((double)theta) * bottom_radius * hscale,
cos(theta) * bottom_radius * hscale,
sin(theta) * bottom_radius * hscale,
bottom_elev * vscale );
}
@@ -332,7 +332,10 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
sgVec4 lower_color[12];
sgVec4 bottom_color[12];
double vis_factor;
double vis_factor, cvf = vis;
if (cvf > 45000)
cvf = 45000;
if ( vis < 3000.0 ) {
vis_factor = (vis - 1000.0) / 2000.0;
@@ -356,9 +359,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
// l->sky_color[j], l->fog_color[j], diff);
upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
+ middle_amt[j];
upper_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
middle_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) )
+ middle_amt[j];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
@@ -397,9 +402,11 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
// sky_color[j], fog_color[j], diff);
upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7);
middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1)
+ middle_amt[j];
upper_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
middle_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) )
+ middle_amt[j];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }

View File

@@ -49,7 +49,6 @@
#include "sphere.hxx"
#include "oursun.hxx"
// Set up sun rendering call backs
static int sgSunOrbPreDraw( ssgEntity *e ) {
/* cout << endl << "Sun orb pre draw" << endl << "----------------"
@@ -91,7 +90,8 @@ static int sgSunHaloPreDraw( ssgEntity *e ) {
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
// glDisable( GL_FOG );
glFogf (GL_FOG_DENSITY, sun_exp2_punch_through);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
@@ -113,6 +113,8 @@ static int sgSunHaloPostDraw( ssgEntity *e ) {
// Constructor
SGSun::SGSun( void ) {
prev_sun_angle = -9999.0;
visibility = -9999.0;
}
@@ -259,7 +261,7 @@ ssgBranch * SGSun::build( SGPath path, double sun_size ) {
sgSunOrbPreDraw, sgSunOrbPostDraw );
// force a repaint of the sun colors with arbitrary defaults
repaint( 0.0 );
repaint( 0.0, 1.0 );
// build the halo
// sun_texbuf = new GLubyte[64*64*3];
@@ -334,43 +336,15 @@ ssgBranch * SGSun::build( SGPath path, double sun_size ) {
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSun::repaint( double sun_angle ) {
static float prev_sun_angle = 9999.0;
bool SGSun::repaint( double sun_angle, double new_visibility ) {
if ( visibility != new_visibility ) {
visibility = new_visibility;
// else sun is well below horizon (so no point in repainting it)
#if 0
if ( (sun_angle * SGD_RADIANS_TO_DEGREES < 100 )
&& (prev_sun_angle != sun_angle))
{
prev_sun_angle = sun_angle;
// x_10 = sun_angle^10
double x_10 = sun_angle * sun_angle * sun_angle * sun_angle * sun_angle
* sun_angle * sun_angle * sun_angle * sun_angle * sun_angle;
float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
if (ambient < 0.3) { ambient = 0.3; }
if (ambient > 1.0) { ambient = 1.0; }
sgVec4 color;
sgSetVec4( color,
(ambient * 6.0) - 1.0, // minimum value = 0.8
(ambient * 11.0) - 2.7, // minimum value = 0.6
(ambient * 12.0) - 3.6, // minimum value = 0.0
1.0 );
// temp test, forces the color to always be white
// sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
if (color[0] > 1.0) color[0] = 1.0;
if (color[1] > 1.0) color[1] = 1.0;
if (color[2] > 1.0) color[2] = 1.0;
#else
if (prev_sun_angle != sun_angle)
{
static double sqrt_m_log01 = sqrt( -log( 0.01 ) );
sun_exp2_punch_through = sqrt_m_log01 / (visibility * 15);
}
if (prev_sun_angle != sun_angle) {
prev_sun_angle = sun_angle;
float sun_factor = 4*cos(sun_angle);
@@ -380,12 +354,12 @@ bool SGSun::repaint( double sun_angle ) {
sun_factor = sun_factor/2 + 0.5;
sgVec4 color;
color[0] = pow(sun_factor, 0.25);
color[1] = pow(sun_factor, 0.50);
color[2] = pow(sun_factor, 4.0);
color[1] = sqrt(sun_factor);
color[0] = sqrt(color[1]);
color[2] = sun_factor * sun_factor;
color[2] *= color[2];
color[3] = 1.0;
#endif
gamma_correct_rgb( color );
// cout << "color = " << color[0] << " " << color[1] << " "

View File

@@ -34,6 +34,7 @@
#include <simgear/misc/sg_path.hxx>
static double sun_exp2_punch_through;
class SGSun {
@@ -49,6 +50,9 @@ class SGSun {
GLuint sun_texid;
GLubyte *sun_texbuf;
double visibility;
double prev_sun_angle;
public:
// Constructor
@@ -65,7 +69,7 @@ public:
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( double sun_angle );
bool repaint( double sun_angle, double new_visibility );
// reposition the sun at the specified right ascension and
// declination, offset by our current position (p) so that it

View File

@@ -43,6 +43,8 @@ SGSky::SGSky( void ) {
ramp_down = 0.15;
// ramp_up = 4.0;
// ramp_down = 4.0;
in_cloud = -1;
}
@@ -56,10 +58,10 @@ SGSky::~SGSky( void )
// initialize the sky and connect the components to the scene graph at
// the provided branch
void SGSky::build( double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
double planet_dist,
int nstars, sgdVec3 *star_data, double star_dist )
void SGSky::build( double h_radius_m, double v_radius_m,
double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data )
{
pre_root = new ssgRoot;
post_root = new ssgRoot;
@@ -71,15 +73,13 @@ void SGSky::build( double sun_size, double moon_size,
post_transform = new ssgTransform;
dome = new SGSkyDome;
pre_transform -> addKid( dome->build() );
pre_transform -> addKid( dome->build( h_radius_m, v_radius_m ) );
planets = new SGStars;
pre_transform -> addKid( planets->build(nplanets, planet_data,
planet_dist)
);
pre_transform -> addKid(planets->build(nplanets, planet_data, h_radius_m));
stars = new SGStars;
pre_transform -> addKid( stars->build(nstars, star_data, star_dist) );
pre_transform -> addKid( stars->build(nstars, star_data, h_radius_m) );
moon = new SGMoon;
pre_transform -> addKid( moon->build(tex_path, moon_size) );
@@ -105,22 +105,24 @@ void SGSky::build( double sun_size, double moon_size,
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color, sgVec4 cloud_color,
double sun_angle, double moon_angle,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data )
bool SGSky::repaint( const SGSkyColor &sc )
{
if ( effective_visibility > 1000.0 ) {
enable();
dome->repaint( sky_color, fog_color, sun_angle, effective_visibility );
oursun->repaint( sun_angle );
moon->repaint( moon_angle );
planets->repaint( sun_angle, nplanets, planet_data );
stars->repaint( sun_angle, nstars, star_data );
dome->repaint( sc.sky_color, sc.fog_color, sc.sun_angle,
effective_visibility );
oursun->repaint( sc.sun_angle, effective_visibility );
moon->repaint( sc.moon_angle );
planets->repaint( sc.sun_angle, sc.nplanets, sc.planet_data );
stars->repaint( sc.sun_angle, sc.nstars, sc.star_data );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
if (cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR){
cloud_layers[i]->repaint( cloud_color );
cloud_layers[i]->repaint( sc.cloud_color );
}
}
} else {
@@ -139,22 +141,27 @@ bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color, sgVec4 cloud_color,
// spin specifies a rotation about the new Z axis (this allows
// additional orientation for the sunrise/set effects and is used by
// the skydome and perhaps clouds.
bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up,
double lon, double lat, double alt, double spin,
double gst,
double sun_ra, double sun_dec, double sun_dist,
double moon_ra, double moon_dec, double moon_dist )
bool SGSky::reposition( SGSkyState &st, double dt )
{
double angle = gst * 15; // degrees
dome->reposition( zero_elev, lon, lat, spin );
oursun->reposition( view_pos, angle, sun_ra, sun_dec, sun_dist );
moon->reposition( view_pos, angle, moon_ra, moon_dec, moon_dist );
planets->reposition( view_pos, angle );
stars->reposition( view_pos, angle );
double angle = st.gst * 15; // degrees
dome->reposition( st.zero_elev, st.lon, st.lat, st.spin );
oursun->reposition( st.view_pos, angle,
st.sun_ra, st.sun_dec, st.sun_dist );
moon->reposition( st.view_pos, angle,
st.moon_ra, st.moon_dec, st.moon_dist );
planets->reposition( st.view_pos, angle );
stars->reposition( st.view_pos, angle );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ) {
cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt );
cloud_layers[i]->reposition( st.zero_elev, st.view_up,
st.lon, st.lat, st.alt, dt );
}
}
@@ -164,73 +171,64 @@ bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up,
// draw background portions of the sky ... do this before you draw the
// rest of your scene.
void SGSky::preDraw() {
void SGSky::preDraw( float alt, float fog_exp2_density ) {
ssgCullAndDraw( pre_root );
// FIXME: This should not be needed, but at this time (08/15/2003)
// certain NVidia drivers don't seem to implement
// fgPushAttrib(FG_FOG_BIT) properly. The result is that
// there is not fog when looking at the sun.
glFogf ( GL_FOG_DENSITY, fog_exp2_density );
// if we are closer than this to a cloud layer, don't draw clouds
static const float slop = 5.0;
int i;
// check where we are relative to the cloud layers
in_cloud = -1;
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->getElevation_m();
float thickness = cloud_layers[i]->getThickness_m();
if ( alt < asl - slop ) {
// below cloud layer
} else if ( alt < asl + thickness + slop ) {
// in cloud layer
// bail now and don't draw any clouds
in_cloud = i;
} else {
// above cloud layer
}
}
// determine rendering order
cur_layer_pos = 0;
while ( cur_layer_pos < (int)cloud_layers.size() &&
alt > cloud_layers[cur_layer_pos]->getElevation_m())
{
++cur_layer_pos;
}
// draw the cloud layers that are above us, top to bottom
for ( i = (int)cloud_layers.size() - 1; i >= cur_layer_pos; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
}
// draw translucent clouds ... do this after you've drawn all the
// oapaque elements of your scene.
void SGSky::postDraw( float alt ) {
float slop = 5.0; // if we are closer than this to a cloud layer,
// don't draw clouds
int in_cloud = -1; // cloud we are in
// draw the cloud layers that are below us, bottom to top
int i;
// check where we are relative to the cloud layers
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->getElevation_m();
float thickness = cloud_layers[i]->getThickness_m();
if ( alt < asl - slop ) {
// below cloud layer
} else if ( alt < asl + thickness + slop ) {
// in cloud layer
// bail now and don't draw any clouds
in_cloud = i;
} else {
// above cloud layer
}
}
// determine rendering order
int pos = 0;
while ( pos < (int)cloud_layers.size() &&
alt > cloud_layers[pos]->getElevation_m())
{
++pos;
}
if ( pos == 0 ) {
// we are below all the cloud layers, draw top to bottom
for ( i = cloud_layers.size() - 1; i >= 0; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
} else if ( pos >= (int)cloud_layers.size() ) {
// we are above all the cloud layers, draw bottom to top
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
} else {
// we are between cloud layers, draw lower layers bottom to
// top and upper layers top to bottom
for ( i = 0; i < pos; ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
for ( i = cloud_layers.size() - 1; i >= pos; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
for ( int i = 0; i < cur_layer_pos; ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
}

View File

@@ -55,6 +55,21 @@ typedef vector < SGCloudLayer* > layer_list_type;
typedef layer_list_type::iterator layer_list_iterator;
typedef layer_list_type::const_iterator layer_list_const_iterator;
typedef struct {
float *view_pos, *zero_elev, *view_up;
double lon, lat, alt, spin;
double gst;
double sun_ra, sun_dec, sun_dist;
double moon_ra, moon_dec, moon_dist;
} SGSkyState;
typedef struct {
float *sky_color, *fog_color, *cloud_color;
double sun_angle, moon_angle;
int nplanets, nstars;
sgdVec3 *planet_data, *star_data;
} SGSkyColor;
/**
* A class to model a realistic (time/date/position) based sky.
*
@@ -80,10 +95,10 @@ typedef layer_list_type::const_iterator layer_list_const_iterator;
* texture_path() method.
* The arguments you pass to the build() method allow you to specify
* the size of your sun sphere and moon sphere, a number of planets,
* and a multitude of stars. For the planets and stars you pass in an
* array of right ascensions, declinations, magnitudes, and the
* distance from the view point.
* the horizontal and vertical radiuses of the sky dome, the size of
* your sun sphere and moon sphere, a number of planets, and a
* multitude of stars. For the planets and stars you pass in an array
* of right ascensions, declinations, and magnitudes.
* Cloud Layers
@@ -204,6 +219,9 @@ private:
float visibility;
float effective_visibility;
int in_cloud;
int cur_layer_pos;
// near cloud visibility state variables
bool in_puff;
double puff_length; // in seconds
@@ -223,19 +241,21 @@ public:
* Initialize the sky and connect the components to the scene
* graph at the provided branch. See discussion in detailed class
* description.
* @param h_radius_m horizontal radius of sky dome
* @param v_radius_m vertical radius of sky dome
* @param sun_size size of sun
* @param moon_size size of moon
* @param nplanets number of planets
* @param planet_data an array of planet right ascensions, declinations,
* and magnitudes
* @param planet_dist distance from viewer to put the planets
* @param nstars number of stars
* @param star_data an array of star right ascensions, declinations,
* and magnitudes
* @param star_dist distance from viewer to put the stars */
void build( double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data, double planet_dist,
int nstars, sgdVec3 *star_data, double star_dist );
*/
void build( double h_radius_m, double v_radius_m,
double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data );
/**
* Repaint the sky components based on current value of sun_angle,
@@ -261,10 +281,7 @@ public:
* @param star_data an array of star right ascensions, declinations,
* and magnitudes
*/
bool repaint( sgVec4 sky_color, sgVec4 fog_color, sgVec4 cloud_color,
double sun_angle, double moon_angle,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data );
bool repaint( const SGSkyColor &sc );
/**
* Reposition the sky at the specified origin and orientation
@@ -294,11 +311,7 @@ public:
* @param moon_dec the moon's current declination
* @param moon_dist the moon's distance from the current view point.
*/
bool reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up,
double lon, double lat, double alt, double spin,
double gst,
double sun_ra, double sun_dec, double sun_dist,
double moon_ra, double moon_dec, double moon_dist );
bool reposition( SGSkyState &st, double dt = 0.0 );
/**
* Modify the given visibility based on cloud layers, thickness,
@@ -314,8 +327,9 @@ public:
* Draw background portions of the sky ... do this before you draw
* the rest of your scene. See discussion in detailed
* class description.
* @param alt current altitude
*/
void preDraw();
void preDraw( float alt, float fog_exp2_density );
/**
* Draw translucent clouds ... do this after you've drawn all the

View File

@@ -22,9 +22,9 @@
// $Id$
// #ifdef HAVE_CONFIG_H
// # include <config.h>
// #endif
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
@@ -130,7 +130,7 @@ bool sgGenTile( const string& path, SGBucket b,
geod_nodes.push_back( geod[i] );
rectangle.push_back( i );
}
point_list texs = calc_tex_coords( b, geod_nodes, rectangle,
point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle,
1000.0 / tex_width );
// Allocate ssg structure
@@ -318,9 +318,10 @@ bool sgBinObjLoad( const string& path, const bool is_base,
double *bounding_radius,
SGMaterialLib *matlib,
bool use_random_objects,
ssgBranch* geometry,
ssgBranch* rwy_lights,
ssgBranch* taxi_lights,
ssgBranch *geometry,
ssgBranch *vasi_lights,
ssgBranch *rwy_lights,
ssgBranch *taxi_lights,
ssgVertexArray *ground_lights )
{
SGBinObject obj;
@@ -351,7 +352,8 @@ bool sgBinObjLoad( const string& path, const bool is_base,
group_list const& pts_n = obj.get_pts_n();
for ( i = 0; i < pts_v.size(); ++i ) {
// cout << "pts_v.size() = " << pts_v.size() << endl;
if ( pt_materials[i].substr(0, 3) == "RWY" ) {
if ( pt_materials[i].substr(0, 3) == "RWY" ) {
// airport environment lighting
sgVec3 up;
sgSetVec3( up, center->x(), center->y(), center->z() );
// returns a transform -> lod -> leaf structure
@@ -359,12 +361,17 @@ bool sgBinObjLoad( const string& path, const bool is_base,
pts_v[i], pts_n[i],
matlib,
pt_materials[i], up );
if ( pt_materials[i].substr(0, 16) == "RWY_BLUE_TAXIWAY" ) {
if ( pt_materials[i] == "RWY_VASI_LIGHTS" ) {
vasi_lights->addKid( branch );
} else if ( pt_materials[i] == "RWY_BLUE_TAXIWAY_LIGHTS"
|| pt_materials[i] == "RWY_GREEN_TAXIWAY_LIGHTS" )
{
taxi_lights->addKid( branch );
} else {
rwy_lights->addKid( branch );
}
} else {
// other geometry
material = pt_materials[i];
tex_index.clear();
ssgLeaf *leaf = sgMakeLeaf( path, GL_POINTS, matlib, material,

View File

@@ -51,15 +51,16 @@ bool sgBinObjLoad( const string& path, const bool is_base,
double *bounding_radius,
SGMaterialLib *matlib,
bool use_random_objects,
ssgBranch* geometry,
ssgBranch* rwy_lights,
ssgBranch* taxi_lights,
ssgBranch *geometry,
ssgBranch *vasi_lights,
ssgBranch *rwy_lights,
ssgBranch *taxi_lights,
ssgVertexArray *ground_lights );
// Generate an ocean tile
bool sgGenTile( const string& path, SGBucket b,
Point3D *center, double *bounding_radius,
SGMaterialLib *matlib, ssgBranch* geometry );
SGMaterialLib *matlib, ssgBranch *geometry );
#endif // _SG_OBJ_HXX

View File

@@ -49,20 +49,6 @@ typedef int_list::iterator int_list_iterator;
typedef int_list::const_iterator int_point_list_iterator;
// Define the various supported light types
typedef enum {
SG_RWYLIGHT_TAXI = 0,
SG_RWYLIGHT_VASI,
SG_RWYLIGHT_EDGE,
SG_RWYLIGHT_TOUCHDOWN,
SG_RWYLIGHT_THRESHOLD,
SG_RWYLIGHT_WHITE,
SG_RWYLIGHT_RED,
SG_RWYLIGHT_GREEN,
SG_RWYLIGHT_YELLOW
} sgPointLightType;
// Generate a directional light. This routines creates a
// 'directional' light that can only be viewed from within 90 degrees
// of the specified dir vector.

View File

@@ -11,7 +11,7 @@
#include <limits.h>
#include <string.h> // memcpy()
#include GLUT_H
#include <GL/gl.h>
#include "GLBitmaps.h"

View File

@@ -19,6 +19,7 @@ include_HEADERS = \
texture.hxx \
$(IMAGE_SERVER_INCL) \
screen-dump.hxx \
extensions.hxx \
tr.h
libsgscreen_a_SOURCES = \
@@ -26,7 +27,8 @@ libsgscreen_a_SOURCES = \
GLBitmaps.cxx GLBitmaps.h \
$(IMAGE_SERVER_SRCS) \
screen-dump.cxx \
tr.cxx \
tr.cxx \
extensions.cxx \
win32-printer.h
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,99 @@
/*
*
* Copyright (c) 2001 C<>sar Blecua Ud<55>as All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* CESAR BLECUA UDIAS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include <string.h>
#include "extensions.hxx"
static bool SGSearchExtensionsString(char *extString, char *extName) {
// Returns GL_TRUE if the *extName string appears in the *extString string,
// surrounded by white spaces, or GL_FALSE otherwise.
char *p, *end;
int n, extNameLen;
if ((extString == NULL) || (extName == NULL))
return false;
extNameLen = strlen(extName);
p=extString;
end = p + strlen(p);
while (p < end) {
n = strcspn(p, " ");
if ((extNameLen == n) && (strncmp(extName, p, n) == 0))
return GL_TRUE;
p += (n + 1);
}
return GL_FALSE;
}
bool SGIsOpenGLExtensionSupported(char *extName) {
// Returns GL_TRUE if the OpenGL Extension whose name is *extName
// is supported by the system, or GL_FALSE otherwise.
//
// The *extName string must follow the OpenGL extensions naming scheme
// (ie: "GL_type_extension", like GL_EXT_convolution)
return SGSearchExtensionsString((char *)glGetString(GL_EXTENSIONS),
extName);
}
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
void* macosxGetGLProcAddress(const char *func) {
/* We may want to cache the bundleRef at some point */
static CFBundleRef bundle = 0;
if (!bundle) {
CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);
CFRelease (bundleURL);
}
if (!bundle)
return 0;
CFStringRef functionName = CFStringCreateWithCString
(kCFAllocatorDefault, func, kCFStringEncodingASCII);
void *function;
function = CFBundleGetFunctionPointerForName (bundle, functionName);
CFRelease (functionName);
return function;
}
#endif

View File

@@ -0,0 +1,157 @@
/*
*
* Copyright (c) 2001 C<>sar Blecua Ud<55>as All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* CESAR BLECUA UDIAS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef __SG_EXTENSIONS_HXX
#define __SG_EXTENSIONS_HXX 1
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
# include <windows.h>
#else
# include <dlfcn.h>
#endif
#include <GL/gl.h>
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef APIENTRY
#define APIENTRY
#endif
// static bool SGSearchExtensionsString(char *extString, char *extName);
bool SGIsOpenGLExtensionSupported(char *extName);
#ifdef __APPLE__
// don't use an inline function for symbol lookup, since it is too big
void* macosxGetGLProcAddress(const char *func);
#endif
inline void (*SGLookupFunction(const char *func))()
{
#if defined( WIN32 ) && !defined(__CYGWIN__) && !defined(__MINGW32__)
return (void (*)()) wglGetProcAddress(func);
#elif defined( __APPLE__ )
return (void (*)()) macosxGetGLProcAddress(func);
#else // UNIX
// If the target system s UNIX and the ARB_get_proc_address
// GLX extension is *not* guaranteed to be supported. An alternative
// dlsym-based approach will be used instead.
void *libHandle;
void (*fptr)();
libHandle = dlopen("libGL.so", RTLD_LAZY);
fptr = (void (*)()) dlsym(libHandle, func);
dlclose(libHandle);
return fptr;
#endif
}
/* OpenGL extension declarations */
/*
* glPointParameterf and glPointParameterfv
*/
#ifndef GL_EXT_point_parameters
#define GL_EXT_point_parameters 1
#define GL_POINT_SIZE_MIN_EXT 0x8126
#define GL_DISTANCE_ATTENUATION_EXT 0x8129
#endif
#ifndef GL_ARB_point_parameters
#define GL_ARB_point_parameters 1
#define GL_POINT_SIZE_MIN_ARB 0x8126
#define GL_DISTANCE_ATTENUATION_ARB 0x8129
#endif
typedef void (APIENTRY * glPointParameterfProc)(GLenum pname, GLfloat param);
typedef void (APIENTRY * glPointParameterfvProc)(GLenum pname, const GLfloat *params);
/*
* glActiveTextureARB
*/
#ifndef GL_ARB_multitexture
#define GL_ARB_multitexture 1
#define GL_TEXTURE0_ARB 0x84C0
#define GL_TEXTURE1_ARB 0x84C1
#define GL_TEXTURE2_ARB 0x84C2
#define GL_TEXTURE3_ARB 0x84C3
#define GL_TEXTURE4_ARB 0x84C4
#define GL_TEXTURE5_ARB 0x84C5
#define GL_TEXTURE6_ARB 0x84C6
#define GL_TEXTURE7_ARB 0x84C7
#define GL_TEXTURE8_ARB 0x84C8
#define GL_TEXTURE9_ARB 0x84C9
#define GL_TEXTURE10_ARB 0x84CA
#define GL_TEXTURE11_ARB 0x84CB
#define GL_TEXTURE12_ARB 0x84CC
#define GL_TEXTURE13_ARB 0x84CD
#define GL_TEXTURE14_ARB 0x84CE
#define GL_TEXTURE15_ARB 0x84CF
#define GL_TEXTURE16_ARB 0x84D0
#define GL_TEXTURE17_ARB 0x84D1
#define GL_TEXTURE18_ARB 0x84D2
#define GL_TEXTURE19_ARB 0x84D3
#define GL_TEXTURE20_ARB 0x84D4
#define GL_TEXTURE21_ARB 0x84D5
#define GL_TEXTURE22_ARB 0x84D6
#define GL_TEXTURE23_ARB 0x84D7
#define GL_TEXTURE24_ARB 0x84D8
#define GL_TEXTURE25_ARB 0x84D9
#define GL_TEXTURE26_ARB 0x84DA
#define GL_TEXTURE27_ARB 0x84DB
#define GL_TEXTURE28_ARB 0x84DC
#define GL_TEXTURE29_ARB 0x84DD
#define GL_TEXTURE30_ARB 0x84DE
#define GL_TEXTURE31_ARB 0x84DF
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
#endif
typedef void (APIENTRY * glActiveTextureProc)(GLenum texture);
/*
* GL_EXT_separate_specular_color
*/
#ifndef GL_LIGHT_MODEL_COLOR_CONTROL
#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
#define GL_SINGLE_COLOR 0x81F9
#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
#endif
#if defined(__cplusplus)
}
#endif
#endif // !__SG_EXTENSIONS_HXX

View File

@@ -32,7 +32,7 @@
#include <stdlib.h>
#include <limits.h>
#include GLUT_H
#include <GL/gl.h>
#include "screen-dump.hxx"

View File

@@ -1,5 +1,4 @@
/**
* \file texture.cxx
/*
* Texture manipulation routines
*
* Copyright (c) Mark J. Kilgard, 1997.
@@ -23,30 +22,41 @@
#include "colours.h"
SGTexture::SGTexture()
: texture_id(0),
texture_data(0),
num_colors(3)
{
texture_data = 0;
}
SGTexture::SGTexture(unsigned int width, unsigned int height)
: texture_id(0)
{
texture_data = new GLubyte[ width * height * 3 ];
}
SGTexture::~SGTexture()
{
delete texture_data;
if ( texture_data ) {
delete texture_data;
}
if ( texture_id != 0 ) {
free_id();
}
}
void
SGTexture::bind()
{
if (!texture_data) {
bool gen = false;
if (!texture_id) {
#ifdef GL_VERSION_1_1
glGenTextures(1, &texture_id);
#elif GL_EXT_texture_object
glGenTexturesEXT(1, &texture_id);
#endif
gen = true;
}
#ifdef GL_VERSION_1_1
@@ -56,7 +66,7 @@ SGTexture::bind()
glBindTextureEXT(GL_TEXTURE_2D, texture_id);
#endif
if (!texture_data) {
if (gen) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -216,7 +226,7 @@ SGTexture::read_rgb_texture(const char *name)
return;
}
texture_data = new GLubyte[ image->xsize * image->ysize * 3];
texture_data = new GLubyte[ image->xsize * image->ysize * 3 ];
rbuf = new GLubyte[ image->xsize ];
gbuf = new GLubyte[ image->xsize ];
bbuf = new GLubyte[ image->xsize ];
@@ -236,7 +246,7 @@ SGTexture::read_rgb_texture(const char *name)
ImageGetRow(image,rbuf,y,0);
ImageGetRow(image,gbuf,y,1);
ImageGetRow(image,bbuf,y,2);
ImageGetRow(image,abuf,y,3); /* Discard. */
ImageGetRow(image,abuf,y,3); // discard
rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
ptr += (image->xsize * 3);
} else {
@@ -255,6 +265,70 @@ SGTexture::read_rgb_texture(const char *name)
delete abuf;
}
void
SGTexture::read_rgba_texture(const char *name)
{
GLubyte *ptr;
GLubyte *rbuf, *gbuf, *bbuf, *abuf;
SGTexture::ImageRec *image;
int y;
if (texture_data)
delete texture_data;
image = ImageOpen(name);
if(!image)
return;
texture_width = image->xsize;
texture_height = image->ysize;
if (image->zsize != 3 && image->zsize != 4) {
ImageClose(image);
return;
}
texture_data = new GLubyte[ image->xsize * image->ysize * 4 ];
rbuf = new GLubyte[ image->xsize ];
gbuf = new GLubyte[ image->xsize ];
bbuf = new GLubyte[ image->xsize ];
abuf = new GLubyte[ image->xsize ];
if(!texture_data || !rbuf || !gbuf || !bbuf || !abuf) {
delete texture_data;
delete rbuf;
delete gbuf;
delete bbuf;
delete abuf;
return;
}
ptr = texture_data;
memset(abuf, 255, image->xsize);
for(y=0; y<image->ysize; y++) {
if(image->zsize == 4) {
ImageGetRow(image,rbuf,y,0);
ImageGetRow(image,gbuf,y,1);
ImageGetRow(image,bbuf,y,2);
ImageGetRow(image,abuf,y,3);
rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize);
ptr += (image->xsize * 4);
} else {
ImageGetRow(image,rbuf,y,0);
ImageGetRow(image,gbuf,y,1);
ImageGetRow(image,bbuf,y,2);
rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize);
ptr += (image->xsize * 3);
}
}
ImageClose(image);
delete rbuf;
delete gbuf;
delete bbuf;
delete abuf;
}
void
SGTexture::read_raw_texture(const char *name)
{
@@ -327,25 +401,32 @@ SGTexture::read_r8_texture(const char *name)
void
SGTexture::set_pixel(GLuint x, GLuint y, sgVec3 &c)
{
if (!texture_data)
return;
unsigned int pos = (x + y*texture_width)*3;
texture_data[pos] = c[0];
texture_data[pos+1] = c[1];
texture_data[pos+2] = c[2];
texture_data[pos] = (unsigned char)(c[0] * 256);
texture_data[pos+1] = (unsigned char)(c[1] * 256);
texture_data[pos+2] = (unsigned char)(c[2] * 256);
}
sgVec3 *
float *
SGTexture::get_pixel(GLuint x, GLuint y)
{
static sgVec3 c;
sgSetVec3(c, 0, 0, 0);
if (!texture_data)
return c;
unsigned int pos = (x + y*texture_width)*3;
sgSetVec3(c, texture_data[pos], texture_data[pos+1], texture_data[pos+2]);
return &c;
return c;
}
SGTexture::ImageRec *
SGTexture::ImageOpen(const char *fileName)
{
@@ -506,6 +587,19 @@ SGTexture::rgbtorgb(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *l, int n) {
}
}
void
SGTexture::rgbatorgba(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *a,
GLubyte *l, int n) {
while(n--) {
l[0] = r[0];
l[1] = g[0];
l[2] = b[0];
l[3] = a[0];
l += 4; r++; g++; b++; a++;
}
}
void
SGTexture::ConvertShort(unsigned short *array, unsigned int length) {
unsigned short b1, b2;

View File

@@ -1,3 +1,14 @@
/**
* \file texture.hxx
* Texture manipulation routines
*
* Copyright (c) Mark J. Kilgard, 1997.
* Code added in april 2003 by Erik Hofman
*
* This program is freely distributable without licensing fees
* and is provided without guarantee or warrantee expressed or
* implied. This program is -not- in the public domain.
*/
#ifndef __SG_TEXTURE_HXX
#define __SG_TEXTURE_HXX 1
@@ -7,6 +18,10 @@
#include <plib/sg.h>
/**
* A class to encapsulate all the info surrounding an OpenGL texture
* and also query various info and load various file formats
*/
class SGTexture {
private:
@@ -16,6 +31,7 @@ private:
GLsizei texture_width;
GLsizei texture_height;
GLsizei num_colors;
void resize(unsigned int width = 256, unsigned int height = 256);
@@ -40,12 +56,24 @@ protected:
void ConvertUint(unsigned *array, unsigned int length);
void ConvertShort(unsigned short *array, unsigned int length);
void rgbtorgb(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *l, int n);
void rgbatorgba(GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *a,
GLubyte *l, int n);
ImageRec *ImageOpen(const char *fileName);
ImageRec *RawImageOpen(const char *fileName);
void ImageClose(ImageRec *image);
void ImageGetRow(ImageRec *image, GLubyte *buf, int y, int z);
inline void free_id() {
#ifdef GL_VERSION_1_1
glDeleteTextures(1, &texture_id);
#else
glDeleteTexturesEXT(1, &texture_id);
#endif
texture_id = 0;
}
public:
SGTexture();
@@ -55,13 +83,15 @@ public:
/* Copyright (c) Mark J. Kilgard, 1997. */
void read_alpha_texture(const char *name);
void read_rgb_texture(const char *name);
void read_rgba_texture(const char *name);
void read_raw_texture(const char *name);
void read_r8_texture(const char *name);
inline bool usable() { return texture_data ? true : false; }
inline bool usable() { return (texture_id > 0) ? true : false; }
inline GLuint id() { return texture_id; }
inline GLubyte *texture() { return texture_data; }
inline void set_data(GLubyte *data) { texture_data = data; }
inline int width() { return texture_width; }
inline int height() { return texture_height; }
@@ -75,14 +105,27 @@ public:
// texture pixel manipulation functions.
void set_pixel(GLuint x, GLuint y, sgVec3 &c);
sgVec3 *get_pixel(GLuint x, GLuint y);
float *get_pixel(GLuint x, GLuint y);
void bind();
inline void select() {
// if (texture_data)
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB,
texture_width, texture_height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texture_data );
inline void select(bool keep_data = false) {
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB,
texture_width, texture_height, 0,
GL_RGB, GL_UNSIGNED_BYTE, texture_data );
if (!keep_data) {
delete[] texture_data;
texture_data = 0;
}
}
// Nowhere does it say that resident textures have to be in video memory!
// NVidia's OpenGL drivers implement glAreTexturesResident() correctly,
// but the Matrox G400, for example, doesn't.
inline bool is_resident() {
GLboolean is_res;
glAreTexturesResident(1, &texture_id, &is_res);
return is_res;
}
};

View File

@@ -32,6 +32,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/props/condition.hxx>
#include <simgear/math/fastmath.hxx>
#include "sound.hxx"
@@ -41,10 +42,10 @@
static double _snd_inv(double v) { return (v == 0) ? 1e99 : 1/v; }
static double _snd_abs(double v) { return (v >= 0) ? v : -v; }
static double _snd_sqrt(double v) { return (v < 0) ? sqrt(-v) : sqrt(v); }
static double _snd_log10(double v) { return (v < 1) ? 0 : log10(v); }
static double _snd_log(double v) { return (v < 1) ? 0 : log(v); }
// static double _snd_sqr(double v) { return pow(v, 2); }
// static double _snd_pow3(double v) { return pow(v, 3); }
static double _snd_log10(double v) { return (v < 1) ? 0 : fast_log10(v); }
static double _snd_log(double v) { return (v < 1) ? 0 : fast_log(v); }
// static double _snd_sqr(double v) { return v*v; }
// static double _snd_pow3(double v) { return v*v*v; }
static const struct {
char *name;

View File

@@ -20,6 +20,12 @@
//
// $Id$
/**
* \file sound.hxx
* Provides a class to manage a single sound event including things
* like looping, volume and pitch changes.
*/
#ifndef _SG_SOUND_HXX
#define _SG_SOUND_HXX 1
@@ -38,6 +44,10 @@ static const double MAX_TRANSIT_TIME = 0.1; // 100 ms.
/**
* Class for handling one sound event.
*
* This class handles everything for a particular sound event, by
* scanning an a pre-loaded property tree structure for sound
* settings, setting up its internal states, and managing sound
* playback whenever such an event happens.
*/
class SGSound
{
@@ -47,10 +57,58 @@ public:
SGSound();
virtual ~SGSound();
/**
* Initialize the sound event.
*
* Prior to initialization of the sound event the propgrams property root
* has to be defined, the sound configuration XML tree has to be loaded
* and a sound manager class has to be defined.
*
* A sound configuration file would look like this:
* <fx>
* <event_name>
* <name/> Define the name of the event. For refference only.
* <mode/> Either:
* looped: play this sound looped.
* in-transit: play looped while the event is happening.
* once: play this sound once.
* <path/> The relative path to the audio file.
* <property/> Take action if this property becomes true.
* <condition/> Take action if this condition becomes true.
* <volume> or <pitch> Define volume or pitch settings.
* <property/> Take the value of this property as a refference for the
* result.
* <internal/> Either:
* dt_start: the time elapsed since this sound is playing.
* dt_stop: the time elapsed since this sound has stopped.
* <offset/> Add this value to the result.
* <factor/> Multiply the result by this factor.
* <min/> Make sure the value is never less than this value.
* <max/> Make sure the value is never larger than this value.
* </volume> or </pitch>
* </event_name>
*
* <event_name>
* </event_name>
* </fx>
*
* @param root The root node of the programs property tree.
* @param child A pointer to the location of the current event as defined
* in the configuration file.
* @param sndmgr A pointer to a pre-initialized sound manager class.
* @param path The path where the audio files remain.
*/
virtual void init (SGPropertyNode *, SGPropertyNode *, SGSoundMgr *,
const string &);
/**
* Check wheter an event has happened and if action has to be taken.
*/
virtual void update (double dt);
/**
* Stop taking action on the pre-defined events.
*/
void stop();
protected:

View File

@@ -92,7 +92,7 @@ void SGSimpleSound::play( slScheduler *sched, bool looped ) {
sched->addSampleEnvelope(sample, 0, 1, volume_envelope, SL_VOLUME_ENVELOPE);
}
void SGSimpleSound::stop( slScheduler *sched, bool quick ) {
void SGSimpleSound::stop( slScheduler *sched ) {
sched->stopSample( sample );
}
@@ -107,7 +107,7 @@ SGSoundMgr::SGSoundMgr() {
if ( audio_sched->notWorking() ) {
SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
} else {
audio_sched -> setMaxConcurrent ( 6 );
audio_sched -> setMaxConcurrent ( SL_MAX_MIXERINPUTS );
audio_mixer = new smMixer;

View File

@@ -23,6 +23,12 @@
//
// $Id$
/**
* \file soundmgr.hxx
* Provides a sound manager class to keep track of
* multiple sounds and manage playing them with different effects and
* timings.
*/
#ifndef _SG_SOUNDMGR_HXX
#define _SG_SOUNDMGR_HXX 1
@@ -44,7 +50,9 @@ SG_USING_STD(map);
SG_USING_STD(string);
// manages everything we need to know for an individual sound sample
/**
* manages everything we need to know for an individual sound sample
*/
class SGSimpleSound {
private:
@@ -61,28 +69,80 @@ public:
SGSimpleSound( unsigned char *buffer, int len );
~SGSimpleSound();
/**
* Start playing this sample.
*
* @param sched A pointer to the appropriate scheduler.
* @param looped Define wether the sound should be played in a loop.
*/
void play( slScheduler *sched, bool looped );
void stop( slScheduler *sched, bool quick = true );
/**
* Stop playing this sample.
*
* @param sched A pointer to the appropriate scheduler.
*/
void stop( slScheduler *sched );
/**
* Play this sample once.
* @see #play
*/
inline void play_once( slScheduler *sched ) { play( sched, false); }
/**
* Play this sample looped.
* @see #play
*/
inline void play_looped( slScheduler *sched ) { play( sched, true); }
/**
* Test if a sample is curretnly playing.
* @return true if is is playing, false otherwise.
*/
inline bool is_playing( ) {
return ( sample->getPlayCount() > 0 );
}
/**
* Get the current pitch setting of this sample.
*/
inline double get_pitch() const { return pitch; }
/**
* Set the pitch of this sample.
*/
inline void set_pitch( double p ) {
pitch = p;
pitch_envelope->setStep( 0, 0.01, pitch );
}
/**
* Get the current volume setting of this sample.
*/
inline double get_volume() const { return volume; }
/**
* Set the volume of this sample.
*/
inline void set_volume( double v ) {
volume = v;
volume_envelope->setStep( 0, 0.01, volume );
}
/**
* Get a refference to the raw sample.
*/
inline slSample *get_sample() { return sample; }
/**
* Get the pitch envelope setting of this sample.
*/
inline slEnvelope *get_pitch_envelope() { return pitch_envelope; }
/**
* Get the volume envelope setting of this sample.
*/
inline slEnvelope *get_volume_envelope() { return volume_envelope; }
};
@@ -101,6 +161,9 @@ typedef sound_map::iterator sound_map_iterator;
typedef sound_map::const_iterator const_sound_map_iterator;
/**
* Manage a collection of SGSimpleSound instances
*/
class SGSoundMgr
{
@@ -154,43 +217,76 @@ public:
void resume ();
// is audio working?
/**
* is audio working?
*/
inline bool is_working() const { return !audio_sched->notWorking(); }
// reinitialize the sound manager
/**
* reinitialize the sound manager
*/
inline void reinit() { init(); }
// add a sound effect, return true if successful
/**
* add a sound effect, return true if successful
*/
bool add( SGSimpleSound *sound, const string& refname);
// add a sound file, return the sample if successful, else return NULL
/**
* Add a sound file to the sound manager.
*
* The advantage of using this function over the previous one is that
* it doesn't load a sample if it already is in memory, but instead it
* uses the already loaded sample data.
*
* @param refname A refference name to make a distincion between samples.
* @param path The path or full filename of the sample to load.
* @param file An optional filename which will be appended to the path.
* @return An instance of the sound for further manipulation.
*/
SGSimpleSound *add( const string& refname,
const char *path, const char *file = NULL );
// remove a sound effect, return true if successful
/**
* remove a sound effect, return true if successful
*/
bool remove( const string& refname );
// return true of the specified sound exists in the sound manager system
/**
* return true of the specified sound exists in the sound manager system
*/
bool exists( const string& refname );
// return a pointer to the SGSimpleSound if the specified sound
// exists in the sound manager system, otherwise return NULL
SGSimpleSound *find( const string& refname );
/**
* return a pointer to the SGSimpleSound if the specified sound
* exists in the sound manager system, otherwise return NULL
*/
SGSimpleSound *find( const string& refname );
// tell the scheduler to play the indexed sample in a continuous
// loop
/**
* tell the scheduler to play the indexed sample in a continuous
* loop
*/
bool play_looped( const string& refname );
// tell the scheduler to play the indexed sample once
/**
* tell the scheduler to play the indexed sample once
*/
bool play_once( const string& refname );
// return true of the specified sound is currently being played
/**
* return true of the specified sound is currently being played
*/
bool is_playing( const string& refname );
// immediate stop playing the sound
/**
* immediate stop playing the sound
*/
bool stop( const string& refname );
// return the audio scheduler
/**
* return the audio scheduler
*/
inline slScheduler *get_scheduler( ) { return audio_sched; };
};

View File

@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in

View File

@@ -0,0 +1,20 @@
includedir = @includedir@/structure
lib_LIBRARIES = libsgstructure.a
include_HEADERS = \
callback.hxx \
commands.hxx \
exception.hxx \
event_mgr.hxx \
subsystem_mgr.hxx
libsgstructure_a_SOURCES = \
commands.cxx \
exception.cxx \
event_mgr.cxx\
subsystem_mgr.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,148 @@
/**************************************************************************
* callback.hxx -- Wrapper classes to treat function and method pointers
* as objects.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
**************************************************************************/
#ifndef _SG_CALLBACK_HXX
#define _SG_CALLBACK_HXX
/**
* Abstract base class for all callbacks.
*/
class SGCallback
{
public:
/**
*
*/
virtual ~SGCallback() {}
/**
*
*/
virtual SGCallback* clone() const = 0;
/**
* Execute the callback function.
*/
virtual void operator()() = 0;
protected:
/**
*
*/
SGCallback() {}
private:
// Not implemented.
void operator=( const SGCallback& );
};
/**
* Callback for invoking a file scope function.
*/
template< typename Fun >
class SGFunctionCallback : public SGCallback
{
public:
/**
*
*/
SGFunctionCallback( const Fun& fun )
: SGCallback(), f_(fun) {}
SGCallback* clone() const
{
return new SGFunctionCallback( *this );
}
void operator()() { f_(); }
private:
// Not defined.
SGFunctionCallback();
private:
Fun f_;
};
/**
* Callback for invoking a member function.
*/
template< class ObjPtr, typename MemFn >
class SGMethodCallback : public SGCallback
{
public:
/**
*
*/
SGMethodCallback( const ObjPtr& pObj, MemFn pMemFn )
: SGCallback(),
pObj_(pObj),
pMemFn_(pMemFn)
{
}
/**
*
*/
SGCallback* clone() const
{
return new SGMethodCallback( *this );
}
/**
*
*/
void operator()()
{
((*pObj_).*pMemFn_)();
}
private:
// Not defined.
SGMethodCallback();
private:
ObjPtr pObj_;
MemFn pMemFn_;
};
/**
* Helper template functions.
*/
template< typename Fun >
SGCallback*
make_callback( const Fun& fun )
{
return new SGFunctionCallback<Fun>(fun);
}
template< class ObjPtr, typename MemFn >
SGCallback*
make_callback( const ObjPtr& pObj, MemFn pMemFn )
{
return new SGMethodCallback<ObjPtr,MemFn>(pObj, pMemFn );
}
#endif // _SG_CALLBACK_HXX

View File

@@ -0,0 +1,258 @@
//
// SGEventMgr.cxx -- Event Manager
//
// Written by Bernie Bright, started April 2002.
//
// Copyright (C) 2002 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include "event_mgr.hxx"
SGEvent::SGEvent()
: _name(""),
_callback(0),
_subsystem(0),
_repeat_value(0),
_initial_value(0),
_ms_to_go(0),
_cum_time(0),
_min_time(100000),
_max_time(0),
_count(0)
{
}
SGEvent::SGEvent( const char* name,
SGCallback* cb,
interval_type repeat_value,
interval_type initial_value )
: _name(name),
_callback(cb),
_subsystem(NULL),
_repeat_value(repeat_value),
_initial_value(initial_value),
_cum_time(0),
_min_time(100000),
_max_time(0),
_count(0)
{
if (_initial_value < 0)
{
this->run();
_ms_to_go = _repeat_value;
}
else
{
_ms_to_go = _initial_value;
}
}
SGEvent::SGEvent( const char* name,
SGSubsystem* subsystem,
interval_type repeat_value,
interval_type initial_value )
: _name(name),
_callback(NULL),
_subsystem(subsystem),
_repeat_value(repeat_value),
_initial_value(initial_value),
_cum_time(0),
_min_time(100000),
_max_time(0),
_count(0)
{
if (_initial_value < 0)
{
this->run();
_ms_to_go = _repeat_value;
}
else
{
_ms_to_go = _initial_value;
}
}
SGEvent::~SGEvent()
{
//delete callback_;
}
void
SGEvent::run()
{
SGTimeStamp start_time;
SGTimeStamp finish_time;
start_time.stamp();
// run the event
if (_callback)
{
(*_callback)();
} else if (_subsystem)
{
_subsystem->update(_repeat_value);
}
finish_time.stamp();
++_count;
unsigned long duration = finish_time - start_time;
_cum_time += duration;
if ( duration < _min_time ) {
_min_time = duration;
}
if ( duration > _max_time ) {
_max_time = duration;
}
}
void
SGEvent::print_stats() const
{
SG_LOG( SG_EVENT, SG_INFO,
" " << _name
<< " int=" << _repeat_value / 1000.0
<< " cum=" << _cum_time
<< " min=" << _min_time
<< " max=" << _max_time
<< " count=" << _count
<< " ave=" << _cum_time / (double)_count );
}
SGEventMgr::SGEventMgr()
{
}
SGEventMgr::~SGEventMgr()
{
}
void
SGEventMgr::init()
{
SG_LOG( SG_EVENT, SG_INFO, "Initializing event manager" );
event_table.clear();
}
void
SGEventMgr::reinit()
{
}
void
SGEventMgr::bind()
{
}
void
SGEventMgr::unbind()
{
}
void
SGEventMgr::update( double dt )
{
int dt_ms = int(dt * 1000);
if (dt_ms < 0)
{
SG_LOG( SG_GENERAL, SG_ALERT,
"SGEventMgr::update() called with negative delta T" );
return;
}
int min_value = 0;
event_container_type::iterator first = event_table.begin();
event_container_type::iterator last = event_table.end();
event_container_type::iterator event = event_table.end();
// Scan all events. Run one whose interval has expired.
while (first != last)
{
if (first->update( dt_ms ))
{
if (first->value() < min_value)
{
// Select event with largest negative value.
// Its been waiting longest.
min_value = first->value();
event = first;
}
}
++first;
}
if (event != last)
{
event->run();
if (event->repeat_value() > 0)
{
event->reset();
}
else
{
SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting event " << event->name() );
event_table.erase( event );
}
}
}
void
SGEventMgr::add( const SGEvent& event )
{
event_table.push_back( event );
SG_LOG( SG_EVENT, SG_INFO, "registered event " << event.name()
<< " to run every " << event.repeat_value() << "ms" );
}
void
SGEventMgr::print_stats() const
{
SG_LOG( SG_EVENT, SG_INFO, "" );
SG_LOG( SG_EVENT, SG_INFO, "Event Stats" );
SG_LOG( SG_EVENT, SG_INFO, "-----------" );
event_container_type::const_iterator first = event_table.begin();
event_container_type::const_iterator last = event_table.end();
for (; first != last; ++first)
{
first->print_stats();
}
SG_LOG( SG_EVENT, SG_INFO, "" );
}

View File

@@ -0,0 +1,209 @@
// eventmMgr.hxx -- periodic event scheduler
//
// Written by Curtis Olson, started December 1997.
// Modified by Bernie Bright, April 2002.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef SG_EVENT_MGR_HXX
#define SG_EVENT_MGR_HXX 1
#include <simgear/compiler.h>
#include <simgear/structure/callback.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/timing/timestamp.hxx>
#include <vector>
#include <string>
SG_USING_STD(vector);
SG_USING_STD(string);
class SGEvent
{
public:
typedef int interval_type;
private:
string _name;
SGCallback* _callback;
SGSubsystem* _subsystem;
interval_type _repeat_value;
interval_type _initial_value;
int _ms_to_go;
unsigned long _cum_time; // cumulative processor time of this event
unsigned long _min_time; // time of quickest execution
unsigned long _max_time; // time of slowest execution
unsigned long _count; // number of times executed
public:
/**
*
*/
SGEvent();
SGEvent( const char* desc,
SGCallback* cb,
interval_type repeat_value,
interval_type initial_value );
SGEvent( const char* desc,
SGSubsystem* subsystem,
interval_type repeat_value,
interval_type initial_value );
/**
*
*/
~SGEvent();
/**
*
*/
inline void reset()
{
_ms_to_go = _repeat_value;
}
/**
* Execute this event's callback.
*/
void run();
inline string name() const { return _name; }
inline interval_type repeat_value() const { return _repeat_value; }
inline int value() const { return _ms_to_go; }
/**
* Display event statistics.
*/
void print_stats() const;
/**
* Update the elapsed time for this event.
* @param dt_ms elapsed time in milliseconds.
* @return true if elapsed time has expired.
*/
inline bool update( int dt_ms )
{
return (_ms_to_go -= dt_ms) <= 0;
}
};
class SGEventMgr : public SGSubsystem
{
private:
typedef SGEvent::interval_type interval_type;
typedef vector< SGEvent > event_container_type;
void add( const SGEvent& event );
// registered events.
event_container_type event_table;
public:
SGEventMgr();
~SGEventMgr();
/**
* Initialize the scheduling subsystem.
*/
void init();
void reinit();
void bind();
void unbind();
/*
* Update the elapsed time for all events.
* @param dt elapsed time in seconds.
*/
void update( double dt );
/**
* register a free standing function to be executed some time in the future.
* @param desc A brief description of this callback for logging.
* @param cb The callback function to be executed.
* @param repeat_value repetition rate in milliseconds.
* @param initial_value initial delay value in milliseconds. A value of
* -1 means run immediately.
*/
template< typename Fun >
inline void add( const char* name,
const Fun& f,
interval_type repeat_value,
interval_type initial_value = -1 )
{
this->add( SGEvent( name,
make_callback(f),
repeat_value,
initial_value ) );
}
/**
* register a subsystem of which the update function will be executed some
* time in the future.
* @param desc A brief description of this callback for logging.
* @param subsystem The subsystem of which the update function will be
* executed.
* @param repeat_value repetition rate in milliseconds.
* @param initial_value initial delay value in milliseconds. A value of
* -1 means run immediately.
*/
inline void add( const char* name,
SGSubsystem* subsystem,
interval_type repeat_value,
interval_type initial_value = -1 )
{
this->add( SGEvent( name,
subsystem,
repeat_value,
initial_value ) );
}
template< class ObjPtr, typename MemFn >
inline void add( const char* name,
const ObjPtr& p,
MemFn pmf,
interval_type repeat_value,
interval_type initial_value = -1 )
{
this->add( SGEvent( name,
make_callback(p,pmf),
repeat_value,
initial_value ) );
}
/**
* Display statistics for all registered events.
*/
void print_stats() const;
};
#endif //SG_EVENT_MGR_HXX

View File

@@ -86,7 +86,7 @@ sg_location::asString () const
{
char buf[128];
string out = "";
if (_path != (string)"") {
if (!_path.empty()) {
out += _path;
if (_line != -1 || _column != -1)
out += ",\n";

View File

@@ -0,0 +1,333 @@
#include <simgear/debug/logstream.hxx>
#include "exception.hxx"
#include "subsystem_mgr.hxx"
////////////////////////////////////////////////////////////////////////
// Implementation of SGSubsystem
////////////////////////////////////////////////////////////////////////
SGSubsystem::SGSubsystem ()
: _suspended(false)
{
}
SGSubsystem::~SGSubsystem ()
{
}
void
SGSubsystem::init ()
{
}
void
SGSubsystem::reinit ()
{
}
void
SGSubsystem::bind ()
{
}
void
SGSubsystem::unbind ()
{
}
void
SGSubsystem::suspend ()
{
_suspended = true;
}
void
SGSubsystem::suspend (bool suspended)
{
_suspended = suspended;
}
void
SGSubsystem::resume ()
{
_suspended = false;
}
bool
SGSubsystem::is_suspended () const
{
return _suspended;
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGSubsystemGroup.
////////////////////////////////////////////////////////////////////////
SGSubsystemGroup::SGSubsystemGroup ()
{
}
SGSubsystemGroup::~SGSubsystemGroup ()
{
for (unsigned int i = 0; i < _members.size(); i++)
delete _members[i];
}
void
SGSubsystemGroup::init ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->init();
}
void
SGSubsystemGroup::reinit ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->reinit();
}
void
SGSubsystemGroup::bind ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->bind();
}
void
SGSubsystemGroup::unbind ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->unbind();
}
void
SGSubsystemGroup::update (double delta_time_sec)
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->update(delta_time_sec); // indirect call
}
void
SGSubsystemGroup::suspend ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->suspend();
}
void
SGSubsystemGroup::resume ()
{
for (unsigned int i = 0; i < _members.size(); i++)
_members[i]->subsystem->resume();
}
bool
SGSubsystemGroup::is_suspended () const
{
return false;
}
void
SGSubsystemGroup::set_subsystem (const string &name, SGSubsystem * subsystem,
double min_step_sec)
{
Member * member = get_member(name, true);
if (member->subsystem != 0)
delete member->subsystem;
member->name = name;
member->subsystem = subsystem;
member->min_step_sec = min_step_sec;
}
SGSubsystem *
SGSubsystemGroup::get_subsystem (const string &name)
{
Member * member = get_member(name);
if (member != 0)
return member->subsystem;
else
return 0;
}
void
SGSubsystemGroup::remove_subsystem (const string &name)
{
for (unsigned int i = 0; i < _members.size(); i++) {
if (name == _members[i]->name) {
_members.erase(_members.begin() + i);
return;
}
}
}
bool
SGSubsystemGroup::has_subsystem (const string &name) const
{
return (((SGSubsystemGroup *)this)->get_member(name) != 0);
}
SGSubsystemGroup::Member *
SGSubsystemGroup::get_member (const string &name, bool create)
{
for (unsigned int i = 0; i < _members.size(); i++) {
if (_members[i]->name == name)
return _members[i];
}
if (create) {
Member * member = new Member;
_members.push_back(member);
return member;
} else {
return 0;
}
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGSubsystemGroup::Member
////////////////////////////////////////////////////////////////////////
SGSubsystemGroup::Member::Member ()
: name(""),
subsystem(0),
min_step_sec(0),
elapsed_sec(0)
{
}
SGSubsystemGroup::Member::Member (const Member &)
{
Member();
}
SGSubsystemGroup::Member::~Member ()
{
// FIXME: causes a crash
// delete subsystem;
}
void
SGSubsystemGroup::Member::update (double delta_time_sec)
{
elapsed_sec += delta_time_sec;
if (elapsed_sec >= min_step_sec) {
if (!subsystem->is_suspended()) {
subsystem->update(elapsed_sec);
elapsed_sec = 0;
}
}
}
////////////////////////////////////////////////////////////////////////
// Implementation of SGSubsystemMgr.
////////////////////////////////////////////////////////////////////////
SGSubsystemMgr::SGSubsystemMgr ()
{
}
SGSubsystemMgr::~SGSubsystemMgr ()
{
}
void
SGSubsystemMgr::init ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].init();
}
void
SGSubsystemMgr::reinit ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].reinit();
}
void
SGSubsystemMgr::bind ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].bind();
}
void
SGSubsystemMgr::unbind ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].unbind();
}
void
SGSubsystemMgr::update (double delta_time_sec)
{
for (int i = 0; i < MAX_GROUPS; i++) {
_groups[i].update(delta_time_sec);
}
}
void
SGSubsystemMgr::suspend ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].suspend();
}
void
SGSubsystemMgr::resume ()
{
for (int i = 0; i < MAX_GROUPS; i++)
_groups[i].resume();
}
bool
SGSubsystemMgr::is_suspended () const
{
return false;
}
void
SGSubsystemMgr::add (const char * name, SGSubsystem * subsystem,
GroupType group, double min_time_sec)
{
SG_LOG(SG_GENERAL, SG_INFO, "Adding subsystem " << name);
get_group(group)->set_subsystem(name, subsystem, min_time_sec);
if (_subsystem_map.find(name) != _subsystem_map.end()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Adding duplicate subsystem " << name);
throw sg_exception("duplicate subsystem");
}
_subsystem_map[name] = subsystem;
}
SGSubsystemGroup *
SGSubsystemMgr::get_group (GroupType group)
{
return &(_groups[group]);
}
SGSubsystem *
SGSubsystemMgr::get_subsystem (const string &name)
{
map<string,SGSubsystem *>::iterator s =_subsystem_map.find(name);
if (s == _subsystem_map.end())
return 0;
else
return s->second;
}
// end of fgfs.cxx

View File

@@ -0,0 +1,345 @@
// Written by David Megginson, started 2000-12
//
// Copyright (C) 2000 David Megginson, david@megginson.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef __SUBSYSTEM_MGR_HXX
#define __SUBSYSTEM_MGR_HXX 1
#include <simgear/compiler.h>
#if 0
#ifdef HAVE_WINDOWS_H
# include <windows.h>
# include <float.h>
#endif
#include STL_STRING
SG_USING_STD(string);
#include <vector>
SG_USING_STD(vector);
#endif
#include <map>
SG_USING_STD(map);
#include <simgear/props/props.hxx>
/**
* Basic interface for all FlightGear subsystems.
*
* <p>This is an abstract interface that all FlightGear subsystems
* will eventually implement. It defines the basic operations for
* each subsystem: initialization, property binding and unbinding, and
* updating. Interfaces may define additional methods, but the
* preferred way of exchanging information with other subsystems is
* through the property tree.</p>
*
* <p>To publish information through a property, a subsystem should
* bind it to a variable or (if necessary) a getter/setter pair in the
* bind() method, and release the property in the unbind() method:</p>
*
* <pre>
* void MySubsystem::bind ()
* {
* fgTie("/controls/flight/elevator", &_elevator);
* fgSetArchivable("/controls/flight/elevator");
* }
*
* void MySubsystem::unbind ()
* {
* fgUntie("/controls/flight/elevator");
* }
* </pre>
*
* <p>To reference a property (possibly) from another subsystem, there
* are two alternatives. If the property will be referenced only
* infrequently (say, in the init() method), then the fgGet* methods
* declared in fg_props.hxx are the simplest:</p>
*
* <pre>
* void MySubsystem::init ()
* {
* _errorMargin = fgGetFloat("/display/error-margin-pct");
* }
* </pre>
*
* <p>On the other hand, if the property will be referenced frequently
* (say, in the update() method), then the hash-table lookup required
* by the fgGet* methods might be too expensive; instead, the
* subsystem should obtain a reference to the actual property node in
* its init() function and use that reference in the main loop:</p>
*
* <pre>
* void MySubsystem::init ()
* {
* _errorNode = fgGetNode("/display/error-margin-pct", true);
* }
*
* void MySubsystem::update (double delta_time_sec)
* {
* do_something(_errorNode.getFloatValue());
* }
* </pre>
*
* <p>The node returned will always be a pointer to SGPropertyNode,
* and the subsystem should <em>not</em> delete it in its destructor
* (the pointer belongs to the property tree, not the subsystem).</p>
*
* <p>The program may ask the subsystem to suspend or resume
* sim-time-dependent operations; by default, the suspend() and
* resume() methods set the protected variable <var>_suspended</var>,
* which the subsystem can reference in its update() method, but
* subsystems may also override the suspend() and resume() methods to
* take different actions.</p>
*/
class SGSubsystem
{
public:
/**
* Default constructor.
*/
SGSubsystem ();
/**
* Virtual destructor to ensure that subclass destructors are called.
*/
virtual ~SGSubsystem ();
/**
* Initialize the subsystem.
*
* <p>This method should set up the state of the subsystem, but
* should not bind any properties. Note that any dependencies on
* the state of other subsystems should be placed here rather than
* in the constructor, so that FlightGear can control the
* initialization order.</p>
*/
virtual void init ();
/**
* Reinitialize the subsystem.
*
* <p>This method should cause the subsystem to reinitialize itself,
* and (normally) to reload any configuration files.</p>
*/
virtual void reinit ();
/**
* Acquire the subsystem's property bindings.
*
* <p>This method should bind all properties that the subsystem
* publishes. It will be invoked after init, but before any
* invocations of update.</p>
*/
virtual void bind ();
/**
* Release the subsystem's property bindings.
*
* <p>This method should release all properties that the subsystem
* publishes. It will be invoked by FlightGear (not the destructor)
* just before the subsystem is removed.</p>
*/
virtual void unbind ();
/**
* Update the subsystem.
*
* <p>FlightGear invokes this method every time the subsystem should
* update its state.</p>
*
* @param delta_time_sec The delta time, in seconds, since the last
* update. On first update, delta time will be 0.
*/
virtual void update (double delta_time_sec) = 0;
/**
* Suspend operation of this subsystem.
*
* <p>This method instructs the subsystem to suspend
* sim-time-dependent operations until asked to resume. The update
* method will still be invoked so that the subsystem can take any
* non-time-dependent actions, such as updating the display.</p>
*
* <p>It is not an error for the suspend method to be invoked when
* the subsystem is already suspended; the invocation should simply
* be ignored.</p>
*/
virtual void suspend ();
/**
* Suspend or resum operation of this subsystem.
*
* @param suspended true if the subsystem should be suspended, false
* otherwise.
*/
virtual void suspend (bool suspended);
/**
* Resume operation of this subsystem.
*
* <p>This method instructs the subsystem to resume
* sim-time-depended operations. It is not an error for the resume
* method to be invoked when the subsystem is not suspended; the
* invocation should simply be ignored.</p>
*/
virtual void resume ();
/**
* Test whether this subsystem is suspended.
*
* @return true if the subsystem is suspended, false if it is not.
*/
virtual bool is_suspended () const;
protected:
bool _suspended;
};
/**
* A group of FlightGear subsystems.
*/
class SGSubsystemGroup : public SGSubsystem
{
public:
SGSubsystemGroup ();
virtual ~SGSubsystemGroup ();
virtual void init ();
virtual void reinit ();
virtual void bind ();
virtual void unbind ();
virtual void update (double delta_time_sec);
virtual void suspend ();
virtual void resume ();
virtual bool is_suspended () const;
virtual void set_subsystem (const string &name,
SGSubsystem * subsystem,
double min_step_sec = 0);
virtual SGSubsystem * get_subsystem (const string &name);
virtual void remove_subsystem (const string &name);
virtual bool has_subsystem (const string &name) const;
private:
struct Member {
Member ();
Member (const Member &member);
virtual ~Member ();
virtual void update (double delta_time_sec);
string name;
SGSubsystem * subsystem;
double min_step_sec;
double elapsed_sec;
};
Member * get_member (const string &name, bool create = false);
vector<Member *> _members;
};
/**
* Manage subsystems for FlightGear.
*
* This top-level subsystem will eventually manage all of the
* subsystems in FlightGear: it broadcasts its life-cycle events
* (init, bind, etc.) to all of the subsystems it manages. Subsystems
* are grouped to guarantee order of initialization and execution --
* currently, the only two groups are INIT and GENERAL, but others
* will appear in the future.
*
* All subsystems are named as well as grouped, and subsystems can be
* looked up by name and cast to the appropriate subtype when another
* subsystem needs to invoke specialized methods.
*
* The subsystem manager owns the pointers to all the subsystems in
* it.
*/
class SGSubsystemMgr : public SGSubsystem
{
public:
/**
* Types of subsystem groups.
*/
enum GroupType {
INIT = 0,
GENERAL,
MAX_GROUPS
};
SGSubsystemMgr ();
virtual ~SGSubsystemMgr ();
virtual void init ();
virtual void reinit ();
virtual void bind ();
virtual void unbind ();
virtual void update (double delta_time_sec);
virtual void suspend ();
virtual void resume ();
virtual bool is_suspended () const;
virtual void add (const char * name,
SGSubsystem * subsystem,
GroupType group = GENERAL,
double min_time_sec = 0);
virtual SGSubsystemGroup * get_group (GroupType group);
virtual SGSubsystem * get_subsystem(const string &name);
private:
SGSubsystemGroup _groups[MAX_GROUPS];
map<string,SGSubsystem *> _subsystem_map;
};
#endif // __SUBSYSTEM_MGR_HXX

View File

@@ -5,6 +5,9 @@
#else
# include <sys/time.h>
#endif
#if _MSC_VER >= 1300
# include "winsock2.h"
#endif
#include "SGThread.hxx"

View File

@@ -22,7 +22,7 @@
/*************************************************************************
*
* This file defines a small and simple class to store geocentric
* coordinates. Basically, class GeoCoord is intended as a base class for
* coordinates. Basically, class SGGeoCoord is intended as a base class for
* any kind of of object, that can be categorized according to its
* location on earth, be it navaids, or aircraft. This class for originally
* written for FlightGear, in order to store Timezone control points.
@@ -31,13 +31,13 @@
#include "geocoord.h"
#include <plib/sg.h>
GeoCoord::GeoCoord(const GeoCoord& other)
SGGeoCoord::SGGeoCoord(const SGGeoCoord& other)
{
lat = other.lat;
lon = other.lon;
}
// double GeoCoord::getAngle(const GeoCoord& other) const
// double SGGeoCoord::getAngle(const SGGeoCoord& other) const
// {
// Vector first( getX(), getY(), getZ());
// Vector secnd(other.getX(), other.getY(), other.getZ());
@@ -57,11 +57,11 @@ GeoCoord::GeoCoord(const GeoCoord& other)
// return angle;
// }
// GeoCoord* GeoCoordContainer::getNearest(const GeoCoord& ref) const
// SGGeoCoord* SGGeoCoordContainer::getNearest(const SGGeoCoord& ref) const
// {
// float angle, maxAngle = 180;
// GeoCoordVectorConstIterator i, nearest;
// SGGeoCoordVectorConstIterator i, nearest;
// for (i = data.begin(); i != data.end(); i++)
// {
// angle = SGD_RADIANS_TO_DEGREES * (*i)->getAngle(ref);
@@ -75,12 +75,12 @@ GeoCoord::GeoCoord(const GeoCoord& other)
// }
GeoCoord* GeoCoordContainer::getNearest(const GeoCoord& ref) const
SGGeoCoord* SGGeoCoordContainer::getNearest(const SGGeoCoord& ref) const
{
sgVec3 first, secnd;
float dist, maxDist=SG_MAX;
sgSetVec3( first, ref.getX(), ref.getY(), ref.getZ());
GeoCoordVectorConstIterator i, nearest;
SGGeoCoordVectorConstIterator i, nearest;
for (i = data.begin(); i != data.end(); i++)
{
sgSetVec3(secnd, (*i)->getX(), (*i)->getY(), (*i)->getZ());
@@ -95,9 +95,9 @@ GeoCoord* GeoCoordContainer::getNearest(const GeoCoord& ref) const
}
GeoCoordContainer::~GeoCoordContainer()
SGGeoCoordContainer::~SGGeoCoordContainer()
{
GeoCoordVectorIterator i = data.begin();
SGGeoCoordVectorIterator i = data.begin();
while (i != data.end())
delete *i++;
}

View File

@@ -47,17 +47,17 @@ SG_USING_NAMESPACE(std);
#include <simgear/constants.h>
class GeoCoord
class SGGeoCoord
{
protected:
float lat;
float lon;
public:
GeoCoord() { lat = 0.0; lon = 0.0;};
GeoCoord(float la, float lo) { lat = la; lon = lo;};
GeoCoord(const GeoCoord& other);
virtual ~GeoCoord() {};
SGGeoCoord() { lat = 0.0; lon = 0.0;};
SGGeoCoord(float la, float lo) { lat = la; lon = lo;};
SGGeoCoord(const SGGeoCoord& other);
virtual ~SGGeoCoord() {};
void set(float la, float lo) { lat = la; lon = lo; };
float getLat() const { return lat; };
@@ -67,32 +67,32 @@ public:
float getZ() const { return sin(SGD_DEGREES_TO_RADIANS*lat); };
//double getAngle(const GeoCoord& other) const;
//double getAngle(const SGGeoCoord& other) const;
virtual void print() {} ;
virtual const char * getDescription() {return 0;};
};
typedef vector<GeoCoord*> GeoCoordVector;
typedef vector<GeoCoord*>::iterator GeoCoordVectorIterator;
typedef vector<GeoCoord*>::const_iterator GeoCoordVectorConstIterator;
typedef vector<SGGeoCoord*> SGGeoCoordVector;
typedef vector<SGGeoCoord*>::iterator SGGeoCoordVectorIterator;
typedef vector<SGGeoCoord*>::const_iterator SGGeoCoordVectorConstIterator;
/************************************************************************
* GeoCoordContainer is a simple container class, that stores objects
* derived from GeoCoord. Basically, it is a wrapper around an STL vector,
* SGGeoCoordContainer is a simple container class, that stores objects
* derived from SGGeoCoord. Basically, it is a wrapper around an STL vector,
* with some added functionality
***********************************************************************/
class GeoCoordContainer
class SGGeoCoordContainer
{
protected:
GeoCoordVector data;
SGGeoCoordVector data;
public:
GeoCoordContainer() {};
virtual ~GeoCoordContainer();
SGGeoCoordContainer() {};
virtual ~SGGeoCoordContainer();
const GeoCoordVector& getData() const { return data; };
GeoCoord* getNearest(const GeoCoord& ref) const;
const SGGeoCoordVector& getData() const { return data; };
SGGeoCoord* getNearest(const SGGeoCoord& ref) const;
};

View File

@@ -71,7 +71,7 @@ static const double J2000 = 2451545.0 - MJD0;
static const double SIDRATE = 0.9972695677;
void SGTime::init( double lon, double lat,
void SGTime::init( double lon_rad, double lat_rad,
const string& root, time_t init_time )
{
SG_LOG( SG_EVENT, SG_INFO, "Initializing Time" );
@@ -94,10 +94,10 @@ void SGTime::init( double lon, double lat,
zone.append( "zone.tab" );
SG_LOG( SG_EVENT, SG_INFO, "Reading timezone info from: "
<< zone.str() );
tzContainer = new TimezoneContainer( zone.c_str() );
tzContainer = new SGTimeZoneContainer( zone.c_str() );
GeoCoord location( SGD_RADIANS_TO_DEGREES * lat, SGD_RADIANS_TO_DEGREES * lon );
GeoCoord* nearestTz = tzContainer->getNearest(location);
SGGeoCoord location( SGD_RADIANS_TO_DEGREES * lat_rad, SGD_RADIANS_TO_DEGREES * lon_rad );
SGGeoCoord* nearestTz = tzContainer->getNearest(location);
SGPath name( root );
name.append( nearestTz->getDescription() );
@@ -110,9 +110,10 @@ void SGTime::init( double lon, double lat,
}
}
SGTime::SGTime( double lon, double lat, const string& root, time_t init_time )
SGTime::SGTime( double lon_rad, double lat_rad, const string& root,
time_t init_time )
{
init( lon, lat, root, init_time );
init( lon_rad, lat_rad, root, init_time );
}
@@ -129,7 +130,7 @@ SGTime::SGTime() {
SGTime::~SGTime()
{
if ( tzContainer != NULL ) {
TimezoneContainer *tmp = tzContainer;
SGTimeZoneContainer *tmp = tzContainer;
tzContainer = NULL;
delete tmp;
}
@@ -196,7 +197,9 @@ static double sidereal_course( time_t cur_time, const struct tm *gmt, double lng
// Update the time related variables
void SGTime::update( double lon, double lat, time_t ct, long int warp ) {
void SGTime::update( double lon_rad, double lat_rad,
time_t ct, long int warp )
{
double gst_precise, gst_course;
#if defined(_MSC_VER) || defined(__MINGW32__)
@@ -251,47 +254,52 @@ void SGTime::update( double lon, double lat, time_t ct, long int warp ) {
gst_diff = gst_precise - gst_course;
lst = sidereal_course( cur_time, gmt, -(lon * SGD_RADIANS_TO_DEGREES) ) + gst_diff;
lst = sidereal_course( cur_time, gmt,
-(lon_rad * SGD_RADIANS_TO_DEGREES) ) + gst_diff;
} else {
// course + difference should drift off very slowly
gst = sidereal_course( cur_time, gmt, 0.00 ) + gst_diff;
lst = sidereal_course( cur_time, gmt, -(lon * SGD_RADIANS_TO_DEGREES) ) + gst_diff;
lst = sidereal_course( cur_time, gmt,
-(lon_rad * SGD_RADIANS_TO_DEGREES) ) + gst_diff;
}
SG_LOG( SG_EVENT, SG_DEBUG,
" Current lon=0.00 Sidereal Time = " << gst );
SG_LOG( SG_EVENT, SG_DEBUG,
" Current LOCAL Sidereal Time = " << lst << " ("
<< sidereal_precise( mjd, -(lon * SGD_RADIANS_TO_DEGREES) )
<< sidereal_precise( mjd, -(lon_rad * SGD_RADIANS_TO_DEGREES) )
<< ") (diff = " << gst_diff << ")" );
}
// Given lon/lat, update timezone information and local_offset
void SGTime::updateLocal( double lon, double lat, const string& root ) {
void SGTime::updateLocal( double lon_rad, double lat_rad, const string& root ) {
// sanity checking
if ( lon < -SGD_PI || lon > SGD_PI ) {
if ( lon_rad < -SGD_PI || lon_rad> SGD_PI ) {
// not within -180 ... 180
lon = 0.0;
lon_rad = 0.0;
}
if ( lat < -SGD_PI * 0.5 || lat > SGD_PI * 0.5 ) {
if ( lat_rad < -SGD_PI * 0.5 || lat_rad > SGD_PI * 0.5 ) {
// not within -90 ... 90
lat = 0.0;
lat_rad = 0.0;
}
if ( lon != lon ) {
// only true if lon == nan
SG_LOG( SG_EVENT, SG_ALERT, " Detected lon == nan, resetting to 0.0" );
lon = 0.0;
if ( lon_rad != lon_rad ) {
// only true if lon_rad == nan
SG_LOG( SG_EVENT, SG_ALERT,
" Detected lon_rad == nan, resetting to 0.0" );
lon_rad = 0.0;
}
if ( lat != lat ) {
// only true if lat == nan
SG_LOG( SG_EVENT, SG_ALERT, " Detected lat == nan, resetting to 0.0" );
lat = 0.0;
if ( lat_rad != lat_rad ) {
// only true if lat_rad == nan
SG_LOG( SG_EVENT, SG_ALERT,
" Detected lat_rad == nan, resetting to 0.0" );
lat_rad = 0.0;
}
time_t currGMT;
time_t aircraftLocalTime;
GeoCoord location( SGD_RADIANS_TO_DEGREES * lat, SGD_RADIANS_TO_DEGREES * lon );
GeoCoord* nearestTz = tzContainer->getNearest(location);
SGGeoCoord location( SGD_RADIANS_TO_DEGREES * lat_rad,
SGD_RADIANS_TO_DEGREES * lon_rad );
SGGeoCoord* nearestTz = tzContainer->getNearest(location);
SGPath zone( root );
zone.append ( nearestTz->getDescription() );
zonename = zone.str();

View File

@@ -69,7 +69,7 @@ class SGTime {
private:
// tzContainer stores all the current Timezone control points/
TimezoneContainer* tzContainer;
SGTimeZoneContainer* tzContainer;
// Points to the current local timezone name;
string zonename;
@@ -104,6 +104,10 @@ private:
// gst_diff has pretty good accuracy over the span of a couple hours
double gst_diff;
/** init common constructor code */
void init( double lon_rad, double lat_rad, const string& root,
time_t init_time );
public:
/** Default constructor */
@@ -120,12 +124,13 @@ public:
* If you don't know your position when you call the SGTime
* constructor, you can just use the first form (which assumes 0,
* 0).
* @param lon current longitude
* @param lat current latitude
* @param lon_rad current longitude (radians)
* @param lat_rad current latitude (radians)
* @param root root path point to data file location (timezone, etc.)
* @param init_time provide an initialization time, 0 means use
current clock time */
SGTime( double lon, double lat, const string& root, time_t init_time /* = 0 */ );
SGTime( double lon_rad, double lat_rad, const string& root,
time_t init_time );
/**
* Create an instance given a data file path.
@@ -136,9 +141,6 @@ public:
/** Destructor */
~SGTime();
/** init common constructor code */
void init( double lon, double lat, const string& root, time_t init_time /* = 0 */ );
/**
* Update the time related variables.
* The update() method requires you to pass in your position and
@@ -146,13 +148,13 @@ public:
* you to offset "sim" time relative to "real" time. The update()
* method is designed to be called by the host application before
* every frame.
* @param lon current longitude
* @param lat current latitude
* @param lon_rad current longitude (radians)
* @param lat_rad current latitude (radians)
* @param ct specify a unix time, otherwise specify 0 to use current
clock time
* @param warp an optional time offset specified in seconds. This
* allows us to advance or rewind "time" if we choose to. */
void update( double lon, double lat, time_t ct /* = 0 */, long int warp /* = 0 */ );
void update( double lon_rad, double lat_rad, time_t ct, long int warp );
/**
* Given lon/lat, update timezone information and local_offset
@@ -161,10 +163,10 @@ public:
* enough that your timezone may have changed as well. In the
* FlightGear project we call updateLocal() every few minutes from
* our periodic event manager.
* @param lon current longitude
* @param lat current latitude
* @param lon_rad current longitude (radians)
* @param lat_rad current latitude (radians)
* @param root base path containing time zone directory */
void updateLocal( double lon, double lat, const string& root );
void updateLocal( double lon_rad, double lat_rad, const string& root );
/** @return current system/unix time in seconds */
inline time_t get_cur_time() const { return cur_time; };

Some files were not shown because too many files have changed in this diff Show More