Compare commits

..

24 Commits

Author SHA1 Message Date
curt
afc2099865 Updated news. 2000-07-03 17:50:03 +00:00
curt
7d251444e6 Tweaks for 0.0.11 release. 2000-07-03 17:45:30 +00:00
curt
1c2289dacd Initial revision. 2000-07-03 15:07:33 +00:00
curt
044ac5d5d3 Just a few more visibility tweaks and clean ups. 2000-06-30 22:16:41 +00:00
curt
38167ed273 Oops, a couple more sky tweaks. 2000-06-30 21:51:12 +00:00
curt
e15ffbc856 Updates to remove unneeded dependencies on FlightGear and SimGear. 2000-06-30 19:45:24 +00:00
curt
6cf2716615 Updates to cloud code to add different basic cloud types. This isn't the
final list of cloud types, but servers as an example / template for someone
who wants to tweak this out and do it right.
2000-06-23 02:55:57 +00:00
curt
0468b315d4 A couple more cloud tweaks. 2000-06-20 21:44:04 +00:00
curt
de66c74a91 Updating cloud code. 2000-06-20 20:31:48 +00:00
curt
7db73cd215 Cloud texcoord fixes to tie apparent cloud position to earth even though
the whole cloud structure is actual tied to ownship movement.
2000-06-20 02:49:03 +00:00
curt
242eceb1c6 Added a spherical course & dist given two points routine. 2000-06-20 02:46:42 +00:00
curt
c2b84db5a2 Moving cloud functionality to sky section. 2000-06-20 00:30:30 +00:00
curt
487bee35ab Initial revision. 2000-06-20 00:27:53 +00:00
curt
9fabeb77bc Metakit seems to really want to #define bool int, #define true 1,
#define false 0, so I massaged the header files to make this impossible.
2000-06-19 17:06:35 +00:00
curt
bfea2dec4d Initial revision. 2000-06-19 17:05:41 +00:00
curt
2ed07850c6 Math/bucket/tiling updates contributed by Norman Vine.
Texture coordinate calculation updates by Curt.
2000-06-16 00:28:19 +00:00
curt
b72d36d96f Minor fiddling with material properties *trying* to chase down a visual bug
where the scene get's brighter or dimmer depending on whether or not the sun
or moon is in the field of view.
2000-06-01 19:14:06 +00:00
curt
e3ff048ff6 First quick hack at panel shading. 2000-05-27 04:40:55 +00:00
curt
ceef43681d First stab at replacing gdbm with metakit. 2000-05-27 03:43:44 +00:00
curt
3ec00676e4 Initial revision. 2000-05-25 16:45:19 +00:00
curt
e6575fb1db MSVC5 portability changes contributed by Bruce Finney. 2000-05-24 04:10:01 +00:00
curt
fa98d733d6 Updated for version 0.0.9 2000-05-24 01:30:42 +00:00
curt
2981a10e62 Updated for MSVC5. 2000-05-24 01:30:18 +00:00
curt
551c06f885 Updates for MSVC5 2000-05-24 01:29:13 +00:00
34 changed files with 2719 additions and 172 deletions

View File

@@ -2,6 +2,94 @@ EXTRA_DIST = mksymlinks.sh acsite.m4 acconfig.h
SUBDIRS = simgear
#
# Additional all, clean, and distclean rules for additional packages.
# We can't just include the additional package dirs in SUBDIRS (which
# would be nice because there are then problems with make dist
#
all:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
install:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
clean:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
distclean:
@list='@subdirs@'; \
target=`echo $@`; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done
#
# distclean the associated packages and include them in the dist
#
dist-hook:
tar cf - simgear/metar | (cd $(distdir); tar xvf -)
@list='@subdirs@'; \
target=distclean; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) echo "distclean error ignored...";; *k*) fail=yes;; *) echo "distclean error ignored...";; esac; \
done
tar cf - simgear/metakit | (cd $(distdir); tar xvf -)
#
# Rule to build RPM distribution package
#
@@ -9,6 +97,3 @@ rpm: dist
cp $(PACKAGE)-$(VERSION).tar.gz /usr/src/packages/SOURCES
rpm -ba @PACKAGE@.spec
dist-hook:
tar cf - simgear/metar | (cd $(distdir); tar xvf -)

8
NEWS
View File

@@ -1,3 +1,11 @@
New in 0.0.11
* July 3, 2000
* Replaced gdbm with metakit
* Added drop in sky (depends on plib)
* Added spherical course and dist given two points calculations
* MSVC5 fixes
* Math/bucket/tiling tweaks from Norman Vine
New in 0.0.7
* March 29, 2000
* Added support for RedHat package building contributed by Habibie

3
README
View File

@@ -0,0 +1,3 @@
MSVC5 users:
Copy simgear/config.h.vc5 to simgear/config.h before building.

243
README.metakit Normal file
View File

@@ -0,0 +1,243 @@
With the author's permission, SimGear now bundles MetaKit. MetaKit is
explained
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>

View File

@@ -182,7 +182,7 @@
#undef HAVE_WAIT3
/* Define if you have gdbm installed system wide. */
#undef HAVE_GDBM
/* #undef HAVE_GDBM */
/* Define if you have zlib installed system wide. */
#undef HAVE_ZLIB

View File

@@ -6,7 +6,7 @@ dnl $Id$
AC_INIT(simgear/bucket/newbucket.cxx)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.0.8)
AM_INIT_AUTOMAKE(SimGear, 0.0.11)
dnl Checks for programs.
AC_PROG_MAKE_SET
@@ -24,11 +24,6 @@ else
fi
dnl Run configure in the gdbm subdir
dnl AC_CONFIG_SUBDIRS( simgear/gdbm )
dnl Specify if we want logging (testing build) or not (release build)
# set logging default value
# with_logging=yes
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
@@ -200,14 +195,26 @@ if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
exit
fi
dnl Check for system installed gdbm
AC_CHECK_HEADER(gdbm.h)
if test "x$ac_cv_header_gdbm_h" = "xyes"; then
AC_DEFINE( HAVE_GDBM )
else
echo "no gdbm found, configuring and building."
# dnl Check for system installed gdbm
# AC_CHECK_HEADER(gdbm.h)
# if test "x$ac_cv_header_gdbm_h" = "xyes"; then
# AC_DEFINE( HAVE_GDBM )
# else
# echo "no gdbm found, configuring and building."
# fi
# AM_CONDITIONAL(HAVE_GDBM, test "x$ac_cv_header_gdbm_h" = "xyes" )
dnl Check for system installed metakit
AC_CHECK_HEADER(mk4.h)
if test "x$ac_cv_header_mk4_h" != "xyes"; then
echo "no metakit found, configuring and building."
# Run configure in the metakit subdir
AC_CONFIG_SUBDIRS( simgear/metakit/unix )
fi
AM_CONDITIONAL(HAVE_GDBM, test "x$ac_cv_header_gdbm_h" = "xyes" )
AM_CONDITIONAL(HAVE_METAKIT, test "x$ac_cv_header_mk4_h" = "xyes" )
dnl Specify if we want logging (testing build) or not (release build)
dnl Check for system installed zlib
AC_CHECK_HEADER(zlib.h)
@@ -245,20 +252,20 @@ AC_OUTPUT( \
simgear/version.h \
simgear/bucket/Makefile \
simgear/debug/Makefile \
simgear/gdbm/Makefile \
simgear/magvar/Makefile \
simgear/math/Makefile \
simgear/misc/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sky/Makefile \
simgear/xgl/Makefile \
simgear/zlib/Makefile \
)
AC_OUTPUT_COMMANDS([
if test "x$ac_cv_header_windows_h" = "xyes" ; then
cp simgear/gdbm/autoconf.h.cygwin32 simgear/gdbm/autoconf.h
fi
# if test "x$ac_cv_header_windows_h" = "xyes" ; then
# cp simgear/gdbm/autoconf.h.cygwin32 simgear/gdbm/autoconf.h
# fi
])
echo ""
@@ -279,8 +286,12 @@ else
echo "Electric fence: no"
fi
if test "x$ac_cv_header_gdbm_h" != "xyes"; then
echo "Building gdbm"
# if test "x$ac_cv_header_gdbm_h" != "xyes"; then
# echo "Building gdbm"
# fi
if test "x$ac_cv_header_mk4_h" != "xyes"; then
echo "Building metakit"
fi
if test "x$ac_cv_header_zlib_h" != "xyes"; then

View File

@@ -4,11 +4,11 @@ else
SERIAL_DIRS =
endif
if HAVE_GDBM
GDBM_DIRS =
else
GDBM_DIRS = gdbm
endif
# if HAVE_GDBM
# GDBM_DIRS =
# else
# GDBM_DIRS = gdbm
# endif
if HAVE_ZLIB
ZLIB_DIRS =
@@ -21,18 +21,19 @@ METAR_DIRS =
EXTRA_DIST = version.h.in
include_HEADERS = compiler.h constants.h fg_traits.hxx fg_zlib.h version.h
include_HEADERS = \
compiler.h constants.h fg_traits.hxx fg_zlib.h inlines.h version.h
SUBDIRS = \
bucket \
debug \
$(GDBM_DIRS) \
magvar \
math \
$(METAR_DIRS) \
misc \
screen \
$(SERIAL_DIRS) \
sky \
xgl \
$(ZLIB_DIRS)

View File

