Compare commits
113 Commits
RELEASE_0_
...
RELEASE_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d915ccec6e | ||
|
|
ea1b70191c | ||
|
|
19815c3bce | ||
|
|
66fb6b5a1c | ||
|
|
94ac87f4f5 | ||
|
|
79d5bf66a7 | ||
|
|
a4535c92c3 | ||
|
|
cecdb15692 | ||
|
|
3c08eae85b | ||
|
|
db928ea1ae | ||
|
|
bb002356b4 | ||
|
|
431e78cf09 | ||
|
|
81b9ec50b0 | ||
|
|
e0ba803ca9 | ||
|
|
7ae57483f3 | ||
|
|
d22640ef4e | ||
|
|
f3eeeb760f | ||
|
|
695e112039 | ||
|
|
133e67adb8 | ||
|
|
6079cd3df8 | ||
|
|
6f4fd2dc6e | ||
|
|
b30eb9c00c | ||
|
|
1236d8be19 | ||
|
|
cb35ecb4b0 | ||
|
|
54550aa002 | ||
|
|
d3db963dce | ||
|
|
1dde23a0c9 | ||
|
|
5feccc73c7 | ||
|
|
1cf13a7c1a | ||
|
|
7289ac645a | ||
|
|
699909f808 | ||
|
|
344610e24b | ||
|
|
092901b9ea | ||
|
|
3ac6b34f4b | ||
|
|
d56b961c47 | ||
|
|
858a73e187 | ||
|
|
1623aee1e0 | ||
|
|
c0a633ea1d | ||
|
|
5628c85b51 | ||
|
|
2e1accc0f3 | ||
|
|
93b747f1ba | ||
|
|
21c16b4a51 | ||
|
|
e5e1e165b9 | ||
|
|
8ae39ae8d4 | ||
|
|
110e01a861 | ||
|
|
578e774778 | ||
|
|
d7d13e458c | ||
|
|
0bf579cf27 | ||
|
|
77cefa924c | ||
|
|
1fe26901af | ||
|
|
0dd50cf3d8 | ||
|
|
54b3c711c3 | ||
|
|
f404161d23 | ||
|
|
5a13068aaa | ||
|
|
32067b9adf | ||
|
|
ea2f5f0035 | ||
|
|
ea6540ef90 | ||
|
|
1d5c1de5d3 | ||
|
|
4b11d87a22 | ||
|
|
c2149f9ea6 | ||
|
|
73a4994cac | ||
|
|
c9a4a6975c | ||
|
|
1a1aa37a0e | ||
|
|
7d3abdc512 | ||
|
|
db4c2243e3 | ||
|
|
6dc243e1af | ||
|
|
adb5fb3bee | ||
|
|
7955319771 | ||
|
|
3da76522f8 | ||
|
|
c9ac1b5a06 | ||
|
|
51dff6b537 | ||
|
|
1f4b55e98e | ||
|
|
229ea27050 | ||
|
|
505b4c434d | ||
|
|
12ab6872ec | ||
|
|
4c78e887e1 | ||
|
|
8871655a9b | ||
|
|
db1966c156 | ||
|
|
d4c0c8940b | ||
|
|
d4134195ea | ||
|
|
a8fd1b4c16 | ||
|
|
086473c8eb | ||
|
|
5642ef61ca | ||
|
|
fec7c62b17 | ||
|
|
e046b1bfdb | ||
|
|
01007986dc | ||
|
|
ad56ba1bfa | ||
|
|
54c2d5a6cc | ||
|
|
25ad84e5cb | ||
|
|
dcdf8a4d5c | ||
|
|
5d24be8c51 | ||
|
|
fa42efcf91 | ||
|
|
7f4f778bb1 | ||
|
|
8a2e5cace8 | ||
|
|
23c66b6cfe | ||
|
|
b65fe814a0 | ||
|
|
e74c8587bd | ||
|
|
ab34b86574 | ||
|
|
011ecd980d | ||
|
|
9ca1c6666e | ||
|
|
ba5316ca8e | ||
|
|
f957227576 | ||
|
|
70f763dbe0 | ||
|
|
f8201e6478 | ||
|
|
e053941467 | ||
|
|
17e2478522 | ||
|
|
17df7141ae | ||
|
|
5167dee0e3 | ||
|
|
a1a596b02a | ||
|
|
27f98d24eb | ||
|
|
51ef4568dd | ||
|
|
4c731de8b7 | ||
|
|
fc692cb540 |
4
Doxyfile
4
Doxyfile
@@ -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
|
||||
|
||||
@@ -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...
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
33
NEWS
@@ -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
|
||||
|
||||
|
||||
285
README.metakit
285
README.metakit
@@ -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>
|
||||
1013
SimGear.dsp
1013
SimGear.dsp
File diff suppressed because it is too large
Load Diff
160
configure.ac
160
configure.ac
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
43
simgear/compatibility/IRIX
Normal file
43
simgear/compatibility/IRIX
Normal 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
|
||||
@@ -28,4 +28,6 @@ include_HEADERS = \
|
||||
ctime \
|
||||
iomanip \
|
||||
new \
|
||||
streambuf
|
||||
streambuf \
|
||||
\
|
||||
IRIX
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace std {
|
||||
using ::setw;
|
||||
|
||||
inline int setfill(int f) { ::setfill(f); }
|
||||
};
|
||||
|
||||
#endif // !__SG_IOMANIP
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@ lib_LIBRARIES = libsgephem.a
|
||||
|
||||
include_HEADERS = \
|
||||
celestialBody.hxx \
|
||||
ephemeris.hxx \
|
||||
ephemeris.hxx \
|
||||
jupiter.hxx \
|
||||
mars.hxx \
|
||||
mercury.hxx \
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
65
simgear/math/fastmath.cxx
Normal 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
69
simgear/math/fastmath.hxx
Normal 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) )
|
||||
{
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 = "
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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] == '_') {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
includedir = @includedir@/scene/sky
|
||||
|
||||
# SUBDIRS = clouds3d
|
||||
SUBDIRS = clouds3d
|
||||
|
||||
lib_LIBRARIES = libsgsky.a
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "SkyUtil.hpp"
|
||||
#include "SkySingleton.hpp"
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/glu.h>
|
||||
|
||||
#include "glut_shapes.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef _MSC_VER
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "vec4f.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "SkyMinMaxBox.hpp"
|
||||
#include "camutils.hpp"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "SkyRenderableInstanceGroup.hpp"
|
||||
#include "SkySceneManager.hpp"
|
||||
|
||||
@@ -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 () ;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#define __glext_h_
|
||||
#define __GLEXT_H_
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
609
simgear/scene/sky/clouds3d/glut_shapes.c
Normal file
609
simgear/scene/sky/clouds3d/glut_shapes.c
Normal 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 */
|
||||
43
simgear/scene/sky/clouds3d/glut_shapes.h
Normal file
43
simgear/scene/sky/clouds3d/glut_shapes.h
Normal 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
|
||||
@@ -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; }
|
||||
|
||||
@@ -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] << " "
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <limits.h>
|
||||
#include <string.h> // memcpy()
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "GLBitmaps.h"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
99
simgear/screen/extensions.cxx
Normal file
99
simgear/screen/extensions.cxx
Normal 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
|
||||
157
simgear/screen/extensions.hxx
Normal file
157
simgear/screen/extensions.hxx
Normal 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
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include GLUT_H
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "screen-dump.hxx"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; };
|
||||
};
|
||||
|
||||
|
||||
3
simgear/structure/.cvsignore
Normal file
3
simgear/structure/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
20
simgear/structure/Makefile.am
Normal file
20
simgear/structure/Makefile.am
Normal 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)
|
||||
|
||||
148
simgear/structure/callback.hxx
Normal file
148
simgear/structure/callback.hxx
Normal 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
|
||||
|
||||
258
simgear/structure/event_mgr.cxx
Normal file
258
simgear/structure/event_mgr.cxx
Normal 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, "" );
|
||||
}
|
||||
209
simgear/structure/event_mgr.hxx
Normal file
209
simgear/structure/event_mgr.hxx
Normal 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
|
||||
@@ -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";
|
||||
333
simgear/structure/subsystem_mgr.cxx
Normal file
333
simgear/structure/subsystem_mgr.cxx
Normal 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
|
||||
345
simgear/structure/subsystem_mgr.hxx
Normal file
345
simgear/structure/subsystem_mgr.hxx
Normal 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
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#if _MSC_VER >= 1300
|
||||
# include "winsock2.h"
|
||||
#endif
|
||||
|
||||
#include "SGThread.hxx"
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user