Compare commits
24 Commits
RELEASE_0_
...
RELEASE_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc2099865 | ||
|
|
7d251444e6 | ||
|
|
1c2289dacd | ||
|
|
044ac5d5d3 | ||
|
|
38167ed273 | ||
|
|
e15ffbc856 | ||
|
|
6cf2716615 | ||
|
|
0468b315d4 | ||
|
|
de66c74a91 | ||
|
|
7db73cd215 | ||
|
|
242eceb1c6 | ||
|
|
c2b84db5a2 | ||
|
|
487bee35ab | ||
|
|
9fabeb77bc | ||
|
|
bfea2dec4d | ||
|
|
2ed07850c6 | ||
|
|
b72d36d96f | ||
|
|
e3ff048ff6 | ||
|
|
ceef43681d | ||
|
|
3ec00676e4 | ||
|
|
e6575fb1db | ||
|
|
fa98d733d6 | ||
|
|
2981a10e62 | ||
|
|
551c06f885 |
91
Makefile.am
91
Makefile.am
@@ -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
8
NEWS
@@ -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
3
README
@@ -0,0 +1,3 @@
|
||||
MSVC5 users:
|
||||
|
||||
Copy simgear/config.h.vc5 to simgear/config.h before building.
|
||||
|
||||
243
README.metakit
Normal file
243
README.metakit
Normal 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>
|
||||
@@ -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
|
||||
|
||||
49
configure.in
49
configure.in
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
154
simgear/config.h.vc5
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
#include "stars.hxx"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
FG_USING_STD(getline);
|
||||
#endif
|
||||
|
||||
// Constructor
|
||||
FGStars::FGStars() {
|
||||
|
||||
61
simgear/inlines.h
Normal file
61
simgear/inlines.h
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
803
simgear/misc/props.cxx
Normal 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
295
simgear/misc/props.hxx
Normal 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
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -41,5 +41,3 @@ point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
|
||||
|
||||
#endif // _TEXCOORD_HXX
|
||||
|
||||
|
||||
|
||||
@@ -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
258
simgear/sky/cloud.cxx
Normal 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
117
simgear/sky/cloud.hxx
Normal 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_
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user