@@ -73,7 +73,7 @@ private:
int y; // y subdivision (0 to 7)
public:
// default constructor
FGBucket();
@@ -90,6 +90,10 @@ public:
// Set the bucket params for the specified lat and lon
void set_bucket( double dlon, double dlat );
void set_bucket( double *lonlat ) {
set_bucket( lonlat[0], lonlat[1] );
}
void make_bad ( void );
// Generate the unique scenery tile index for this bucket
@@ -227,7 +231,7 @@ inline FGBucket::FGBucket(const bool is_good) {
lon = -1000;
}
}
// Parse a unique scenery tile index and find the lon, lat, x, and y
inline FGBucket::FGBucket(const long int bindex) {
@@ -236,11 +240,11 @@ inline FGBucket::FGBucket(const long int bindex) {
lon = index >> 14;
index -= lon << 14;
lon -= 180;
lat = index >> 6;
index -= lat << 6;
lat -= 90;
y = index >> 3;
index -= y << 3;
@@ -310,9 +314,9 @@ inline double FGBucket::get_height() const {
// create an impossible bucket
inline void FGBucket::make_bad( void ) {
set_bucket(0.0, 0.0);
lon = -1000;
lon = -1000;
}
// offset a bucket struct by the specified tile units in the X & Y
// direction
@@ -323,12 +327,6 @@ FGBucket fgBucketOffset( double dlon, double dlat, int x, int y );
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy );
/*
// Given a lat/lon, fill in the local tile index array
void fgBucketGenIdxArray(fgBUCKET *p1, fgBUCKET *tiles, int width, int height);
*/
inline ostream&
operator<< ( ostream& out, const FGBucket& b )
{

View File

@@ -127,7 +127,10 @@
// Microsoft compilers.
//
#ifdef _MSC_VER
# if _MSC_VER == 1200 // msvc++ 6.0
# define bcopy(from, to, n) memcpy(to, from, n)
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
# if _MSC_VER == 1200 // msvc++ 6.0
# define FG_NAMESPACES
# define FG_HAVE_STD
# define FG_HAVE_STD_INCLUDES
@@ -147,7 +150,25 @@
# pragma warning(disable: 4305) //
# elif _MSC_VER == 1100 // msvc++ 5.0
# error MSVC++ 5.0 still to be supported...
# define NEEDNAMESPACESTD
# define FG_NAMESPACES
# define FG_HAVE_STD
# define FG_HAVE_STD_INCLUDES
# define FG_HAVE_STREAMBUF
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
# pragma warning(disable: 4244) // conversion from double to float
# pragma warning(disable: 4305) //
# else
# error What version of MSVC++ is this?
# endif

View File

@@ -47,9 +47,6 @@
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define if you have gdbm installed system wide. */
#undef HAVE_GDBM
/* Define if you have zlib installed system wide. */
#undef HAVE_ZLIB

154
simgear/config.h.vc5 Normal file
View File

@@ -0,0 +1,154 @@
/* Include/config.h. Generated for MSCV++ 5.0 */
/* Define if the X Window System is missing or not being used. */
#define X_DISPLAY_MISSING 1
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define to package name */
#define PACKAGE "FlightGear"
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if you can safely include both <sys/time.h> and <time.h>. */
/* #undef TIME_WITH_SYS_TIME */
/* Define if your <sys/time.h> declares struct tm. */
/* #define TM_IN_SYS_TIME 1 */
/* Define to version number */
#define VERSION "0.0.8"
/* Define if compiling on a Winbloze (95, NT, etc.) platform */
#define WIN32 1
/* Define if you have the GetLocalTime function. */
#define HAVE_GETLOCALTIME 1
/* Define if you have the ftime function. */
/* #define HAVE_FTIME 1 */
/* Define if you have the getitimer function. */
/* #define HAVE_GETITIMER 1 */
/* Define if you have the getrusage function. */
/* #define HAVE_GETRUSAGE 1 */
/* Define if you have the gettimeofday function. */
/* #define HAVE_GETTIMEOFDAY 1 */
/* Define if you have the mktime function. */
#define HAVE_MKTIME 1
/* Define if you have the rand function. */
#define HAVE_RAND 1
/* Define if you have the random function. */
#define HAVE_RANDOM 1
/* Define if you have the rint function. */
/* #define HAVE_RINT 1 */
/* Define if you have the setitimer function. */
/* #define HAVE_SETITIMER 1 */
/* Define if you have the signal function. */
#define HAVE_SIGNAL 1
/* Define if you have the strstr function. */
#define HAVE_STRSTR 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <getopt.h> header file. */
/* #define HAVE_GETOPT_H 1 */
/* Define if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <sys/time.h> header file. */
/* #define HAVE_SYS_TIME_H 1 */
/* Define if you have the <sys/timeb.h> header file. */
#define HAVE_SYS_TIMEB_H 1
/* Define if you have the <unistd.h> header file. */
/* #define HAVE_UNISTD_H 1 */
/* Define if you have the <values.h> header file. */
/* #define HAVE_VALUES_H 1 */
/* Define if you have the <winbase.h> header file. */
#define HAVE_WINBASE_H 1
/* Define if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1
/* Define if you have the GL library (-lGL). */
#define HAVE_LIBGL 1
/* Define if you have the GLU library (-lGLU). */
#define HAVE_LIBGLU 1
/* Define if you have the GLcore library (-lGLcore). */
/* #undef HAVE_LIBGLCORE */
/* Define if you have the ICE library (-lICE). */
/* #define HAVE_LIBICE 1 */
/* Define if you have the MesaGL library (-lMesaGL). */
/* #undef HAVE_LIBMESAGL */
/* Define if you have the MesaGLU library (-lMesaGLU). */
/* #undef HAVE_LIBMESAGLU */
/* Define if you have the SM library (-lSM). */
/* #define HAVE_LIBSM 1 */
/* Define if you have the X11 library (-lX11). */
/* #define HAVE_LIBX11 1 */
/* Define if you have the Xext library (-lXext). */
/* #define HAVE_LIBXEXT 1 */
/* Define if you have the Xi library (-lXi). */
/* #define HAVE_LIBXI 1 */
/* Define if you have the Xmu library (-lXmu). */
/* #define HAVE_LIBXMU 1 */
/* Define if you have the Xt library (-lXt). */
/* #define HAVE_LIBXT 1 */
/* Define if you have the glut library (-lglut). */
#define HAVE_LIBGLUT 1
/* Define if you have the m library (-lm). */
#define HAVE_LIBM 1
/* Define if you have the socket library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
#define HAVE_MEMCPY 1

View File

@@ -21,8 +21,8 @@
// $Id$
#ifndef _SUPPORTGEAR_CONSTANTS_H
#define _SUPPORTGEAR_CONSTANTS_H
#ifndef _SG_CONSTANTS_H
#define _SG_CONSTANTS_H
#ifdef HAVE_CONFIG_H
@@ -140,4 +140,4 @@
#define FG_EPSILON 0.0000001
#endif // _SUPPORTGEAR_CONSTANTS_H
#endif // _SG_CONSTANTS_H

View File

@@ -26,6 +26,9 @@
#include "stars.hxx"
#ifdef _MSC_VER
FG_USING_STD(getline);
#endif
// Constructor
FGStars::FGStars() {

61
simgear/inlines.h Normal file
View File

@@ -0,0 +1,61 @@
// inlines.h -- various inline template definitions
//
// Written by Norman Vine, started June 2000.
//
// Copyright (C) 2000 Norman Vine - nhv@cape.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_INLINES_H
#define _SG_INLINES_H
template <class T>
inline const int SG_SIGN(const T x) {
return x < T(0) ? -1 : 1;
}
template <class T>
inline const T SG_MIN(const T a, const T b) {
return a < b ? a : b;
}
// return the minimum of three values
template <class T>
inline const T SG_MIN3( const T a, const T b, const T c) {
return (a < b ? SG_MIN (a, c) : SG_MIN (b, c));
}
template <class T>
inline const T SG_MAX(const T a, const T b) {
return a > b ? a : b;
}
// return the maximum of three values
template <class T>
inline const T SG_MAX3 (const T a, const T b, const T c) {
return (a > b ? SG_MAX (a, c) : SG_MAX (b, c));
}
//
template <class T>
inline void SG_SWAP( T &a, T &b) {
T c = a; a = b; b = c;
}
#endif // _SG_INLINES_H

View File

@@ -56,8 +56,11 @@ void fgGeocToGeod( double lat_geoc, double radius, double
*sea_level_r = EQUATORIAL_RADIUS_M*E;
*alt = radius - *sea_level_r;
} else {
// cout << " lat_geoc = " << lat_geoc << endl;
t_lat = tan(lat_geoc);
// cout << " tan(t_lat) = " << t_lat << endl;
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
// cout << " x_alpha = " << x_alpha << endl;
double tmp = RESQ_M - x_alpha * x_alpha;
if ( tmp < 0.0 ) { tmp = 0.0; }
mu_alpha = atan2(sqrt(tmp),E*x_alpha);

View File

@@ -30,6 +30,8 @@
#endif
#include <math.h>
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
@@ -66,7 +68,8 @@ inline Point3D fgCartToPolar3d(const Point3D& cp) {
// distance. NOTE: starting point is specifed in radians, distance is
// specified in meters (and converted internally to radians)
// ... assumes a spherical world
inline Point3D calc_lon_lat( const Point3D& orig, double course, double dist ) {
inline Point3D calc_gc_lon_lat( const Point3D& orig, double course,
double dist ) {
Point3D result;
// lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
@@ -96,6 +99,60 @@ inline Point3D calc_lon_lat( const Point3D& orig, double course, double dist ) {
}
// calc course/dist
inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist ) {
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
double tmp1 = sin( (start.y() - dest.y()) / 2 );
double tmp2 = sin( (start.x() - dest.x()) / 2 );
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
cos(start.y()) * cos(dest.y()) * tmp2 * tmp2));
// We obtain the initial course, tc1, (at point 1) from point 1 to
// point 2 by the following. The formula fails if the initial
// point is a pole. We can special case this with:
//
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
// IF (lat1 > 0)
// tc1= pi // starting from N pole
// ELSE
// tc1= 0 // starting from S pole
// ENDIF
// ENDIF
//
// For starting points other than the poles:
//
// IF sin(lon2-lon1)<0
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ELSE
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ENDIF
double tc1;
if ( cos(start.y()) < FG_EPSILON ) {
// EPS a small number ~ machine precision
if ( start.y() > 0 ) {
tc1 = FG_PI; // starting from N pole
} else {
tc1 = 0; // starting from S pole
}
}
// For starting points other than the poles:
double tmp3 = sin(d)*cos(start.y());
double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
double tmp5 = acos(tmp4/tmp3);
if ( sin( dest.x() - start.x() ) < 0 ) {
tc1 = tmp5;
} else {
tc1 = 2 * FG_PI - tmp5;
}
*course = tc1;
*dist = d * RAD_TO_NM * NM_TO_METER;
}
#endif // _POLAR_HXX

View File

@@ -35,18 +35,13 @@ double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
const sgVec3 d ) {
sgVec3 u, u1, v;
double ud, dd, tmp;
// u = p - p0
sgSubVec3(u, p, p0);
// calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
ud = sgScalarProductVec3(u, d);
dd = sgScalarProductVec3(d, d);
tmp = ud / dd;
sgScaleVec3(u1, d, tmp);;
sgScaleVec3( u1, d, sgScalarProductVec3(u,d) / sgScalarProductVec3(d,d) );
// v = u - u1 = vector from closest point on line, p1, to the
// original point, p.
@@ -81,3 +76,18 @@ double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
return ( sgdScalarProductVec3(v, v) );
}
// This is a quicker form of
// sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
// sgPostMultMat4( sgMat, sgTRANS );
void sgPostMultMat4ByTransMat4( sgMat4 src, const sgVec3 trans )
{
for( int i=0; i<4; i++) {
for( int j=0; j<3; j++ ) {
src[i][j] += (src[i][3] * trans[j]);
}
}
}

View File

@@ -83,6 +83,14 @@ inline void sgmap_vec_onto_cur_surface_plane( sgVec3 normal,
}
inline void sgCopyNegateVec4( sgVec4 dst, sgVec4 src )
{
dst [ 0 ] = -src [ 0 ] ;
dst [ 1 ] = -src [ 1 ] ;
dst [ 2 ] = -src [ 2 ] ;
dst [ 3 ] = -src [ 3 ] ;
}
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
@@ -93,6 +101,10 @@ double sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
const sgdVec3 d );
// This is same as
// sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
// sgPostMultMat4( sgMat, sgTRANS );
void sgPostMultMat4ByTransMat4( sgMat4 src, const sgVec3 trans );
#endif // _VECTOR_HXX

View File

@@ -11,6 +11,7 @@ lib_LIBRARIES = libsgmisc.a
include_HEADERS = \
fgpath.hxx \
fgstream.hxx \
props.hxx \
stopwatch.hxx \
strutils.hxx \
texcoord.hxx \
@@ -19,6 +20,7 @@ include_HEADERS = \
libsgmisc_a_SOURCES = \
fgpath.cxx \
fgstream.cxx \
props.cxx \
strutils.cxx \
texcoord.cxx \
zfstream.cxx

803
simgear/misc/props.cxx Normal file
View File

@@ -0,0 +1,803 @@
// props.cxx -- implementation of FGFS global properties.
//
// 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$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/debug/logstream.hxx>
#include "props.hxx"
#include <stdlib.h>
#include <string>
using std::string;
FGPropertyList current_properties;
static string empty_string;
////////////////////////////////////////////////////////////////////////
// Implementation of FGValue.
////////////////////////////////////////////////////////////////////////
/**
* Construct a new value.
*/
FGValue::FGValue ()
: _type(UNKNOWN), _tied(false)
{
}
/**
* Destroy a value.
*/
FGValue::~FGValue ()
{
if (!_tied && _type == STRING) {
delete _value.string_val;
_value.string_val = 0;
}
}
bool
FGValue::getRawBool () const
{
if (_tied) {
if (_value.bool_func.getter != 0)
return (*(_value.bool_func.getter))();
else
return false;
} else {
return _value.bool_val;
}
}
int
FGValue::getRawInt () const
{
if (_tied) {
if (_value.int_func.getter != 0)
return (*(_value.int_func.getter))();
else
return 0;
} else {
return _value.int_val;
}
}
float
FGValue::getRawFloat () const
{
if (_tied) {
if (_value.float_func.getter != 0)
return (*(_value.float_func.getter))();
else
return 0.0;
} else {
return _value.float_val;
}
}
double
FGValue::getRawDouble () const
{
if (_tied) {
if (_value.double_func.getter != 0)
return (*(_value.double_func.getter))();
else
return 0.0L;
} else {
return _value.double_val;
}
}
const string &
FGValue::getRawString () const
{
if (_tied) {
if (_value.string_func.getter != 0)
return (*(_value.string_func.getter))();
else
return empty_string;
} else {
return *_value.string_val;
}
}
bool
FGValue::setRawBool (bool value)
{
if (_tied) {
if (_value.bool_func.setter != 0) {
(*_value.bool_func.setter)(value);
return true;
} else {
return false;
}
} else {
_value.bool_val = value;
return true;
}
}
bool
FGValue::setRawInt (int value)
{
if (_tied) {
if (_value.int_func.setter != 0) {
(*_value.int_func.setter)(value);
return true;
} else {
return false;
}
} else {
_value.int_val = value;
return true;
}
}
bool
FGValue::setRawFloat (float value)
{
if (_tied) {
if (_value.float_func.setter != 0) {
(*_value.float_func.setter)(value);
return true;
} else {
return false;
}
} else {
_value.float_val = value;
return true;
}
}
bool
FGValue::setRawDouble (double value)
{
if (_tied) {
if (_value.double_func.setter != 0) {
(*_value.double_func.setter)(value);
return true;
} else {
return false;
}
} else {
_value.double_val = value;
return true;
}
}
bool
FGValue::setRawString (const string &value)
{
if (_tied) {
if (_value.string_func.setter != 0) {
(*_value.string_func.setter)(value);
return true;
} else {
return false;
}
} else {
if (_value.string_val == 0)
_value.string_val = new string;
*(_value.string_val) = value;
return true;
}
}
/**
* Attempt to get the boolean value of a property.
*/
bool
FGValue::getBoolValue () const
{
switch (_type) {
case UNKNOWN:
return false;
case BOOL:
return getRawBool();
case INT:
return (getRawInt() == 0 ? false : true);
case FLOAT:
return (getRawFloat() == 0.0 ? false : true);
case DOUBLE:
return (getRawDouble() == 0.0 ? false : true);
case STRING:
return (getRawString() == "false" ? false : true);
}
return false;
}
/**
* Attempt to get the integer value of a property.
*/
int
FGValue::getIntValue () const
{
switch (_type) {
case UNKNOWN:
return 0;
case BOOL:
return getRawBool();
case INT:
return getRawInt();
case FLOAT:
return (int)(getRawFloat());
case DOUBLE:
return (int)(getRawDouble());
case STRING:
return atoi(getRawString().c_str());
}
return 0;
}
/**
* Attempt to get the float value of a property.
*/
float
FGValue::getFloatValue () const
{
switch (_type) {
case UNKNOWN:
return 0.0;
case BOOL:
return (float)(getRawBool());
case INT:
return (float)(getRawInt());
case FLOAT:
return getRawFloat();
case DOUBLE:
return (float)(getRawDouble());
case STRING:
return (float)atof(getRawString().c_str());
}
return 0.0;
}
/**
* Attempt to get the double value of a property.
*/
double
FGValue::getDoubleValue () const
{
switch (_type) {
case UNKNOWN:
return 0.0;
case BOOL:
return (double)(getRawBool());
case INT:
return (double)(getRawInt());
case FLOAT:
return (double)(getRawFloat());
case DOUBLE:
return getRawDouble();
case STRING:
return atof(getRawString().c_str());
}
return 0.0;
}
/**
* Attempt to get the string value of a property.
*/
const string &
FGValue::getStringValue () const
{
switch (_type) {
case UNKNOWN:
case BOOL:
case INT:
case FLOAT:
case DOUBLE:
return empty_string;
case STRING:
return getRawString();
}
return empty_string;
}
bool
FGValue::setBoolValue (bool value)
{
if (_type == UNKNOWN || _type == BOOL) {
_type = BOOL;
return setRawBool(value);
} else {
return false;
}
}
bool
FGValue::setIntValue (int value)
{
if (_type == UNKNOWN || _type == INT) {
_type = INT;
return setRawInt(value);
} else {
return false;
}
}
bool
FGValue::setFloatValue (float value)
{
if (_type == UNKNOWN || _type == FLOAT) {
_type = FLOAT;
return setRawFloat(value);
} else {
return false;
}
}
bool
FGValue::setDoubleValue (double value)
{
if (_type == UNKNOWN || _type == DOUBLE) {
_type = DOUBLE;
return setRawDouble(value);
} else {
return false;
}
}
bool
FGValue::setStringValue (const string &value)
{
if (_type == UNKNOWN || _type == STRING) {
_type = STRING;
return setRawString(value);
} else {
return false;
}
}
bool
FGValue::tieBool (bool_getter getter, bool_setter setter = 0,
bool useDefault = true)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
(*setter)(getBoolValue());
_tied = true;
_type = BOOL;
_value.bool_func.getter = getter;
_value.bool_func.setter = setter;
return true;
}
}
bool
FGValue::tieInt (int_getter getter, int_setter setter = 0,
bool useDefault = true)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
(*setter)(getIntValue());
_tied = true;
_type = INT;
_value.int_func.getter = getter;
_value.int_func.setter = setter;
return true;
}
}
bool
FGValue::tieFloat (float_getter getter, float_setter setter = 0,
bool useDefault = true)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
(*setter)(getFloatValue());
_tied = true;
_type = FLOAT;
_value.float_func.getter = getter;
_value.float_func.setter = setter;
return true;
}
}
bool
FGValue::tieDouble (double_getter getter, double_setter setter = 0,
bool useDefault = true)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
(*setter)(getDoubleValue());
_tied = true;
_type = DOUBLE;
_value.double_func.getter = getter;
_value.double_func.setter = setter;
return true;
}
}
bool
FGValue::tieString (string_getter getter, string_setter setter = 0,
bool useDefault = true)
{
if (_tied) {
return false;
} else {
if (useDefault && setter && _type != UNKNOWN)
(*setter)(getStringValue());
if (_type == STRING)
delete _value.string_val;
_tied = true;
_type = STRING;
_value.string_func.getter = getter;
_value.string_func.setter = setter;
return true;
}
}
bool
FGValue::untieBool ()
{
if (_tied && _type == BOOL) {
bool value = getRawBool();
_value.bool_val = value;
_tied = false;
return true;
} else {
return false;
}
}
bool
FGValue::untieInt ()
{
if (_tied && _type == INT) {
int value = getRawInt();
_value.int_val = value;
_tied = false;
return true;
} else {
return false;
}
}
bool
FGValue::untieFloat ()
{
if (_tied && _type == FLOAT) {
float value = getRawFloat();
_value.float_val = value;
_tied = false;
return true;
} else {
return false;
}
}
bool
FGValue::untieDouble ()
{
if (_tied && _type == DOUBLE) {
double value = getRawDouble();
_value.double_val = value;
_tied = false;
return true;
} else {
return false;
}
}
bool
FGValue::untieString ()
{
if (_tied && _type == STRING) {
const string &value = getRawString();
_value.string_val = new string(value);
_tied = false;
return true;
} else {
return false;
}
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGPropertyList.
////////////////////////////////////////////////////////////////////////
FGPropertyList::FGPropertyList ()
{
}
FGPropertyList::~FGPropertyList ()
{
}
FGValue *
FGPropertyList::getValue (const string &name, bool create = false)
{
const_iterator el = _props.find(name);
if (el == _props.end()) {
if (!create)
return 0;
else {
FG_LOG(FG_GENERAL, FG_INFO, "Creating new property '" << name << '\'');
}
}
return &(_props[name]);
}
const FGValue *
FGPropertyList::getValue (const string &name) const
{
value_map::const_iterator el = _props.find(name);
return &(el->second);
}
bool
FGPropertyList::getBoolValue (const string &name) const
{
const FGValue * val = getValue(name);
if (val == 0)
return false;
else
return val->getBoolValue();
}
int
FGPropertyList::getIntValue (const string &name) const
{
const FGValue * val = getValue(name);
if (val == 0)
return 0;
else
return val->getIntValue();
}
float
FGPropertyList::getFloatValue (const string &name) const
{
const FGValue * val = getValue(name);
if (val == 0)
return 0.0;
else
return val->getFloatValue();
}
double
FGPropertyList::getDoubleValue (const string &name) const
{
const FGValue * val = getValue(name);
if (val == 0)
return 0.0;
else
return val->getDoubleValue();
}
const string &
FGPropertyList::getStringValue (const string &name) const
{
const FGValue * val = getValue(name);
if (val == 0)
return empty_string;
else
return val->getStringValue();
}
bool
FGPropertyList::setBoolValue (const string &name, bool value)
{
return getValue(name, true)->setBoolValue(value);
}
bool
FGPropertyList::setIntValue (const string &name, int value)
{
return getValue(name, true)->setIntValue(value);
}
bool
FGPropertyList::setFloatValue (const string &name, float value)
{
return getValue(name, true)->setFloatValue(value);
}
bool
FGPropertyList::setDoubleValue (const string &name, double value)
{
return getValue(name, true)->setDoubleValue(value);
}
bool
FGPropertyList::setStringValue (const string &name, const string &value)
{
return getValue(name, true)->setStringValue(value);
}
bool
FGPropertyList::tieBool (const string &name,
bool_getter getter,
bool_setter setter,
bool useDefault = true)
{
FG_LOG(FG_GENERAL, FG_INFO, "Tying bool property '" << name << '\'');
return getValue(name, true)->tieBool(getter, setter, useDefault);
}
bool
FGPropertyList::tieInt (const string &name,
int_getter getter,
int_setter setter,
bool useDefault = true)
{
FG_LOG(FG_GENERAL, FG_INFO, "Tying int property '" << name << '\'');
return getValue(name, true)->tieInt(getter, setter, useDefault);
}
bool
FGPropertyList::tieFloat (const string &name,
float_getter getter,
float_setter setter,
bool useDefault = true)
{
FG_LOG(FG_GENERAL, FG_INFO, "Tying float property '" << name << '\'');
return getValue(name, true)->tieFloat(getter, setter, useDefault);
}
bool
FGPropertyList::tieDouble (const string &name,
double_getter getter,
double_setter setter,
bool useDefault = true)
{
FG_LOG(FG_GENERAL, FG_INFO, "Tying double property '" << name << '\'');
return getValue(name, true)->tieDouble(getter, setter, useDefault);
}
bool
FGPropertyList::tieString (const string &name,
string_getter getter,
string_setter setter,
bool useDefault = true)
{
FG_LOG(FG_GENERAL, FG_INFO, "Tying string property '" << name << '\'');
return getValue(name, true)->tieString(getter, setter, useDefault);
}
bool
FGPropertyList::untieBool (const string &name)
{
FG_LOG(FG_GENERAL, FG_INFO, "Untying bool property '" << name << '\'');
return getValue(name, true)->untieBool();
}
bool
FGPropertyList::untieInt (const string &name)
{
FG_LOG(FG_GENERAL, FG_INFO, "Untying int property '" << name << '\'');
return getValue(name, true)->untieInt();
}
bool
FGPropertyList::untieFloat (const string &name)
{
FG_LOG(FG_GENERAL, FG_INFO, "Untying float property '" << name << '\'');
return getValue(name, true)->untieFloat();
}
bool
FGPropertyList::untieDouble (const string &name)
{
FG_LOG(FG_GENERAL, FG_INFO, "Untying double property '" << name << '\'');
return getValue(name, true)->untieDouble();
}
bool
FGPropertyList::untieString (const string &name)
{
FG_LOG(FG_GENERAL, FG_INFO, "Untying string property '" << name << '\'');
return getValue(name, true)->untieString();
}
void
FGPropertyList::dumpToLog () const
{
const_iterator it = FGPropertyList::begin();
FG_LOG(FG_GENERAL, FG_INFO, "Begin property list dump...");
while (it != end()) {
FG_LOG(FG_GENERAL, FG_INFO, "Property: " << it->first);
it++;
}
FG_LOG(FG_GENERAL, FG_INFO, "...End property list dump");
}
// end of props.cxx

295
simgear/misc/props.hxx Normal file
View File

@@ -0,0 +1,295 @@
// props.hxx -- class to manage global FlightGear properties.
//
// 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 __PROPS_HXX
#define __PROPS_HXX
#include <string>
#include <map>
using std::string;
using std::map;
////////////////////////////////////////////////////////////////////////
// Values.
////////////////////////////////////////////////////////////////////////
/**
* Abstract representation of a FlightGear value.
*
* This value is designed to be fairly robust -- it can exist without
* a specified value, it can be any of several types, and it can
* be tied to an external variable without disrupting any existing
* pointers or references to the value. Some basic type conversions
* are also handled automatically.
*
* Values also have attributes that control whether they can be read
* from, written to, or archived (i.e. saved to disk).
*/
class FGValue
{
public:
// External getters
typedef bool (*bool_getter)();
typedef int (*int_getter)();
typedef float (*float_getter)();
typedef double (*double_getter)();
typedef const string &(*string_getter)();
// External setters
typedef void (*bool_setter)(bool);
typedef void (*int_setter)(int);
typedef void (*float_setter)(float);
typedef void (*double_setter)(double);
typedef void (*string_setter)(const string &);
enum Type {
UNKNOWN, // no value assigned yet
BOOL, // boolean
INT, // integer
FLOAT, // floating point
DOUBLE, // double precision
STRING // text
};
FGValue ();
virtual ~FGValue ();
// Meta information.
virtual Type getType () const { return _type; }
virtual bool isTied () const { return _tied; }
// Accessors.
virtual bool getBoolValue () const;
virtual int getIntValue () const;
virtual float getFloatValue () const;
virtual double getDoubleValue () const;
virtual const string &getStringValue () const;
// Setters.
virtual bool setBoolValue (bool value);
virtual bool setIntValue (int value);
virtual bool setFloatValue (float value);
virtual bool setDoubleValue (double value);
virtual bool setStringValue (const string &value);
// Tie to external variables.
virtual bool tieBool (bool_getter getter,
bool_setter setter = 0,
bool useDefault = true);
virtual bool tieInt (int_getter getter,
int_setter setter = 0,
bool useDefault = true);
virtual bool tieFloat (float_getter getter,
float_setter setter = 0,
bool useDefault = true);
virtual bool tieDouble (double_getter getter,
double_setter setter = 0,
bool useDefault = true);
virtual bool tieString (string_getter getter,
string_setter setter = 0,
bool useDefault = true);
// Untie from external variables.
virtual bool untieBool ();
virtual bool untieInt ();
virtual bool untieFloat ();
virtual bool untieDouble ();
virtual bool untieString ();
protected:
bool getRawBool () const;
int getRawInt () const;
float getRawFloat () const;
double getRawDouble () const;
const string &getRawString () const;
bool setRawBool (bool value);
bool setRawInt (int value);
bool setRawFloat (float value);
bool setRawDouble (double value);
bool setRawString (const string & value);
private:
Type _type;
bool _tied;
// The value is one of the following...
union {
bool bool_val;
int int_val;
float float_val;
double double_val;
string * string_val;
struct {
bool_setter setter;
bool_getter getter;
} bool_func;
struct {
int_setter setter;
int_getter getter;
} int_func;
struct {
void * obj;
float_setter setter;
float_getter getter;
} float_func;
struct {
void * obj;
double_setter setter;
double_getter getter;
} double_func;
struct {
string_setter setter;
string_getter getter;
} string_func;
} _value;
};
////////////////////////////////////////////////////////////////////////
// Top-level manager.
////////////////////////////////////////////////////////////////////////
/**
* A list of FlightGear properties.
*
* This list associates names (conventional written as paths,
* i.e. "/foo/bar/hack") with FGValue classes. Once an FGValue
* object is associated with the name, the association is
* permanent -- it is safe to keep a pointer or reference.
* however, that the type of a value may change if it is tied
* to a variable.
*
* When iterating through the list, the value type is
*
* pair<string,FGValue>
*
* To get the name from a const_iterator, use
*
* it->first
*
* and to get the value from a const_iterator, use
*
* it->second
*/
class FGPropertyList
{
public:
typedef map<string, FGValue> value_map;
typedef FGValue::bool_getter bool_getter;
typedef FGValue::int_getter int_getter;
typedef FGValue::float_getter float_getter;
typedef FGValue::double_getter double_getter;
typedef FGValue::string_getter string_getter;
typedef FGValue::bool_setter bool_setter;
typedef FGValue::int_setter int_setter;
typedef FGValue::float_setter float_setter;
typedef FGValue::double_setter double_setter;
typedef FGValue::string_setter string_setter;
typedef value_map::value_type value_type;
typedef value_map::size_type size_type;
typedef value_map::const_iterator const_iterator;
FGPropertyList ();
virtual ~FGPropertyList ();
virtual size_type size () const { return _props.size(); }
virtual const_iterator begin () const { return _props.begin(); }
virtual const_iterator end () const { return _props.end(); }
virtual FGValue * getValue (const string &name, bool create = false);
virtual const FGValue * getValue (const string &name) const;
virtual bool getBoolValue (const string &name) const;
virtual int getIntValue (const string &name) const;
virtual float getFloatValue (const string &name) const;
virtual double getDoubleValue (const string &name) const;
virtual const string &getStringValue (const string &name) const;
virtual bool setBoolValue (const string &name, bool value);
virtual bool setIntValue (const string &name, int value);
virtual bool setFloatValue (const string &name, float value);
virtual bool setDoubleValue (const string &name, double value);
virtual bool setStringValue (const string &name, const string &value);
virtual bool tieBool (const string &name,
bool_getter getter,
bool_setter setter = 0,
bool useDefault = true);
virtual bool tieInt (const string &name,
int_getter getter,
int_setter setter = 0,
bool useDefault = true);
virtual bool tieFloat (const string &name,
float_getter getter,
float_setter setter = 0,
bool useDefault = true);
virtual bool tieDouble (const string &name,
double_getter getter,
double_setter setter = 0,
bool useDefault = true);
virtual bool tieString (const string &name,
string_getter getter,
string_setter setter = 0,
bool useDefault = true);
virtual bool untieBool (const string &name);
virtual bool untieInt (const string &name);
virtual bool untieFloat (const string &name);
virtual bool untieDouble (const string &name);
virtual bool untieString (const string &name);
virtual void dumpToLog () const;
private:
value_map _props;
};
////////////////////////////////////////////////////////////////////////
// Global property manager.
////////////////////////////////////////////////////////////////////////
extern FGPropertyList current_properties;
#endif __PROPS_HXX

View File

@@ -113,17 +113,40 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
// cout << "dx = " << dx << " dy = " << dy << endl;
bool do_shift = false;
Point3D mod_shift;
// Point3D mod_shift;
if ( (dx > HALF_MAX_TEX_COORD) || (dy > HALF_MAX_TEX_COORD) ) {
// structure is too big, we'll just have to shift it so that
// tmin = (0,0). This messes up subsequent texture scaling,
// but is the best we can do.
// cout << "SHIFTING" << endl;
do_shift = true;
tmin.setx( (double)( (int)tmin.x() + 1 ) );
tmin.sety( (double)( (int)tmin.y() + 1 ) );
if ( tmin.x() < 0 ) {
tmin.setx( (double)( (int)tmin.x() - 1 ) );
} else {
tmin.setx( (int)tmin.x() );
}
if ( tmin.y() < 0 ) {
tmin.sety( (double)( (int)tmin.y() - 1 ) );
} else {
tmin.sety( (int)tmin.y() );
}
// cout << "found tmin = " << tmin << endl;
} else {
if ( tmin.x() < 0 ) {
tmin.setx( ( (int)(tmin.x() / HALF_MAX_TEX_COORD) - 1 )
* HALF_MAX_TEX_COORD );
} else {
tmin.setx( ( (int)(tmin.x() / HALF_MAX_TEX_COORD) )
* HALF_MAX_TEX_COORD );
}
if ( tmin.y() < 0 ) {
tmin.sety( ( (int)(tmin.y() / HALF_MAX_TEX_COORD) - 1 )
* HALF_MAX_TEX_COORD );
} else {
tmin.sety( ( (int)(tmin.y() / HALF_MAX_TEX_COORD) )
* HALF_MAX_TEX_COORD );
}
#if 0
// structure is small enough ... we can mod it so we can
// properly scale the texture coordinates later.
// cout << "MODDING" << endl;
@@ -142,7 +165,7 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
// At this point we know that the object is < 16 wide in
// texture coordinate space. If the modulo of the tmin is >
// the mod of the tmax at this point, then we know that the
// starting tex coordinate for the tmin > 16 so we can shift
// starting tex coordinate for the tmax > 16 so we can shift
// everything down by 16 and get it within the 0-32 range.
if ( x1 > x2 ) {
@@ -156,7 +179,7 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
} else {
mod_shift.sety( 0.0 );
}
#endif
// cout << "mod_shift = " << mod_shift << endl;
}
@@ -169,8 +192,9 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
t = basic_tex_coord( p, degree_width, degree_height, scale );
// cout << "second t = " << t << endl;
if ( do_shift ) {
adjusted_t = t - tmin;
// if ( do_shift ) {
adjusted_t = t - tmin;
#if 0
} else {
adjusted_t.setx( fmod(t.x() + mod_shift.x(), MAX_TEX_COORD) );
while ( adjusted_t.x() < 0 ) {
@@ -182,7 +206,7 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
}
// cout << "adjusted_t " << adjusted_t << endl;
}
#endif
if ( adjusted_t.x() < FG_EPSILON ) {
adjusted_t.setx( 0.0 );
}

View File

@@ -41,5 +41,3 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
#endif // _TEXCOORD_HXX

View File

@@ -1,6 +1,7 @@
noinst_LIBRARIES = libSky.a
libSky_a_SOURCES = \
cloud.cxx cloud.hxx \
dome.cxx dome.hxx \
moon.cxx moon.hxx \
oursun.cxx oursun.hxx \

258
simgear/sky/cloud.cxx Normal file
View File

@@ -0,0 +1,258 @@
// cloud.cxx -- model a single cloud layer
//
// Written by Curtis Olson, started June 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
// 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 <config.h>
#endif
#include <stdio.h>
#include <iostream>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/math/fg_random.h>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include "cloud.hxx"
// Constructor
SGCloudLayer::SGCloudLayer( void ) {
}
// Destructor
SGCloudLayer::~SGCloudLayer( void ) {
}
// build the moon object
void SGCloudLayer::build( double s, double asl, double thickness,
double transition, ssgSimpleState *state )
{
scale = 4000.0;
layer_asl = asl;
layer_thickness = thickness;
layer_transition = transition;
size = s;
last_lon = last_lat = -999.0f;
layer_state = state;
cl = new ssgColourArray( 4 );
vl = new ssgVertexArray( 4 );
tl = new ssgTexCoordArray( 4 );
// build the cloud layer
sgVec4 color;
sgVec3 vertex;
sgVec2 tc;
sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f );
sgSetVec3( vertex, -size, -size, 0.0f );
sgVec2 base;
sgSetVec2( base, fg_random(), fg_random() );
sgSetVec2( tc, base[0], base[1] );
cl->add( color );
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, size, -size, 0.0f );
sgSetVec2( tc, base[0] + size / scale, base[1] );
cl->add( color );
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, -size, size, 0.0f );
sgSetVec2( tc, base[0], base[1] + size / scale );
cl->add( color );
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, size, size, 0.0f );
sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
cl->add( color );
vl->add( vertex );
tl->add( tc );
ssgLeaf *layer =
new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl );
layer->setState( layer_state );
// force a repaint of the moon colors with arbitrary defaults
repaint( color );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
layer_transform = new ssgTransform;
// moon_transform->addKid( halo );
layer_transform->addKid( layer );
layer_root = new ssgRoot;
layer_root->addKid( layer_transform );
}
// repaint the cloud layer colors
bool SGCloudLayer::repaint( sgVec3 fog_color ) {
float *color;
for ( int i = 0; i < 4; ++i ) {
color = cl->get( i );
sgCopyVec4( color, fog_color );
}
return true;
}
// 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 SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
double alt )
{
sgMat4 T1, LON, LAT;
sgVec3 axis;
// combine p and asl (meters) to get translation offset
sgVec3 asl_offset;
sgCopyVec3( asl_offset, up );
sgNormalizeVec3( asl_offset );
if ( alt <= layer_asl ) {
sgScaleVec3( asl_offset, layer_asl );
} else {
sgScaleVec3( asl_offset, layer_asl + layer_thickness );
}
// cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1]
// << "," << asl_offset[2] << endl;
sgAddVec3( asl_offset, p );
// cout << " asl_offset = " << asl_offset[0] << "," << asl_offset[1]
// << "," << asl_offset[2] << endl;
// Translate to zero elevation
// Point3D zero_elev = current_view.get_cur_zero_elev();
// xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
sgMakeTransMat4( T1, asl_offset );
// printf(" Translated to %.2f %.2f %.2f\n",
// zero_elev.x, zero_elev.y, zero_elev.z );
// Rotate to proper orientation
// printf(" lon = %.2f lat = %.2f\n",
// FG_Longitude * SGD_RADIANS_TO_DEGREES,
// FG_Latitude * SGD_RADIANS_TO_DEGREES);
// xglRotatef( f->get_Longitude() * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis );
// xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES,
// 0.0, 1.0, 0.0 );
sgSetVec3( axis, 0.0, 1.0, 0.0 );
sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis );
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, LON );
sgPreMultMat4( TRANSFORM, LAT );
sgCoord layerpos;
sgSetCoord( &layerpos, TRANSFORM );
layer_transform->setTransform( &layerpos );
// now calculate update texture coordinates
if ( last_lon < -900 ) {
last_lon = lon;
last_lat = lat;
}
if ( lon != last_lon || lat != last_lat ) {
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 );
// cout << "course = " << course << ", dist = " << dist << endl;
double xoff = cos( course ) * dist / (2 * scale);
double yoff = sin( course ) * dist / (2 * scale);
// cout << "xoff = " << xoff << ", yoff = " << yoff << endl;
float *base, *tc;
base = tl->get( 0 );
base[0] += xoff;
while ( base[0] > 1.0 ) { base[0] -= 1.0; }
while ( base[0] < 0.0 ) { base[0] += 1.0; }
base[1] += yoff;
while ( base[1] > 1.0 ) { base[1] -= 1.0; }
while ( base[1] < 0.0 ) { base[1] += 1.0; }
// cout << "base = " << base[0] << "," << base[1] << endl;
tc = tl->get( 1 );
sgSetVec2( tc, base[0] + size / scale, base[1] );
tc = tl->get( 2 );
sgSetVec2( tc, base[0], base[1] + size / scale );
tc = tl->get( 3 );
sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
last_lon = lon;
last_lat = lat;
}
return true;
}
void SGCloudLayer::draw() {
ssgCullAndDraw( layer_root );
}
// make an ssgSimpleState for a cloud layer given the named texture
ssgSimpleState *SGCloudMakeState( const string &path ) {
ssgSimpleState *state = new ssgSimpleState();
state->setTexture( (char *)path.c_str() );
state->setShadeModel( GL_SMOOTH );
state->disable( GL_LIGHTING );
state->disable( GL_CULL_FACE );
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->enable( GL_BLEND );
state->enable( GL_ALPHA_TEST );
state->setAlphaClamp( 0.01 );
return state;
}

117
simgear/sky/cloud.hxx Normal file
View File

@@ -0,0 +1,117 @@
// cloud.hxx -- model a single cloud layer
//
// Written by Curtis Olson, started June 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
// 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_CLOUD_HXX_
#define _SG_CLOUD_HXX_
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#include <plib/ssg.h>
#include STL_STRING
FG_USING_STD(string);
#define SG_MAX_CLOUD_TYPES 4 // change this if we add/remove cloud
// types en the enum below
enum SGCloudType {
SG_CLOUD_OVERCAST = 0,
SG_CLOUD_MOSTLY_CLOUDY = 1,
SG_CLOUD_MOSTLY_SUNNY = 2,
SG_CLOUD_CIRRUS = 3,
};
class SGCloudLayer {
private:
ssgRoot *layer_root;
ssgTransform *layer_transform;
ssgSimpleState *layer_state;
ssgColourArray *cl;
ssgVertexArray *vl;
ssgTexCoordArray *tl;
// height above sea level (meters)
float layer_asl;
float layer_thickness;
float layer_transition;
float size;
float scale;
// for handling texture coordinates to simulate cloud movement
// from winds, and to simulate the clouds being tied to ground
// position, not view position
// double xoff, yoff;
double last_lon, last_lat;
public:
// Constructor
SGCloudLayer( void );
// Destructor
~SGCloudLayer( void );
// build the cloud object
void build( double size, double asl, double thickness,
double transition, ssgSimpleState *state );
// 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
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 );
// draw the cloud layer
void draw();
inline float get_asl() const { return layer_asl; }
inline float get_thickness() const { return layer_thickness; }
inline float get_transition() const { return layer_transition; }
};
// make an ssgSimpleState for a cloud layer given the named texture
ssgSimpleState *SGCloudMakeState( const string &path );
#endif // _SG_CLOUD_HXX_

View File

@@ -35,7 +35,8 @@
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include <simgear/constants.h>
#include <plib/sg.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/fg_random.h>
@@ -108,6 +109,8 @@ ssgBranch * SGSkyDome::build( ) {
dome_state->disable( GL_TEXTURE_2D );
dome_state->enable( GL_COLOR_MATERIAL );
dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
dome_state->disable( GL_BLEND );
dome_state->disable( GL_ALPHA_TEST );
@@ -137,7 +140,7 @@ ssgBranch * SGSkyDome::build( ) {
sgSetVec3( center_vertex, 0.0, 0.0, CENTER_ELEV );
for ( i = 0; i < 12; i++ ) {
theta = (i * 30.0) * DEG_TO_RAD;
theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS;
sgSetVec3( upper_vertex[i],
cos(theta) * UPPER_RADIUS,
@@ -215,7 +218,7 @@ ssgBranch * SGSkyDome::build( ) {
// force a repaint of the sky colors with ugly defaults
sgVec3 fog_color;
sgSetVec3( fog_color, 1.0, 1.0, 1.0 );
repaint( color, fog_color, 0.0 );
repaint( color, fog_color, 0.0, 5000.0 );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
@@ -268,7 +271,8 @@ ssgBranch * SGSkyDome::build( ) {
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle )
bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
double vis )
{
double diff;
sgVec3 outer_param, outer_amt, outer_diff;
@@ -309,11 +313,28 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle )
// First, recalulate the basic colors
//
sgVec4 center_color;
sgVec4 upper_color[12];
sgVec4 middle_color[12];
sgVec4 lower_color[12];
sgVec4 bottom_color[12];
double vis_factor;
if ( vis < 3000.0 ) {
vis_factor = (vis - 1000.0) / 2000.0;
if ( vis_factor < 0.0 ) {
vis_factor = 0.0;
}
} else {
vis_factor = 1.0;
}
for ( j = 0; j < 3; j++ ) {
diff = sky_color[j] - fog_color[j];
center_color[j] = sky_color[j] - diff * ( 1.0 - vis_factor );
}
for ( i = 0; i < 6; i++ ) {
for ( j = 0; j < 3; j++ ) {
diff = sky_color[j] - fog_color[j];
@@ -321,8 +342,9 @@ 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 * 0.3;
middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
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];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
@@ -361,8 +383,9 @@ 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 * 0.3;
middle_color[i][j] = sky_color[j] - diff * 0.9 + middle_amt[j];
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];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
@@ -407,7 +430,7 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle )
slot = center_disk_cl->get( counter++ );
// sgVec4 red;
// sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
sgCopyVec4( slot, sky_color );
sgCopyVec4( slot, center_color );
for ( i = 11; i >= 0; i-- ) {
slot = center_disk_cl->get( counter++ );
sgCopyVec4( slot, upper_color[i] );
@@ -482,19 +505,21 @@ bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
// zero_elev.x, zero_elev.y, zero_elev.z );
// Rotate to proper orientation
// printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
// FG_Latitude * RAD_TO_DEG);
// xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
// printf(" lon = %.2f lat = %.2f\n",
// FG_Longitude * SGD_RADIANS_TO_DEGREES,
// FG_Latitude * SGD_RADIANS_TO_DEGREES);
// xglRotatef( f->get_Longitude() * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis );
sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis );
// xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
// xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES,
// 0.0, 1.0, 0.0 );
sgSetVec3( axis, 0.0, 1.0, 0.0 );
sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis );
sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis );
// xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
// xglRotatef( l->sun_rotation * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( SPIN, spin * RAD_TO_DEG, axis );
sgMakeRotMat4( SPIN, spin * SGD_RADIANS_TO_DEGREES, axis );
sgMat4 TRANSFORM;

View File

@@ -69,7 +69,8 @@ public:
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle );
bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle,
double vis );
// reposition the sky at the specified origin and orientation
// lon specifies a rotation about the Z axis

View File

@@ -31,6 +31,7 @@
#include <stdio.h>
#include <iostream>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/constants.h>
@@ -57,6 +58,14 @@ static int sgMoonOrbPostDraw( ssgEntity *e ) {
glEnable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
/* test
glDisable( GL_LIGHTING );
glDisable( GL_CULL_FACE );
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
glEnable( GL_CULL_FACE );
glEnable( GL_LIGHTING ); */
return true;
}
@@ -104,8 +113,9 @@ ssgBranch * SGMoon::build( FGPath path, double moon_size ) {
orb_state->enable( GL_TEXTURE_2D );
orb_state->enable( GL_COLOR_MATERIAL );
orb_state->setColourMaterial( GL_DIFFUSE );
orb_state->setMaterial( GL_AMBIENT, 0.0, 0.0, 0.0, 1.0 );
orb_state->setMaterial( GL_SPECULAR, 0.0, 0.0, 0.0, 1.0 );
orb_state->setMaterial( GL_AMBIENT, 0, 0, 0, 1.0 );
orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
orb_state->enable( GL_BLEND );
orb_state->enable( GL_ALPHA_TEST );
orb_state->setAlphaClamp( 0.01 );
@@ -139,8 +149,8 @@ ssgBranch * SGMoon::build( FGPath path, double moon_size ) {
halo_state->disable( GL_COLOR_MATERIAL );
halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
halo_state->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ;
halo_state -> setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ;
halo_state -> setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
halo_state->setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ;
halo_state->setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
// halo_state -> setShininess ( 0 ) ;
halo_state->enable( GL_ALPHA_TEST );
halo_state->setAlphaClamp(0.01);
@@ -193,7 +203,7 @@ ssgBranch * SGMoon::build( FGPath path, double moon_size ) {
// 90 degrees = moon rise/set
// 180 degrees = darkest midnight
bool SGMoon::repaint( double moon_angle ) {
if ( moon_angle * RAD_TO_DEG < 100 ) {
if ( moon_angle * SGD_RADIANS_TO_DEGREES < 100 ) {
// else moon is well below horizon (so no point in repainting it)
// x_10 = moon_angle^10
@@ -211,7 +221,10 @@ bool SGMoon::repaint( double moon_angle ) {
(ambient * 11.0) - 3.0, // minimum value = 0.3
(ambient * 12.0) - 3.6, // minimum value = 0.0
0.5 );
// 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;
@@ -245,16 +258,17 @@ bool SGMoon::reposition( sgVec3 p, double angle,
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, angle, axis );
// xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0);
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, (rightAscension * RAD_TO_DEG) - 90.0, axis );
sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
// xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
// xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0);
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, declination * RAD_TO_DEG, axis );
sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis );
// xglTranslatef(0,60000,0);
sgSetVec3( v, 0.0, 60000.0, 0.0 );
// xglTranslatef(0,moon_dist);
sgSetVec3( v, 0.0, moon_dist, 0.0 );
sgMakeTransMat4( T2, v );
sgMat4 TRANSFORM;
@@ -271,3 +285,4 @@ bool SGMoon::reposition( sgVec3 p, double angle,
return true;
}

View File

@@ -31,10 +31,9 @@
#include <stdio.h>
#include <iostream>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/constants.h>
#include "sphere.hxx"
#include "oursun.hxx"
@@ -204,10 +203,13 @@ ssgBranch * SGSun::build( FGPath path, double sun_size ) {
orb_state = new ssgSimpleState();
orb_state->setShadeModel( GL_SMOOTH );
orb_state->disable( GL_LIGHTING );
// orb_state->enable( GL_LIGHTING );
orb_state->disable( GL_CULL_FACE );
orb_state->disable( GL_TEXTURE_2D );
orb_state->enable( GL_COLOR_MATERIAL );
orb_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
orb_state->disable( GL_BLEND );
orb_state->disable( GL_ALPHA_TEST );
@@ -231,13 +233,15 @@ ssgBranch * SGSun::build( FGPath path, double sun_size ) {
path.append( "halo.rgba" );
halo_state = new ssgSimpleState();
halo_state->setTexture( (char *)path.c_str() );
// halo_state->setTexture( sun_texid );
halo_state->enable( GL_TEXTURE_2D );
halo_state->disable( GL_LIGHTING );
// halo_state->enable( GL_LIGHTING );
halo_state->setShadeModel( GL_SMOOTH );
halo_state->disable( GL_CULL_FACE );
halo_state->enable( GL_COLOR_MATERIAL );
halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
halo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
halo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
halo_state->enable( GL_ALPHA_TEST );
halo_state->setAlphaClamp(0.01);
halo_state->enable ( GL_BLEND ) ;
@@ -274,9 +278,9 @@ ssgBranch * SGSun::build( FGPath path, double sun_size ) {
// into the provide scene graph branch
sun_transform = new ssgTransform;
sun_transform->addKid( halo );
halo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
halo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
sun_transform->addKid( halo );
sun_transform->addKid( orb );
return sun_transform;
@@ -289,7 +293,7 @@ ssgBranch * SGSun::build( FGPath path, double sun_size ) {
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSun::repaint( double sun_angle ) {
if ( sun_angle * RAD_TO_DEG < 100 ) {
if ( sun_angle * SGD_RADIANS_TO_DEGREES < 100 ) {
// else sun is well below horizon (so no point in repainting it)
// x_10 = sun_angle^10
@@ -307,6 +311,9 @@ bool SGSun::repaint( double sun_angle ) {
(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;
@@ -340,16 +347,17 @@ bool SGSun::reposition( sgVec3 p, double angle,
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, angle, axis );
// xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0);
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, (rightAscension * RAD_TO_DEG) - 90.0, axis );
sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
// xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
// xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0);
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, declination * RAD_TO_DEG, axis );
sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis );
// xglTranslatef(0,60000,0);
sgSetVec3( v, 0.0, 60000.0, 0.0 );
// xglTranslatef(0,sun_dist);
sgSetVec3( v, 0.0, sun_dist, 0.0 );
sgMakeTransMat4( T2, v );
sgMat4 TRANSFORM;

View File

@@ -26,13 +26,26 @@
# include <config.h>
#endif
#include <plib/ssg.h> // plib include
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/math/fg_random.h>
#include "sky.hxx"
// Constructor
SGSky::SGSky( void ) {
effective_visibility = visibility = 10000.0;
// near cloud visibility state variables
in_puff = false;
puff_length = 0;
puff_progression = 0;
ramp_up = 0.15;
ramp_down = 0.15;
// ramp_up = 4.0;
// ramp_down = 4.0;
}
@@ -43,35 +56,64 @@ SGSky::~SGSky( void ) {
// initialize the sky and connect the components to the scene graph at
// the provided branch
ssgBranch * 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 sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
double planet_dist,
int nstars, sgdVec3 *star_data, double star_dist )
{
sky_selector = new ssgSelector;
sky_transform = new ssgTransform;
pre_root = new ssgRoot;
post_root = new ssgRoot;
pre_selector = new ssgSelector;
post_selector = new ssgSelector;
pre_transform = new ssgTransform;
post_transform = new ssgTransform;
dome = new SGSkyDome;
sky_transform -> addKid( dome->build() );
pre_transform -> addKid( dome->build() );
planets = new SGStars;
sky_transform -> addKid( planets->build(nplanets, planet_data,
pre_transform -> addKid( planets->build(nplanets, planet_data,
planet_dist)
);
stars = new SGStars;
sky_transform -> addKid( stars->build(nstars, star_data, star_dist) );
pre_transform -> addKid( stars->build(nstars, star_data, star_dist) );
moon = new SGMoon;
sky_transform -> addKid( moon->build(tex_path, moon_size) );
pre_transform -> addKid( moon->build(tex_path, moon_size) );
oursun = new SGSun;
sky_transform -> addKid( oursun->build(tex_path, sun_size) );
pre_transform -> addKid( oursun->build(tex_path, sun_size) );
sky_selector->addKid( sky_transform );
sky_selector->clrTraversalMaskBits( SSGTRAV_HOT );
pre_selector->addKid( pre_transform );
pre_selector->clrTraversalMaskBits( SSGTRAV_HOT );
return sky_selector;
post_selector->addKid( post_transform );
post_selector->clrTraversalMaskBits( SSGTRAV_HOT );
pre_root->addKid( pre_selector );
post_root->addKid( post_selector );
// add the cloud ssgStates to the material lib
FGPath cloud_path;
cloud_path.set( tex_path.str() );
cloud_path.append( "overcast.rgb" );
cloud_mats[SG_CLOUD_OVERCAST] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "mostlycloudy.rgba" );
cloud_mats[SG_CLOUD_MOSTLY_CLOUDY] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "mostlysunny.rgba" );
cloud_mats[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "cirrus.rgba" );
cloud_mats[SG_CLOUD_CIRRUS] = SGCloudMakeState( cloud_path.str() );
}
@@ -87,11 +129,21 @@ bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data )
{
dome->repaint( sky_color, fog_color, sun_angle );
oursun->repaint( sun_angle );
moon->repaint( moon_angle );
planets->repaint( sun_angle, nplanets, planet_data );
stars->repaint( sun_angle, nstars, star_data );
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 );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
cloud_layers[i]->repaint( fog_color );
}
} else {
// turn off sky
disable();
}
return true;
}
@@ -104,8 +156,8 @@ bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_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,
double lon, double lat, double spin,
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 )
@@ -117,5 +169,220 @@ bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev,
planets->reposition( view_pos, angle );
stars->reposition( view_pos, angle );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt );
}
return true;
}
// draw background portions of the sky ... do this before you draw the
// rest of your scene.
void SGSky::preDraw() {
ssgCullAndDraw( pre_root );
}
// 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
// check where we are relative to the cloud layers
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->get_asl();
float thickness = cloud_layers[i]->get_thickness();
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]->get_asl())
{
++pos;
}
if ( pos == 0 ) {
// we are below all the cloud layers, draw top to bottom
for ( int 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 ( int 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 ( int i = 0; i < pos; ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
for ( int i = cloud_layers.size() - 1; i >= pos; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw();
}
}
}
}
void SGSky::add_cloud_layer( double asl, double thickness, double transition,
ssgSimpleState *state ) {
SGCloudLayer *layer = new SGCloudLayer;
layer->build( 40000.0f, asl, thickness, transition, state );
layer_list_iterator current = cloud_layers.begin();
layer_list_iterator last = cloud_layers.end();
while ( current != last && (*current)->get_asl() < asl ) {
++current;
}
if ( current != last ) {
cloud_layers.insert( current, layer );
} else {
cloud_layers.push_back( layer );
}
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
cout << "layer " << i << " = " << cloud_layers[i]->get_asl() << endl;
}
cout << endl;
}
void SGSky::add_cloud_layer( double asl, double thickness, double transition,
const string &tex_path ) {
ssgSimpleState *state = SGCloudMakeState( tex_path );
add_cloud_layer( asl, thickness, transition, state );
}
void SGSky::add_cloud_layer( double asl, double thickness, double transition,
SGCloudType type ) {
if ( type > 0 && type < SG_MAX_CLOUD_TYPES ) {
add_cloud_layer( asl, thickness, transition, cloud_mats[type] );
}
}
// modify the current visibility based on cloud layers, thickness,
// transition range, and simulated "puffs".
void SGSky::modify_vis( float alt, float time_factor ) {
float effvis = visibility;
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->get_asl();
float thickness = cloud_layers[i]->get_thickness();
float transition = cloud_layers[i]->get_transition();
double ratio = 1.0;
if ( alt < asl - transition ) {
// below cloud layer
ratio = 1.0;
} else if ( alt < asl ) {
// in lower transition
ratio = (asl - alt) / transition;
} else if ( alt < asl + thickness ) {
// in cloud layer
ratio = 0.0;
} else if ( alt < asl + thickness + transition ) {
// in upper transition
ratio = (alt - (asl + thickness)) / transition;
} else {
// above cloud layer
ratio = 1.0;
}
// accumulate effects from multiple cloud layers
effvis *= ratio;
if ( ratio < 1.0 ) {
if ( ! in_puff ) {
// calc chance of entering cloud puff
double rnd = fg_random();
double chance = rnd * rnd * rnd;
if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) {
in_puff = true;
puff_length = fg_random() * 2.0; // up to 2 seconds
puff_progression = 0.0;
}
}
if ( in_puff ) {
// modify actual_visibility based on puff envelope
if ( puff_progression <= ramp_up ) {
double x = 0.5 * SGD_PI * puff_progression / ramp_up;
double factor = 1.0 - sin( x );
// cout << "ramp up = " << puff_progression
// << " factor = " << factor << endl;
effvis = effvis * factor;
} else if ( puff_progression >= ramp_up + puff_length ) {
double x = 0.5 * SGD_PI *
(puff_progression - (ramp_up + puff_length)) /
ramp_down;
double factor = sin( x );
// cout << "ramp down = "
// << puff_progression - (ramp_up + puff_length)
// << " factor = " << factor << endl;
effvis = effvis * factor;
} else {
effvis = 0.0;
}
/* cout << "len = " << puff_length
<< " x = " << x
<< " factor = " << factor
<< " actual_visibility = " << actual_visibility
<< endl; */
// time_factor = ( global_multi_loop *
// current_options.get_speed_up() ) /
// (double)current_options.get_model_hz();
puff_progression += time_factor;
// cout << "time factor = " << time_factor << endl;
/* cout << "gml = " << global_multi_loop
<< " speed up = " << current_options.get_speed_up()
<< " hz = " << current_options.get_model_hz() << endl;
*/
if ( puff_progression > puff_length + ramp_up + ramp_down) {
in_puff = false;
}
}
// never let visibility drop below 25 meters
if ( effvis <= 25.0 ) {
effvis = 25.0;
}
}
} // for
effective_visibility = effvis;
}

View File

@@ -33,28 +33,56 @@
#include <plib/ssg.h> // plib include
#include <simgear/compiler.h>
#include <simgear/misc/fgpath.hxx>
#include <vector>
#include "cloud.hxx"
#include "dome.hxx"
#include "moon.hxx"
#include "oursun.hxx"
#include "stars.hxx"
FG_USING_STD(vector);
typedef vector < SGCloudLayer* > layer_list_type;
typedef layer_list_type::iterator layer_list_iterator;
typedef layer_list_type::const_iterator layer_list_const_iterator;
class SGSky {
private:
// components of the sky
SGSkyDome *dome;
SGSun *oursun;
SGMoon *moon;
SGStars *planets;
SGStars *stars;
ssgSimpleState *cloud_mats[SG_MAX_CLOUD_TYPES];
layer_list_type cloud_layers;
ssgSelector *sky_selector;
ssgTransform *sky_transform;
ssgRoot *pre_root, *post_root;
ssgSelector *pre_selector, *post_selector;
ssgTransform *pre_transform, *post_transform;
FGPath tex_path;
// visibility
float visibility;
float effective_visibility;
// near cloud visibility state variables
bool in_puff;
double puff_length; // in seconds
double puff_progression; // in seconds
double ramp_up; // in seconds
double ramp_down; // in seconds
public:
// Constructor
@@ -65,9 +93,9 @@ public:
// initialize the sky and connect the components to the scene
// graph at the provided branch
ssgBranch *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 sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data, double planet_dist,
int nstars, sgdVec3 *star_data, double star_dist );
// repaint the sky components based on current value of sun_angle,
// sky, and fog colors.
@@ -76,7 +104,7 @@ public:
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( sgVec4 sky_color, sgVec4 fog_color,
bool repaint( sgVec4 sky_color, sgVec4 fog_color,
double sun_angle, double moon_angle,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data );
@@ -88,23 +116,59 @@ public:
// 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 reposition( sgVec3 view_pos, sgVec3 zero_elev,
double lon, double lat, double spin,
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 );
// modify the given visibility based on cloud layers, thickness,
// transition range, and simulated "puffs".
void modify_vis( float alt, float time_factor );
// draw background portions of the sky ... do this before you draw
// the rest of your scene.
void preDraw();
// draw translucent clouds ... do this after you've drawn all the
// oapaque elements of your scene.
void postDraw( float alt );
// specify the texture path (optional, defaults to current directory)
inline void texture_path( const string& path ) {
tex_path = FGPath( path );
}
// enable the sky in the scene graph (default)
inline void enable() { sky_selector->select( 1 ); }
// enable the sky
inline void enable() {
pre_selector->select( 1 );
post_selector->select( 1 );
}
// disable the sky in the scene graph. The leaf node is still
// there, how ever it won't be traversed on by ssgCullandRender()
inline void disable() { sky_selector->select( 0 ); }
inline void disable() {
pre_selector->select( 0 );
post_selector->select( 0 );
}
// add a cloud layer (above sea level in meters)
void add_cloud_layer( double asl, double thickness, double transition,
SGCloudType type );
void add_cloud_layer( double asl, double thickness, double transition,
const string &tex_path );
void add_cloud_layer( double asl, double thickness, double transition,
ssgSimpleState *state );
inline int get_num_layers() const { return cloud_layers.size(); }
inline SGCloudLayer *get_cloud_layer( int i ) const {
return cloud_layers[i];
}
inline float get_visibility() const { return effective_visibility; }
inline void set_visibility( float v ) {
effective_visibility = visibility = v;
}
};

View File

@@ -26,6 +26,11 @@
# include <config.h>
#endif
#include <simgear/compiler.h>
#include STL_IOSTREAM
#include <plib/sg.h>
#include <plib/ssg.h>
@@ -43,26 +48,8 @@ ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
sgVec2 vec2;
sgVec3 vec3;
// handle cl whether it is preinitialized or not
if ( cl == NULL ) {
// create a new array if needed
cl = new ssgColourArray( 1 );
}
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
if ( cl->getNum() > 1 ) {
cl->removeAll();
cl->add( color );
} else if ( cl->getNum() == 0 ) {
cl->add( color );
} else {
// accept value as given to us in
}
drho = M_PI / (float) stacks;
dtheta = 2.0 * M_PI / (float) slices;
drho = SG_PI / (float) stacks;
dtheta = 2.0 * SG_PI / (float) slices;
/* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
@@ -123,6 +110,15 @@ ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
ssgLeaf *slice =
new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
if ( vl->getNum() != nl->getNum() ) {
cout << "bad sphere1\n";
exit(-1);
}
if ( vl->getNum() != tl->getNum() ) {
cout << "bad sphere2\n";
exit(-1);
}
slice->setState( state );
slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );

View File

@@ -31,12 +31,16 @@
#include <stdio.h>
#include <iostream>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/constants.h>
#include "stars.hxx"
#ifdef _MSC_VER
FG_USING_STD(cout);
FG_USING_STD(endl);
#endif
// Set up star rendering call backs
static int sgStarPreDraw( ssgEntity *e ) {
@@ -84,6 +88,8 @@ ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) {
state->disable( 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->enable( GL_BLEND );
state->disable( GL_ALPHA_TEST );
@@ -141,26 +147,26 @@ bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) {
float *color;
// determine which star structure to draw
if ( sun_angle > (FG_PI_2 + 10.0 * DEG_TO_RAD ) ) {
if ( sun_angle > (0.5 * SGD_PI + 10.0 * SGD_DEGREES_TO_RADIANS ) ) {
// deep night
factor = 1.0;
cutoff = 4.5;
} else if ( sun_angle > (FG_PI_2 + 8.8 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 8.8 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 1.0;
cutoff = 3.8;
} else if ( sun_angle > (FG_PI_2 + 7.5 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 7.5 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 0.95;
cutoff = 3.1;
} else if ( sun_angle > (FG_PI_2 + 7.0 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 7.0 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 0.9;
cutoff = 2.4;
} else if ( sun_angle > (FG_PI_2 + 6.5 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 6.5 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 0.85;
cutoff = 1.8;
} else if ( sun_angle > (FG_PI_2 + 6.0 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 6.0 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 0.8;
cutoff = 1.2;
} else if ( sun_angle > (FG_PI_2 + 5.5 * DEG_TO_RAD ) ) {
} else if ( sun_angle > (0.5 * SGD_PI + 5.5 * SGD_DEGREES_TO_RADIANS ) ) {
factor = 0.75;
cutoff = 0.6;
} else {