Compare commits
160
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c363758449 | ||
|
|
dfdeb8be9b | ||
|
|
d1c8f60ca9 | ||
|
|
2fb961c922 | ||
|
|
2e17b28994 | ||
|
|
c3f558b034 | ||
|
|
65ce1a04b2 | ||
|
|
3af4a19f76 | ||
|
|
5178f69f18 | ||
|
|
52e2005b3e | ||
|
|
94fa51e3f7 | ||
|
|
590547e12d | ||
|
|
c6832d2513 | ||
|
|
1fd63c30e9 | ||
|
|
f08ae9f2ea | ||
|
|
5c61e97358 | ||
|
|
87e38e2617 | ||
|
|
92e1856caa | ||
|
|
20c099b7ef | ||
|
|
7eb74c7e2a | ||
|
|
8d63c300e2 | ||
|
|
01ccdd3ae1 | ||
|
|
ab074726df | ||
|
|
ed26458a24 | ||
|
|
fcf1d34e55 | ||
|
|
19f99ea273 | ||
|
|
fe5bb76def | ||
|
|
7ecf508453 | ||
|
|
83e6e44eab | ||
|
|
69a93342c0 | ||
|
|
e17338622a | ||
|
|
a67fd7ea99 | ||
|
|
cf2b8afbe9 | ||
|
|
a1e7761384 | ||
|
|
d068915b42 | ||
|
|
adeb0d48fc | ||
|
|
55c89ea865 | ||
|
|
8bd07e358f | ||
|
|
01113e82f3 | ||
|
|
6d79582890 | ||
|
|
2ae3c89406 | ||
|
|
1818102ffe | ||
|
|
406d6dd6fc | ||
|
|
c8ef854f01 | ||
|
|
87dcaf5a00 | ||
|
|
c3bdd0e537 | ||
|
|
c23fd6e66f | ||
|
|
e809eee896 | ||
|
|
c44ef2126c | ||
|
|
e2bfb5633b | ||
|
|
064ee8ba8f | ||
|
|
a5c130446e | ||
|
|
4162817c0b | ||
|
|
81cab6e089 | ||
|
|
d78204d147 | ||
|
|
d8b523d067 | ||
|
|
c4cfad6069 | ||
|
|
5bddb88ce2 | ||
|
|
8c4ee69aeb | ||
|
|
b3a533f8ce | ||
|
|
a885314a39 | ||
|
|
0567a76445 | ||
|
|
d6dc2d6eab | ||
|
|
b75a694682 | ||
|
|
2e7e9b73a0 | ||
|
|
7a11523692 | ||
|
|
f85a9866fe | ||
|
|
9b05c27938 | ||
|
|
fd96729362 | ||
|
|
c57cc096f8 | ||
|
|
c8efd0a465 | ||
|
|
db60139845 | ||
|
|
cadefd323a | ||
|
|
baab88f42a | ||
|
|
767b74dd35 | ||
|
|
90e8287f43 | ||
|
|
d8b7e5b8fd | ||
|
|
7769447283 | ||
|
|
d6a790cf13 | ||
|
|
033c66363d | ||
|
|
3ff1789963 | ||
|
|
9737c0c4dd | ||
|
|
b201383a80 | ||
|
|
2253b82304 | ||
|
|
2581446d85 | ||
|
|
a6291b286c | ||
|
|
96a396bfcb | ||
|
|
0833a11686 | ||
|
|
9c7f7f3d32 | ||
|
|
7847fe8074 | ||
|
|
c57d25ac51 | ||
|
|
1341b5b9f8 | ||
|
|
fb54e9e103 | ||
|
|
3a835dde7d | ||
|
|
128a4a36ca | ||
|
|
255bb6dd07 | ||
|
|
786b1e3a30 | ||
|
|
d5f38a558e | ||
|
|
ce5d4b7db8 | ||
|
|
8c0b36fe9e | ||
|
|
c7e6459c64 | ||
|
|
86e31e696d | ||
|
|
be0b1bb994 | ||
|
|
03e74bfeb4 | ||
|
|
972223cd50 | ||
|
|
761b7b9354 | ||
|
|
6a3d1895d9 | ||
|
|
d1178a26ce | ||
|
|
8ffdfa3cb1 | ||
|
|
384e56b9b4 | ||
|
|
d198e962b0 | ||
|
|
0136fdadbb | ||
|
|
c616568830 | ||
|
|
995d2c1ede | ||
|
|
051a5e9a38 | ||
|
|
60d89097de | ||
|
|
6c35255549 | ||
|
|
c985d8846d | ||
|
|
9a8ab26381 | ||
|
|
711622fd5b | ||
|
|
96474823b5 | ||
|
|
bbf4b54613 | ||
|
|
9795c5dd6b | ||
|
|
addcace80d | ||
|
|
77e43a5fa8 | ||
|
|
b751188e56 | ||
|
|
1ad9a15864 | ||
|
|
d0d7878e0a | ||
|
|
be5d365348 | ||
|
|
a8e0002a64 | ||
|
|
bf75cf7225 | ||
|
|
c024b680bc | ||
|
|
c896475765 | ||
|
|
101fdb3598 | ||
|
|
b13505afdf | ||
|
|
9d96b171a0 | ||
|
|
8b5a0cde69 | ||
|
|
bed7593cdd | ||
|
|
9fed946567 | ||
|
|
4d0bc0ae39 | ||
|
|
f9824aa7de | ||
|
|
4d2522964a | ||
|
|
dbe4a59b8e | ||
|
|
918f8a3ed4 | ||
|
|
f645596606 | ||
|
|
d778dd081d | ||
|
|
f6ed02c3fb | ||
|
|
7fa5dd7a35 | ||
|
|
a3186af099 | ||
|
|
a2d95ac742 | ||
|
|
10715bbea7 | ||
|
|
89fcb12556 | ||
|
|
cc3d7ddee5 | ||
|
|
cc01f99acb | ||
|
|
62b75190bb | ||
|
|
520124c1be | ||
|
|
e251bfcbaf | ||
|
|
aef809348f | ||
|
|
2d4a8774b8 | ||
|
|
b55c8fd828 |
@@ -2,6 +2,7 @@ Makefile
|
||||
Makefile.in
|
||||
SimGear.spec
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.log
|
||||
config.status
|
||||
|
||||
@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.0.17
|
||||
PROJECT_NUMBER = 0.3.0
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
||||
+8
-7
@@ -1,15 +1,16 @@
|
||||
EXTRA_DIST = \
|
||||
acsite.m4 \
|
||||
acconfig.h \
|
||||
mksymlinks.sh \
|
||||
acinclude.m4 \
|
||||
autogen.sh \
|
||||
README.MSVC \
|
||||
README.metakit \
|
||||
README.zlib \
|
||||
SimGear.dsp \
|
||||
SimGear.dsw \
|
||||
metakit-2.4.2-32.tar.gz \
|
||||
zlib-1.1.3.tar.gz
|
||||
SimGear.dsw
|
||||
|
||||
SUBDIRS = simgear
|
||||
SUBDIRS = src-libs simgear
|
||||
|
||||
dist-hook:
|
||||
(cd $(top_srcdir); $(HOME)/projects/FlightGear-0.7/admin/am2dsp.pl)
|
||||
|
||||
#
|
||||
# Rule to build RPM distribution package
|
||||
|
||||
@@ -1,10 +1,68 @@
|
||||
New in 0.3.0
|
||||
* December 3, 2002
|
||||
|
||||
* removed interpreter subdir
|
||||
* NOMINAX fix for Cygwin/gcc-3.2
|
||||
* Added some prototype 3d clouds based on Mark Harris's demos.
|
||||
* Simplified the command manager interface
|
||||
* Allow an "include" attribute on root PropertyList element.
|
||||
|
||||
|
||||
New in 0.2.0
|
||||
* September 6, 2002
|
||||
|
||||
* Modernized the autoconf/make scripts, plus lots of tweaks and enhancements.
|
||||
* Removed efence support (in favor of valgrind.)
|
||||
|
||||
* Added a javascript interpreter.
|
||||
* SGSocket reimplimented on top of plib/net libs.
|
||||
* Added a new random number generation algorithm.
|
||||
* Total rewrite of the strutils package.
|
||||
|
||||
* Patch for the random number seed.
|
||||
* IA-64 w/ Intel compiler fixes.
|
||||
* MSVC/MINGW fixes.
|
||||
* Mac OS X fixes.
|
||||
* Irix fixes.
|
||||
* Code clean ups to remove warning messages.
|
||||
* Optimizations in sg_binobj to reduce the amout of memory copying
|
||||
needed when loading a binobj format file.
|
||||
* Fixed a couple places where variables could be used before they were
|
||||
initialized.
|
||||
* Various property manager fixes and improvements.
|
||||
* Fixes to cloud layer management code.
|
||||
* Made the sky dome more flexible to facilitate use in other applications.
|
||||
|
||||
|
||||
New in 0.0.18
|
||||
* April 20, 2002
|
||||
|
||||
* Created a src/libs subdirectory for several packages that need to be
|
||||
installed by the user but are used by many other packages and may already
|
||||
be installed. So we just bundle the source separately as a convenience
|
||||
if the user needs to build and install these.
|
||||
* Upgrade to zlib-1.1.4 (security fix)
|
||||
* Upgrade to metakit-2.4.2-32.tar.gz (latest upstream release)
|
||||
* Added support for point objects in the scenery file format.
|
||||
* Additions to the binary file format to make it *much* more flexible.
|
||||
For each major primative type: points, triangles, fans, and strips, you
|
||||
can specify an index list of vertices, normals, colors, and texture
|
||||
coordinates. You can skip any of these you like to save on space.
|
||||
* Added support for new file features in the binary -> ascii scenery file
|
||||
decoder.
|
||||
* Various code clean ups.
|
||||
* Separate XML I/O operations into a separate header file.
|
||||
* Major property manager rewrite, then lots of followup cleaning and
|
||||
improvements.
|
||||
|
||||
|
||||
New in 0.0.17 (final)
|
||||
* February 16, 2002
|
||||
|
||||
* Converted some cout's to SG_LOG's.
|
||||
* xplicitely reset the glBlendFunc() after drawing the moon for the
|
||||
* Explicitely reset the glBlendFunc() after drawing the moon for the
|
||||
Voodoo2 linux driver since it seems to have a bug in glPopAttrib().
|
||||
|
||||
|
||||
New in 0.0.17pre2
|
||||
* February 13, 2002
|
||||
|
||||
@@ -60,6 +118,7 @@ New in 0.0.16
|
||||
ultra-hires tiled screen dumps suitable for large format printers.
|
||||
(Norman Vine)
|
||||
|
||||
|
||||
New in 0.0.15
|
||||
* June 20, 2001
|
||||
* Various bug fixes, tweaks, and optimizations.
|
||||
@@ -88,6 +147,7 @@ New in 0.0.15
|
||||
* Fixed some critical null pointer bugs in property manager.
|
||||
* Magnetic variation can now be fetched for any arbitrary location.
|
||||
|
||||
|
||||
New in 0.0.14
|
||||
* December 14, 2000
|
||||
* Added a module to manage waypoints and routes, calculate bearing and
|
||||
@@ -109,6 +169,7 @@ New in 0.0.14
|
||||
* MacOS tweaks.
|
||||
* FreeBSD tweaks.
|
||||
|
||||
|
||||
New in 0.0.13
|
||||
* September 14, 2000
|
||||
* Added support for reading and writing xml files (easyxml)
|
||||
@@ -119,6 +180,7 @@ New in 0.0.13
|
||||
* MacOS tweaks.
|
||||
* MSVC tweaks.
|
||||
|
||||
|
||||
New in 0.0.12
|
||||
* July 19, 2000
|
||||
* Converted project license from GPL to LGPL.
|
||||
@@ -128,6 +190,7 @@ New in 0.0.12
|
||||
* Added a property manager (registry)
|
||||
* Some documentation added.
|
||||
|
||||
|
||||
New in 0.0.11
|
||||
* July 3, 2000
|
||||
* Replaced gdbm with metakit
|
||||
@@ -136,6 +199,7 @@ New in 0.0.11
|
||||
* 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
|
||||
@@ -148,18 +212,22 @@ New in 0.0.7
|
||||
* Optimizations and bullet proofing of magnetic variation code by Norman
|
||||
Vine and Ed Williams
|
||||
|
||||
|
||||
New in 0.0.6
|
||||
* March 27, 2000
|
||||
* Added Nima World Magnetic Model 2000 contributed by Ed Williams
|
||||
* Fixes for MSVC++
|
||||
|
||||
|
||||
New in 0.0.5
|
||||
* March 17, 2000
|
||||
* Restructured directory layout to facilitate windows/mac IDE builds.
|
||||
|
||||
|
||||
New in 0.0.4
|
||||
* Removed mat3.h and friends (we now use plib's sg lib for these sorts of
|
||||
things.)
|
||||
|
||||
|
||||
New in 0.0.3
|
||||
* Release that conincides with FlightGear-0.7.2
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
This document describes how to build SimGear using the supplied workspace and
|
||||
project files.
|
||||
|
||||
Unpack the SimGear source file into your work directory. This creates a new
|
||||
subdirectory called SimGear-X.Y.Z. Rename this to SimGear. Before we can
|
||||
build SimGear you must unpack and build the third party libraries metakit and
|
||||
zlib. Sources for these are included in the SimGear/src-libs directory.
|
||||
Unpack these into the top level SimGear directory. At this point your
|
||||
directory structure should look something like this:
|
||||
|
||||
<work_dir>/
|
||||
SimGear/
|
||||
metakit-x.y.z/
|
||||
simgear/
|
||||
src-libs/
|
||||
zlib-x.y.z/
|
||||
|
||||
Now open the SimGear workspace. This workspace file contains projects for
|
||||
building metakit(mklib), SimGear and zlib. Select each project as the active
|
||||
project and build all. Order is unimportant since there are no dependencies
|
||||
between the projects.
|
||||
|
||||
The workspace and project files are generated by a perl script with extra
|
||||
input from the am2dsp.cfg file.
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
For your convenience (and with the author's permission) a copy of the
|
||||
MetaKit source is bundled with SimGear. You must have metakit
|
||||
installed before you can build SimGear.
|
||||
MetaKit source is bundled with SimGear in $(top_srcdir)/src-libs/.
|
||||
You must have metakit installed before you can build SimGear.
|
||||
|
||||
- Most linux distributions have a metakit package. For linux
|
||||
developers, we recommend ysou install your distributions package
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
[This file is mirrored in both the FlightGear and SimGear packages.]
|
||||
|
||||
You *must* have plib version 1.6.0 or later installed on your system
|
||||
to build FlightGear!" Flight Gear is no longer compatible with the
|
||||
earlier versions of the library.
|
||||
|
||||
You can get the latest version of plib from:
|
||||
|
||||
http://plib.sourceforge.net
|
||||
|
||||
Build notes:
|
||||
|
||||
You should be able to just run "./configure" to configure the package
|
||||
and use all of plib's defaults. Then run "make" followed by "make
|
||||
install". By default, plib installs itself into /usr so if you don't
|
||||
like this, be sure to specify an alternate prefix such as --prefix=/usr/local
|
||||
+33
-33
@@ -1,7 +1,7 @@
|
||||
For your convenience and allowed by zlib's license terms:
|
||||
http://www.gzip.org/zlib/zlib_license.html a copy of the zlib source
|
||||
is bundled with SimGear. You must have zlib installed before you can
|
||||
build SimGear.
|
||||
is bundled with SimGear in $(top_srcdir)/src-libs/. You must have
|
||||
zlib installed before you can build SimGear.
|
||||
|
||||
- Most linux distributions have a zlib package. For linux
|
||||
developers, we recommend ysou install your distributions package
|
||||
@@ -23,10 +23,11 @@ We now send you to the official zlib README ...
|
||||
|
||||
=============================================================================
|
||||
|
||||
zlib 1.1.3 is a general purpose data compression library. All the code
|
||||
|
||||
zlib 1.1.4 is a general purpose data compression library. All the code
|
||||
is thread safe. The data format used by the zlib library
|
||||
is described by RFCs (Request for Comments) 1950 to 1952 in the files
|
||||
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
|
||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
|
||||
format) and rfc1952.txt (gzip format). These documents are also available in
|
||||
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
|
||||
|
||||
@@ -39,51 +40,50 @@ except example.c and minigzip.c.
|
||||
|
||||
To compile all files and run the test program, follow the instructions
|
||||
given at the top of Makefile. In short "make test; make install"
|
||||
should work for most machines. For Unix: "configure; make test; make install"
|
||||
should work for most machines. For Unix: "./configure; make test; make install"
|
||||
For MSDOS, use one of the special makefiles such as Makefile.msc.
|
||||
For VMS, use Make_vms.com or descrip.mms.
|
||||
|
||||
Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to
|
||||
Questions about zlib should be sent to <zlib@gzip.org>, or to
|
||||
Gilles Vollant <info@winimage.com> for the Windows DLL version.
|
||||
The zlib home page is http://www.cdrom.com/pub/infozip/zlib/
|
||||
The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/
|
||||
Before reporting a problem, please check those sites to verify that
|
||||
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
|
||||
Before reporting a problem, please check this site to verify that
|
||||
you have the latest version of zlib; otherwise get the latest version and
|
||||
check whether the problem still exists or not.
|
||||
|
||||
Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997
|
||||
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
|
||||
before asking for help.
|
||||
|
||||
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available in
|
||||
http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm
|
||||
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
|
||||
|
||||
The changes made in version 1.1.3 are documented in the file ChangeLog.
|
||||
The main changes since 1.1.2 are:
|
||||
The changes made in version 1.1.4 are documented in the file ChangeLog.
|
||||
The only changes made since 1.1.3 are bug corrections:
|
||||
|
||||
- fix "an inflate input buffer bug that shows up on rare but persistent
|
||||
occasions" (Mark)
|
||||
- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
|
||||
- fix gzseek(..., SEEK_SET) in write mode
|
||||
- fix crc check after a gzeek (Frank Faubert)
|
||||
- fix miniunzip when the last entry in a zip file is itself a zip file
|
||||
(J Lillge)
|
||||
- add contrib/asm586 and contrib/asm686 (Brian Raiter)
|
||||
See http://www.muppetlabs.com/~breadbox/software/assembly.html
|
||||
- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
|
||||
- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
|
||||
- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
|
||||
- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
|
||||
- added a FAQ file
|
||||
- ZFREE was repeated on same allocation on some error conditions.
|
||||
This creates a security problem described in
|
||||
http://www.zlib.org/advisory-2002-03-11.txt
|
||||
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
|
||||
- Avoid accesses before window for invalid distances with inflate window
|
||||
less than 32K.
|
||||
- force windowBits > 8 to avoid a bug in the encoder for a window size
|
||||
of 256 bytes. (A complete fix will be available in 1.1.5).
|
||||
|
||||
The beta version 1.1.5beta includes many more changes. A new official
|
||||
version 1.1.5 will be released as soon as extensive testing has been
|
||||
completed on it.
|
||||
|
||||
plus many changes for portability.
|
||||
|
||||
Unsupported third party contributions are provided in directory "contrib".
|
||||
|
||||
A Java implementation of zlib is available in the Java Development Kit 1.1
|
||||
A Java implementation of zlib is available in the Java Development Kit
|
||||
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
|
||||
See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details.
|
||||
See the zlib home page http://www.zlib.org for details.
|
||||
|
||||
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
|
||||
is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
|
||||
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
|
||||
is in the CPAN (Comprehensive Perl Archive Network) sites
|
||||
http://www.cpan.org/modules/by-module/Compress/
|
||||
|
||||
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
|
||||
is available in Python 1.5 and later versions, see
|
||||
@@ -142,7 +142,7 @@ Acknowledgments:
|
||||
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-1998 Jean-loup Gailly and Mark Adler
|
||||
(C) 1995-2002 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
+340
-370
@@ -30,19 +30,12 @@ RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "HAVE_CONFIG_H" /I "." /I ".." /I ".\SimGear" /D "HAVE_CONFIG_H" /D "NDEBUG" /D "WIN32" /D "_MBCS" /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_MBCS" /FD /c /MT /I "." /I ".." /I ".\SimGear" /I ".\SimGear\metakit-2.4.3\include" /I "..\SimGear\zlib-1.1.4" /D "HAVE_CONFIG_H"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
@@ -53,19 +46,12 @@ LINK32=link.exe -lib
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /GX /ZI /Od /D "HAVE_CONFIG_H" /I "." /I ".." /I ".\SimGear" /D "HAVE_CONFIG_H" /D "_DEBUG" /D "WIN32" /D "_MBCS" /FR /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD CPP /nologo /W3 /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_MBCS" /FR /FD /GZ /c /MT /I "." /I ".." /I ".\SimGear" /I ".\SimGear\metakit-2.4.3\include" /I "..\SimGear\zlib-1.1.4" /D "HAVE_CONFIG_H"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
@@ -409,6 +395,21 @@ SOURCE=.\simgear\io\sg_socket.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\io\sg_socket_udp.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgio"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgio"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgmagvar"
|
||||
@@ -1131,6 +1132,325 @@ SOURCE=.\simgear\sky\stars.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgclouds3d"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\vec3fv.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\mat16fv.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\tri.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\plane.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\camera.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\camutils.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\minmaxbox.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyMinMaxBox.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyLight.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyMaterial.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyTextureManager.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyTextureState.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyDynamicTextureManager.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyRenderableInstanceCloud.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyRenderableInstanceGroup.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyCloud.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyArchive.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyUtil.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkyContext.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkySceneManager.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\sky\clouds3d\SkySceneLoader.cpp
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgclouds3d"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgclouds3d"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgtiming"
|
||||
@@ -1490,376 +1810,26 @@ SOURCE=.\simgear\xml\xmltok_impl.h
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_z"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\adler32.c
|
||||
SOURCE=.\simgear\simgear_config.h.vc5
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\compress.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\crc32.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\deflate.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\deflate.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\gzio.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infblock.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infblock.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infcodes.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infcodes.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inffast.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inffast.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inffixed.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inflate.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inftrees.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\inftrees.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infutil.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\infutil.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\trees.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\trees.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\uncompr.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\zutil.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\zlib\zutil.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_z"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_z"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
# Begin Source File
|
||||
|
||||
SOURCE = .\simgear\simgear_config.h.vc5
|
||||
|
||||
!IF "$(CFG)" == "FlightGear - Win32 Release"
|
||||
|
||||
# Begin Custom Build - Creating config.h
|
||||
InputPath=.\simgear\simgear_config.h.vc5
|
||||
|
||||
".\simgear\simgear_config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# Begin Custom Build - Creating config.h
|
||||
InputPath=.\simgear\simgear_config.h.vc5
|
||||
|
||||
".\simgear\simgear_config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h
|
||||
|
||||
# End Custom Build
|
||||
|
||||
+24
@@ -15,6 +15,30 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "mklib"=".\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "zlib"=".\SimGear\zlib.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
03/25/2001 - Resolve location of Sky dome implimentation documentation.
|
||||
-327
@@ -1,327 +0,0 @@
|
||||
/* acconfig.h
|
||||
This file is in the public domain.
|
||||
|
||||
Descriptive text for the C preprocessor macros that
|
||||
the distributed Autoconf macros can define.
|
||||
No software package will use all of them; autoheader copies the ones
|
||||
your configure.in uses into your configuration header file templates.
|
||||
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). Although this order
|
||||
can split up related entries, it makes it easier to check whether
|
||||
a given entry is in the file.
|
||||
|
||||
Leave the following blank line there!! Autoheader needs it. */
|
||||
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define if type char is unsigned and you are not using gcc. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
#undef __CHAR_UNSIGNED__
|
||||
#endif
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef CLOSEDIR_VOID
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
#undef DGUX
|
||||
|
||||
/* Define if you have <dirent.h>. */
|
||||
#undef DIRENT
|
||||
|
||||
/* Define to enable audio support */
|
||||
#undef ENABLE_AUDIO_SUPPORT
|
||||
|
||||
/* Define to enable GLUT joystick support (limited to 3 axes) */
|
||||
#undef ENABLE_GLUT_JOYSTICK
|
||||
|
||||
/* Define to enable plib joystick support (recommended) */
|
||||
#undef ENABLE_PLIB_JOYSTICK
|
||||
|
||||
/* Define to eliminate all trace of debugging messages such as for a
|
||||
release build */
|
||||
#undef FG_NDEBUG
|
||||
|
||||
/* Define to include Oliver's networking support */
|
||||
#undef FG_NETWORK_OLK
|
||||
|
||||
/* Define to avoid Christian's new weather code */
|
||||
#undef FG_OLD_WEATHER
|
||||
|
||||
/* Define if we are building FGFS (should always be defined) */
|
||||
#undef FGFS
|
||||
|
||||
/* Define to enable 3dfx/glide render in a window hack under unix.
|
||||
This probably won't work under windows. */
|
||||
#undef XMESA
|
||||
#undef FX
|
||||
|
||||
/* Define to the type of elements in the array set by `getgroups'.
|
||||
Usually this is either `int' or `gid_t'. */
|
||||
#undef GETGROUPS_T
|
||||
|
||||
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
|
||||
#undef GETLOADAVG_PRIVILEGED
|
||||
|
||||
/* Define if the `getpgrp' function takes no argument. */
|
||||
#undef GETPGRP_VOID
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you external variables daylight. */
|
||||
#undef HAVE_DAYLIGHT
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if your system has a working fnmatch function. */
|
||||
#undef HAVE_FNMATCH
|
||||
|
||||
/* Define if your system has its own `getloadavg' function. */
|
||||
#undef HAVE_GETLOADAVG
|
||||
|
||||
/* Define if you have getrusage() */
|
||||
#undef HAVE_GETRUSAGE
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
#undef HAVE_GETMNTENT
|
||||
|
||||
/* Define if you have the gpc library and headers installed. */
|
||||
#undef HAVE_GPC_H
|
||||
|
||||
/* Define if the `long double' type works. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#undef HAVE_LONG_FILE_NAMES
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if system calls automatically restart after interruption
|
||||
by a signal. */
|
||||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||
|
||||
/* Define if you have rint() which rounds to closest int but returns
|
||||
result as a double data type. */
|
||||
#undef HAVE_RINT
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
#undef HAVE_ST_BLOCKS
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#undef HAVE_STRCOLL
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the stdint.h include. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have <sys/param.h> */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have <sys/stat.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have timegm() */
|
||||
#undef HAVE_TIMEGM
|
||||
|
||||
/* Define if you external variables timezone. */
|
||||
#undef HAVE_TIMEZONE
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
#undef HAVE_TM_ZONE
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#undef HAVE_TZNAME
|
||||
|
||||
/* Define if you have <unistd.h>. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you have the wait3 system call. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
#undef inline
|
||||
|
||||
/* Define if int is 16 bits instead of 32. */
|
||||
#undef INT_16_BITS
|
||||
|
||||
/* Define if long int is 64 bits. */
|
||||
#undef LONG_64_BITS
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
|
||||
#undef MAJOR_IN_MKDEV
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
|
||||
#undef MAJOR_IN_SYSMACROS
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <ndir.h>. */
|
||||
#undef NDIR
|
||||
|
||||
/* Define if you have <memory.h>, and <string.h> doesn't declare the
|
||||
mem* functions. */
|
||||
#undef NEED_MEMORY_H
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
#undef NLIST_NAME_UNION
|
||||
|
||||
/* Define if you have <nlist.h>. */
|
||||
#undef NLIST_STRUCT
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to package name */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define if the `setpgrp' function takes no argument. */
|
||||
#undef SETPGRP_VOID
|
||||
|
||||
/* Define if the setvbuf function takes the buffering type as its second
|
||||
argument and the buffer pointer as the third, as on System V
|
||||
before release 3. */
|
||||
#undef SETVBUF_REVERSED
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
#undef SVR4
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <sys/dir.h>. */
|
||||
#undef SYSDIR
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <sys/ndir.h>. */
|
||||
#undef SYSNDIR
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
#undef SYS_SIGLIST_DECLARED
|
||||
|
||||
/* 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. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define for Encore UMAX. */
|
||||
#undef UMAX
|
||||
|
||||
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||
instead of <sys/cpustats.h>. */
|
||||
#undef UMAX4_3
|
||||
|
||||
/* Define if you do not have <strings.h>, index, bzero, etc.. */
|
||||
#undef USG
|
||||
|
||||
/* Define to version number */
|
||||
#undef VERSION
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef VOID_CLOSEDIR
|
||||
|
||||
/* Define if compiling on a Winbloze (95, NT, etc.) platform */
|
||||
#undef WIN32
|
||||
|
||||
/* Define if your processor stores words with the most significant
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Define if the X Window System is missing or not being used. */
|
||||
#undef X_DISPLAY_MISSING
|
||||
|
||||
/* Define if lex declares yytext as a char * by default, not a char[]. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
If you're adding to this file, keep in mind:
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). */
|
||||
|
||||
@@ -102,7 +102,7 @@ for exdir in $exdirs ; do
|
||||
mylibdir="${exdir}/lib${subexdir}"
|
||||
wi_EXTRA_LDIR($mylibdir)
|
||||
|
||||
progdir="${exdir}/bin${subexdirr}"
|
||||
progdir="${exdir}/bin${subexdir}"
|
||||
wi_EXTRA_PDIR($progdir)
|
||||
fi
|
||||
done
|
||||
+11
-12
@@ -1,40 +1,39 @@
|
||||
type = StaticLibrary,Multithreaded,
|
||||
exclude_dir = threads
|
||||
|
||||
include_path = .
|
||||
include_path = ..
|
||||
include_path = .\SimGear
|
||||
#include_path = \usr\include
|
||||
include_path = .\SimGear\metakit-2.4.3\include
|
||||
include_path = ..\SimGear\zlib-1.1.4
|
||||
|
||||
define = HAVE_CONFIG_H
|
||||
|
||||
#add_project = .\SimGear\simgear\metakit\win\msvc60\mklib.dsp
|
||||
add_project = .\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp,mklib
|
||||
add_project = .\SimGear\zlib.dsp,zlib
|
||||
|
||||
# Rule to create simgear_config.h
|
||||
add_source_file = \
|
||||
# Begin Source File\
|
||||
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
SOURCE = .\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
!IF "$(CFG)" == "FlightGear - Win32 Release"\
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"\
|
||||
\
|
||||
# Begin Custom Build - Creating config.h\
|
||||
InputPath=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
".\simgear\simgear_config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
|
||||
\
|
||||
# End Custom Build\
|
||||
\
|
||||
!ELSEIF "$(CFG)" == "FlightGear - Win32 Debug"\
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"\
|
||||
\
|
||||
# Begin Custom Build - Creating config.h\
|
||||
InputPath=.\simgear\simgear_config.h.vc5\
|
||||
\
|
||||
".\simgear\simgear_config.h": $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
".\simgear\simgear_config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\
|
||||
copy .\simgear\simgear_config.h.vc5 .\simgear\simgear_config.h\
|
||||
\
|
||||
# End Custom Build\
|
||||
\
|
||||
!ENDIF\
|
||||
\
|
||||
# End Source File
|
||||
|
||||
|
||||
+20
-25
@@ -2,45 +2,40 @@
|
||||
|
||||
OSTYPE=`uname -s`
|
||||
MACHINE=`uname -m`
|
||||
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\-p[0-9]$//' | sed -e 's/\.//'`
|
||||
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\.\([0-9]*\).*/\1/'`
|
||||
if test $AUTO_MAKE_VERSION -lt 15; then
|
||||
echo ""
|
||||
echo "You need to upgrade to automake version 1.5 or greater."
|
||||
echo "Most distributions have packages available to install or you can"
|
||||
echo "find the source for the most recent version at"
|
||||
echo "ftp://ftp.gnu.org/gnu/automake"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Host info: $OSTYPE $MACHINE"
|
||||
echo -n " automake: `automake --version | head -1 | awk '{print $4}'`"
|
||||
echo " ($AUTO_MAKE_VERSION)"
|
||||
echo ""
|
||||
|
||||
ACLOCAL_OPTS=""
|
||||
if [ $AUTO_MAKE_VERSION -ge 14 ]; then
|
||||
if [ $OSTYPE = "IRIX" -o $OSTYPE = "IRIX64" ]; then echo " -I ."
|
||||
ACLOCAL_OPTS="-I ."
|
||||
fi
|
||||
fi
|
||||
echo "Running aclocal $ACLOCAL_OPTS"
|
||||
aclocal $ACLOCAL_OPTS
|
||||
echo "Running aclocal"
|
||||
aclocal
|
||||
|
||||
echo "Running autoheader"
|
||||
autoheader
|
||||
if [ ! -e simgear/simgear_config.h.in ]; then
|
||||
echo "ERROR: autoheader didn't create simgear/simgear_config.h.in!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Running automake"
|
||||
if [ $OSTYPE = "IRIX" -o $OSTYPE = "IRIX64" ]; then
|
||||
echo " --add-missing --include-deps"
|
||||
automake --add-missing --include-deps
|
||||
else
|
||||
echo " --add-missing"
|
||||
automake --add-missing
|
||||
fi
|
||||
echo "Running automake --add-missing"
|
||||
automake --add-missing
|
||||
|
||||
echo "Running autoconf"
|
||||
autoconf
|
||||
|
||||
# fixup Makefiles for Irix
|
||||
if test "$OSTYPE" = "IRIX" -o "$OSTYPE" = "IRIX64"; then
|
||||
echo "Fixing Makefiles for Irix"
|
||||
for n in `find . -name Makefile.in`; do \
|
||||
mv -f $n $n.ar-new; \
|
||||
sed 's/$(AR) cru /$(AR) -o /g' $n.ar-new > $n; \
|
||||
rm -f $n.ar-new; \
|
||||
done;
|
||||
if [ ! -e configure ]; then
|
||||
echo "ERROR: configure was not created!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
+64
-45
@@ -3,13 +3,14 @@ dnl working configure script.
|
||||
dnl
|
||||
dnl $Id$
|
||||
|
||||
AC_INIT(simgear/bucket/newbucket.cxx)
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
|
||||
|
||||
# Require at least automake 2.13
|
||||
AC_PREREQ(2.13)
|
||||
# Require at least automake 2.52
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.17pre2)
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.3.0)
|
||||
|
||||
dnl Specify KAI C++ compiler and flags.
|
||||
dnl Borrowed with slight modification from blitz distribution.
|
||||
@@ -37,14 +38,20 @@ AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
|
||||
# Used on the Irix platform
|
||||
AR="ar"
|
||||
ARFLAGS="cru"
|
||||
OS=`uname -s`
|
||||
if test "$OS" = "IRIX" -o "$OS" = "IRIX64"; then
|
||||
if test "$CXX" = "CC"; then
|
||||
AR="CC -ar"
|
||||
AC_SUBST(AR)
|
||||
ARFLAGS="-o"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(AR)
|
||||
AC_SUBST(ARFLAGS)
|
||||
|
||||
|
||||
if echo $includedir | egrep "simgear$" > /dev/null; then
|
||||
echo "includedir is" $includedir "libdir is" $libdir
|
||||
@@ -53,25 +60,11 @@ else
|
||||
echo "includedir changed to" $includedir "libdir is" $libdir
|
||||
fi
|
||||
|
||||
# Determine version of automake ... important because of
|
||||
# incompatibilities between versions
|
||||
AUTO_MAKE_VERSION=`automake --version | head -1 | awk '{print $4}' | sed -e 's/\-p[[0-9]]$//' | sed -e 's/\.//'`
|
||||
AM_CONDITIONAL(ANCIENT_AUTOMAKE, test $AUTO_MAKE_VERSION -lt 14)
|
||||
AM_CONDITIONAL(OLD_AUTOMAKE, test $AUTO_MAKE_VERSION -lt 15)
|
||||
|
||||
# set logging default value
|
||||
# with_logging=yes
|
||||
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
|
||||
if test "x$with_logging" = "xno" ; then
|
||||
AC_DEFINE(FG_NDEBUG)
|
||||
fi
|
||||
|
||||
dnl specify if we are building with "electric fence"
|
||||
AC_ARG_WITH(efence, [ --with-efence Specify if we are building with "electric-fence"])
|
||||
|
||||
if test "x$with_efence" = "xyes" ; then
|
||||
echo "Building with efence"
|
||||
LIBS="$LIBS -lefence"
|
||||
AC_DEFINE([FG_NDEBUG], 1, [Define for no logging output])
|
||||
fi
|
||||
|
||||
# Specify if we want to build with Norman's jpeg image server support.
|
||||
@@ -120,7 +113,7 @@ AM_CONDITIONAL(IS_CYGWIN, test "x$is_cygwin" = "xyes")
|
||||
|
||||
if test "x$HOSTTYPE" != "xmacintosh" -a "x$is_mingw" != "xyes"; then
|
||||
dnl extra library and include directories
|
||||
EXTRA_DIRS="/usr/local /usr/local/plib /usr/X11R6"
|
||||
EXTRA_DIRS="/usr/X11R6"
|
||||
|
||||
if test -d /opt/X11R6 ; then
|
||||
EXTRA_DIRS="$EXTRA_DIRS /opt/X11R6"
|
||||
@@ -136,9 +129,6 @@ dnl enough. AM_CONDITIONALS are then referenced to conditionally
|
||||
dnl build a Makefile.in from a Makefile.am which lets us define custom
|
||||
dnl includes, compile alternative source files, etc.
|
||||
|
||||
dnl Enable serial support on Unix type systems
|
||||
AM_CONDITIONAL(ENABLE_UNIX_SERIAL, true)
|
||||
|
||||
dnl X11 might be installed on Mac OS X, don't want to use it if it is.
|
||||
if test "x$HOSTTYPE" != "xmacintosh" ; then
|
||||
dnl Check for X11 (fancy)
|
||||
@@ -177,6 +167,8 @@ fi
|
||||
|
||||
dnl check for OpenGL related libraries
|
||||
|
||||
AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
|
||||
|
||||
if test "x$HOSTTYPE" = "xmacintosh" ; then
|
||||
dnl Macintosh OSX
|
||||
LIBS="$LIBS -framework OpenGL -framework GLUT"
|
||||
@@ -200,8 +192,8 @@ elif test "x$ac_cv_header_windows_h" != "xyes" ; then
|
||||
if test "x$ac_cv_lib_MesaGL_glNewList" = "xyes" ; then
|
||||
AC_CHECK_HEADER(GL/fxmesa.h)
|
||||
if test "x$ac_cv_header_GL_fxmesa_h" = "xyes"; then
|
||||
AC_DEFINE( XMESA )
|
||||
AC_DEFINE( FX )
|
||||
AC_DEFINE([XMESA], 1, [Define for fxmesa])
|
||||
AC_DEFINE([FX], 1, [Define for fxmesa])
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -223,10 +215,8 @@ else
|
||||
dnl Win32 libs
|
||||
|
||||
echo Win32 specific hacks...
|
||||
AC_DEFINE(WIN32)
|
||||
|
||||
dnl force a failed check since we will be building under windoze
|
||||
AM_CONDITIONAL(ENABLE_XMESA_FX, test "no" = "yes")
|
||||
AC_DEFINE([WIN32], 1, [Define for Win32 platforms])
|
||||
AC_DEFINE([NOMINMAX], 1, [Define for Win32 platforms])
|
||||
|
||||
dnl just define these to true and hope for the best
|
||||
ac_cv_lib_glut_glutGetModifiers="yes"
|
||||
@@ -262,7 +252,9 @@ fi
|
||||
if test "x$ac_cv_lib_glut_glutGameModeString" = "xno"; then
|
||||
echo
|
||||
echo "Your version of glut doesn't support game mode."
|
||||
echo "You need to fetch and install the latest version of glut from:"
|
||||
echo "You need to install the latest version of glut. If your"
|
||||
echo "distribution doesn't provide a newer version, you can get the source"
|
||||
echo "code from:"
|
||||
echo
|
||||
echo " http://reality.sgi.com/opengl/glut3/glut3.html"
|
||||
exit 1
|
||||
@@ -276,12 +268,17 @@ AC_SUBST(opengl_LIBS)
|
||||
|
||||
AM_CONDITIONAL(HAVE_XWINDOWS, test "x$ac_cv_lib_X11_XCreateWindow" = "xyes" )
|
||||
|
||||
# The following are C++ items that need to be tested for with the c++
|
||||
# compiler
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
|
||||
dnl Check for "plib" without which we cannot go on
|
||||
AC_CHECK_HEADER(plib/pu.h)
|
||||
if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
|
||||
AC_CHECK_HEADER(plib/ul.h)
|
||||
if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the plib library installed on your system to build"
|
||||
echo "the FGFS simulator!"
|
||||
echo "SimGear!"
|
||||
echo
|
||||
echo "Please see README.plib for more details."
|
||||
echo
|
||||
@@ -289,20 +286,46 @@ if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
|
||||
exit
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for plib 1.6.0 or newer])
|
||||
AC_TRY_RUN([
|
||||
#include <plib/ul.h>
|
||||
|
||||
#define MIN_PLIB_VERSION 160
|
||||
|
||||
int main() {
|
||||
int major, minor, micro;
|
||||
|
||||
if ( PLIB_VERSION < MIN_PLIB_VERSION ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
],
|
||||
AC_MSG_RESULT(yes),
|
||||
[AC_MSG_RESULT(wrong version);
|
||||
AC_MSG_ERROR([Install plib 1.6.0 or later first...])],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
dnl Check for system installed metakit
|
||||
AC_CHECK_HEADER(mk4.h)
|
||||
if test "x$ac_cv_header_mk4_h" != "xyes"; then
|
||||
echo
|
||||
echo "Metakit not found, you will need to install this first."
|
||||
echo "Please read the README.metakit for more information."
|
||||
exit
|
||||
fi
|
||||
|
||||
AC_LANG_POP
|
||||
|
||||
dnl Specify if we want logging (testing build) or not (release build)
|
||||
|
||||
dnl Check for system installed zlib
|
||||
AC_CHECK_HEADER(zlib.h)
|
||||
if test "x$ac_cv_header_zlib_h" != "xyes"; then
|
||||
echo
|
||||
echo "zlib not found, you will need to install this first."
|
||||
echo "Please read the README.zlib for more information."
|
||||
exit
|
||||
@@ -315,7 +338,7 @@ AC_CHECK_HEADERS( \
|
||||
sys/stat.h sys/time.h sys/timeb.h unistd.h windows.h winbase.h values.h )
|
||||
|
||||
if test "x$ac_cv_header_stdint_h" = "xyes"; then
|
||||
AC_DEFINE( HAVE_STDINT_H )
|
||||
AC_DEFINE([HAVE_STDINT_H], 1, [Define if stdint.h exists])
|
||||
fi
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@@ -328,13 +351,14 @@ dnl Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS( ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
|
||||
random setitimer getitimer signal GetLocalTime rint getrusage )
|
||||
random drand48 setitimer getitimer signal GetLocalTime rint getrusage )
|
||||
|
||||
AM_CONFIG_HEADER(simgear/simgear_config.h)
|
||||
|
||||
AC_OUTPUT( \
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
SimGear.spec \
|
||||
src-libs/Makefile \
|
||||
simgear/Makefile \
|
||||
simgear/version.h \
|
||||
simgear/bucket/Makefile \
|
||||
@@ -349,13 +373,14 @@ AC_OUTPUT( \
|
||||
simgear/screen/Makefile \
|
||||
simgear/serial/Makefile \
|
||||
simgear/sky/Makefile \
|
||||
simgear/sky/clouds3d/Makefile \
|
||||
simgear/threads/Makefile \
|
||||
simgear/timing/Makefile \
|
||||
simgear/xgl/Makefile \
|
||||
simgear/xml/Makefile \
|
||||
)
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
# AC_OUTPUT_COMMANDS([])
|
||||
|
||||
echo ""
|
||||
echo "Configure Summary"
|
||||
@@ -369,12 +394,6 @@ else
|
||||
echo "Debug messages: yes"
|
||||
fi
|
||||
|
||||
if test "x$with_efence" != "x"; then
|
||||
echo "Electric fence: $with_efence"
|
||||
else
|
||||
echo "Electric fence: no"
|
||||
fi
|
||||
|
||||
echo -n "Automake version: ($AUTO_MAKE_VERSION) "
|
||||
automake --version | head -1
|
||||
|
||||
Binary file not shown.
@@ -1,42 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
echo ""
|
||||
echo "running $0 to rebuild simgear include links"
|
||||
|
||||
# toast the old directory
|
||||
rm -rf src/simgear
|
||||
mkdir src/simgear
|
||||
mkdir src/simgear/bucket
|
||||
mkdir src/simgear/debug
|
||||
mkdir src/simgear/math
|
||||
mkdir src/simgear/misc
|
||||
mkdir src/simgear/screen
|
||||
mkdir src/simgear/serial
|
||||
mkdir src/simgear/xgl
|
||||
mkdir src/simgear/zlib
|
||||
|
||||
# build new links
|
||||
ln -s ../include/compiler.h src/simgear/compiler.h
|
||||
ln -s ../include/constants.h src/simgear/constants.h
|
||||
ln -s ../include/fg_traits.hxx src/simgear/fg_traits.hxx
|
||||
ln -s ../include/fg_zlib.h src/simgear/fg_zlib.h
|
||||
ln -s ../include/version.h src/simgear/version.h
|
||||
|
||||
ln -s ../../bucket/newbucket.hxx src/simgear/bucket/newbucket.hxx
|
||||
|
||||
ln -s ../../debug/debug_types.h src/simgear/debug/debug_types.h
|
||||
ln -s ../../debug/logstream.hxx src/simgear/debug/logstream.hxx
|
||||
|
||||
ln -s ../../math/fg_memory.h src/simgear/math/fg_memory.h
|
||||
ln -s ../../math/fg_types.hxx src/simgear/math/fg_types.hxx
|
||||
ln -s ../../math/point3d.hxx src/simgear/math/point3d.hxx
|
||||
ln -s ../../math/polar3d.hxx src/simgear/math/polar3d.hxx
|
||||
|
||||
ln -s ../../misc/fgpath.hxx src/simgear/misc/fgpath.hxx
|
||||
ln -s ../../misc/fgstream.hxx src/simgear/misc/fgstream.hxx
|
||||
ln -s ../../misc/zfstream.hxx src/simgear/misc/zfstream.hxx
|
||||
|
||||
ln -s ../../xgl/xgl.h src/simgear/xgl/xgl.h
|
||||
|
||||
ln -s ../../zlib/zlib.h src/simgear/zlib/zlib.h
|
||||
ln -s ../../zlib/zconf.h src/simgear/zlib/zconf.h
|
||||
@@ -1,6 +1,8 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
simgear_config.h
|
||||
simgear_config.h.in
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
version.h
|
||||
|
||||
+2
-7
@@ -1,9 +1,3 @@
|
||||
if ENABLE_UNIX_SERIAL
|
||||
SERIAL_DIRS = serial
|
||||
else
|
||||
SERIAL_DIRS =
|
||||
endif
|
||||
|
||||
if HAVE_THREADS
|
||||
SGTHREAD_DIR = threads
|
||||
else
|
||||
@@ -30,9 +24,10 @@ SUBDIRS = \
|
||||
$(METAR_DIRS) \
|
||||
route \
|
||||
screen \
|
||||
$(SERIAL_DIRS) \
|
||||
serial \
|
||||
sky \
|
||||
$(SGTHREAD_DIR) \
|
||||
timing \
|
||||
xgl
|
||||
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
|
||||
@@ -14,8 +14,4 @@ libsgbucket_a_SOURCES = newbucket.cxx
|
||||
# $(top_builddir)/bucket/libsgbucket.a \
|
||||
# $(top_builddir)/misc/libsgmisc.a
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
+39
-6
@@ -71,6 +71,14 @@
|
||||
#ifndef _SG_COMPILER_H
|
||||
#define _SG_COMPILER_H
|
||||
|
||||
/*
|
||||
* Helper macro SG_STRINGIZE:
|
||||
* Converts the parameter X to a string after macro replacement
|
||||
* on X has been performed.
|
||||
*/
|
||||
#define SG_STRINGIZE(X) SG_DO_STRINGIZE(X)
|
||||
#define SG_DO_STRINGIZE(X) #X
|
||||
|
||||
#ifdef __GNUC__
|
||||
# if __GNUC__ == 2
|
||||
# if __GNUC_MINOR__ < 8
|
||||
@@ -133,15 +141,18 @@
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# else
|
||||
# error Time to upgrade. GNU compilers < 2.7 not supported
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
|
||||
|
||||
#endif // __GNUC__
|
||||
|
||||
#if defined( __MINGW32__ )
|
||||
# define bcopy(from, to, n) memcpy(to, from, n)
|
||||
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/* KAI C++ */
|
||||
@@ -162,7 +173,10 @@
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
|
||||
|
||||
#endif // __KCC
|
||||
|
||||
//
|
||||
// Metrowerks
|
||||
@@ -193,7 +207,10 @@
|
||||
|
||||
// -dw- currently used glut has no game mode stuff
|
||||
# define GLUT_WRONG_VERSION
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "Metrowerks CodeWarrior C++ version " SG_STRINGIZE(__MWERKS__)
|
||||
|
||||
#endif // __MWERKS__
|
||||
|
||||
//
|
||||
// Microsoft compilers.
|
||||
@@ -218,13 +235,19 @@
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define snprintf _snprintf
|
||||
|
||||
# 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
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "Microsoft Visual C++ version " SG_STRINGIZE(_MSC_VER)
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# if defined(HAVE_SGI_STL_PORT)
|
||||
@@ -256,6 +279,8 @@
|
||||
# define SG_NAMESPACES
|
||||
// # define SG_HAVE_STD
|
||||
|
||||
# define SG_COMPILER_STR "Borland C++ version " SG_STRINGIZE(__BORLANDC__)
|
||||
|
||||
#endif // __BORLANDC__
|
||||
|
||||
//
|
||||
@@ -296,6 +321,8 @@
|
||||
#pragma set woff 1682,3303
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "SGI Irix compiler version " SG_STRINGIZE(_COMPILER_VERSION)
|
||||
|
||||
#endif // Native SGI compilers
|
||||
|
||||
|
||||
@@ -310,12 +337,15 @@
|
||||
# else
|
||||
extern void *memmove(void *, const void *, size_t);
|
||||
# endif // __cplusplus
|
||||
|
||||
# define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
|
||||
|
||||
#endif // sun
|
||||
|
||||
//
|
||||
// Intel C++ Compiler
|
||||
//
|
||||
#if defined(__ICC)
|
||||
#if defined(__ICC) || defined (__ECC)
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
@@ -331,6 +361,9 @@
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define SG_COMPILER_STR "Intel C++ version " SG_STRINGIZE(__ICC)
|
||||
|
||||
#endif // __ICC
|
||||
|
||||
//
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@
|
||||
|
||||
/** Highest binobj format version we know how to read/write. This starts at
|
||||
* 0 and can go up to 65535 */
|
||||
#define SG_BINOBJ_VERSION 5
|
||||
#define SG_BINOBJ_VERSION 6
|
||||
|
||||
/** for backwards compatibility */
|
||||
#define SG_SCENERY_FILE_FORMAT "0.4"
|
||||
|
||||
@@ -8,8 +8,4 @@ include_HEADERS = debug_types.h logstream.hxx
|
||||
|
||||
libsgdebug_a_SOURCES = logstream.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "logstream.hxx"
|
||||
|
||||
logstream *global_logstream = NULL;
|
||||
|
||||
bool logbuf::logging_enabled = true;
|
||||
sgDebugClass logbuf::logClass = SG_NONE;
|
||||
sgDebugPriority logbuf::logPriority = SG_INFO;
|
||||
|
||||
@@ -256,6 +256,7 @@ logstream::operator<< ( const loglevel& l )
|
||||
return *this;
|
||||
}
|
||||
|
||||
extern logstream *global_logstream;
|
||||
|
||||
/**
|
||||
* \relates logstream
|
||||
@@ -267,8 +268,22 @@ logstream::operator<< ( const loglevel& l )
|
||||
inline logstream&
|
||||
sglog()
|
||||
{
|
||||
static logstream logstrm( cerr );
|
||||
return logstrm;
|
||||
if (global_logstream == NULL) {
|
||||
|
||||
#ifdef __APPLE__
|
||||
/**
|
||||
* There appears to be a bug in the C++ runtime in Mac OS X that
|
||||
* will crash if certain funtions are called (in this case
|
||||
* cerr.rdbuf()) during static initialization of a class. This
|
||||
* print statement is hack to kick the library in the pants so it
|
||||
* won't crash when cerr.rdbuf() is first called -DW
|
||||
**/
|
||||
cout << "Using Mac OS X hack for initializing C++ stdio..." << endl;
|
||||
#endif
|
||||
global_logstream = new logstream (cerr);
|
||||
}
|
||||
|
||||
return *global_logstream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
#include <string>
|
||||
#include "Debug/logstream.hxx"
|
||||
|
||||
class Test {
|
||||
|
||||
public:
|
||||
Test() {
|
||||
//cout << "Cout seems to work" << endl;
|
||||
//cerr << "Cerr seems to work" << endl;
|
||||
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
|
||||
SG_LOG(SG_EVENT, SG_INFO, "Test::Test" << "foo");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Test test;
|
||||
|
||||
int
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
fglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
|
||||
SG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
|
||||
SG_LOG( FG_TERRAIN, SG_DEBUG, "terrain::debug" ); // shouldnt appear
|
||||
SG_LOG( FG_TERRAIN, SG_INFO, "terrain::info" );
|
||||
SG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
|
||||
SG_LOG( FG_TERRAIN, SG_ALERT, "terrain::alert" );
|
||||
//SG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
|
||||
//SG_LOG( FG_TERRAIN, SG_DEBUG, "terrain::debug" ); // shouldnt appear
|
||||
//SG_LOG( FG_TERRAIN, SG_INFO, "terrain::info" );
|
||||
//SG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
|
||||
//SG_LOG( FG_TERRAIN, SG_ALERT, "terrain::alert" );
|
||||
|
||||
int i = 12345;
|
||||
long l = 54321L;
|
||||
|
||||
@@ -31,8 +31,4 @@ libsgephem_a_SOURCES = \
|
||||
uranus.cxx \
|
||||
venus.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
@@ -158,22 +158,112 @@ double CelestialBody::sgCalcEccAnom(double M, double e)
|
||||
return eccAnom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* inline CelestialBody::CelestialBody
|
||||
* public constructor for a generic celestialBody object.
|
||||
* initializes the 6 primary orbital elements. The elements are:
|
||||
* N: longitude of the ascending node
|
||||
* i: inclination to the ecliptic
|
||||
* w: argument of perihelion
|
||||
* a: semi-major axis, or mean distance from the sun
|
||||
* e: eccenticity
|
||||
* M: mean anomaly
|
||||
* Each orbital element consists of a constant part and a variable part that
|
||||
* gradually changes over time.
|
||||
*
|
||||
* Argumetns:
|
||||
* the 13 arguments to the constructor constitute the first, constant
|
||||
* ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital
|
||||
* elements. The 13th argument is the current time. Note that the inclination
|
||||
* is written with a capital (If, Is), because 'if' is a reserved word in the
|
||||
* C/C++ programming language.
|
||||
***************************************************************************/
|
||||
CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
double If, double Is,
|
||||
double wf, double ws,
|
||||
double af, double as,
|
||||
double ef, double es,
|
||||
double Mf, double Ms, double mjd)
|
||||
{
|
||||
NFirst = Nf; NSec = Ns;
|
||||
iFirst = If; iSec = Is;
|
||||
wFirst = wf; wSec = ws;
|
||||
aFirst = af; aSec = as;
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
updateOrbElements(mjd);
|
||||
}
|
||||
|
||||
CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
double If, double Is,
|
||||
double wf, double ws,
|
||||
double af, double as,
|
||||
double ef, double es,
|
||||
double Mf, double Ms)
|
||||
{
|
||||
NFirst = Nf; NSec = Ns;
|
||||
iFirst = If; iSec = Is;
|
||||
wFirst = wf; wSec = ws;
|
||||
aFirst = af; aSec = as;
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* inline void CelestialBody::updateOrbElements(double mjd)
|
||||
* given the current time, this private member calculates the actual
|
||||
* orbital elements
|
||||
*
|
||||
* Arguments: double mjd: the current modified julian date:
|
||||
*
|
||||
* return value: none
|
||||
***************************************************************************/
|
||||
void CelestialBody::updateOrbElements(double mjd)
|
||||
{
|
||||
double actTime = sgCalcActTime(mjd);
|
||||
M = SGD_DEGREES_TO_RADIANS * (MFirst + (MSec * actTime));
|
||||
w = SGD_DEGREES_TO_RADIANS * (wFirst + (wSec * actTime));
|
||||
N = SGD_DEGREES_TO_RADIANS * (NFirst + (NSec * actTime));
|
||||
i = SGD_DEGREES_TO_RADIANS * (iFirst + (iSec * actTime));
|
||||
e = eFirst + (eSec * actTime);
|
||||
a = aFirst + (aSec * actTime);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* inline double CelestialBody::sgCalcActTime(double mjd)
|
||||
* this private member function returns the offset in days from the epoch for
|
||||
* wich the orbital elements are calculated (Jan, 1st, 2000).
|
||||
*
|
||||
* Argument: the current time
|
||||
*
|
||||
* return value: the (fractional) number of days until Jan 1, 2000.
|
||||
****************************************************************************/
|
||||
double CelestialBody::sgCalcActTime(double mjd)
|
||||
{
|
||||
return (mjd - 36523.5);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* inline void CelestialBody::getPos(double* ra, double* dec)
|
||||
* gives public access to Right Ascension and declination
|
||||
*
|
||||
****************************************************************************/
|
||||
void CelestialBody::getPos(double* ra, double* dec)
|
||||
{
|
||||
*ra = rightAscension;
|
||||
*dec = declination;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
|
||||
* gives public acces to the current Right ascension, declination, and
|
||||
* magnitude
|
||||
****************************************************************************/
|
||||
void CelestialBody::getPos(double* ra, double* dec, double* magn)
|
||||
{
|
||||
*ra = rightAscension;
|
||||
*dec = declination;
|
||||
*magn = magnitude;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -87,113 +87,6 @@ public:
|
||||
void updatePosition(double mjd, Star *ourSun);
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* inline CelestialBody::CelestialBody
|
||||
* public constructor for a generic celestialBody object.
|
||||
* initializes the 6 primary orbital elements. The elements are:
|
||||
* N: longitude of the ascending node
|
||||
* i: inclination to the ecliptic
|
||||
* w: argument of perihelion
|
||||
* a: semi-major axis, or mean distance from the sun
|
||||
* e: eccenticity
|
||||
* M: mean anomaly
|
||||
* Each orbital element consists of a constant part and a variable part that
|
||||
* gradually changes over time.
|
||||
*
|
||||
* Argumetns:
|
||||
* the 13 arguments to the constructor constitute the first, constant
|
||||
* ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital
|
||||
* elements. The 13th argument is the current time. Note that the inclination
|
||||
* is written with a capital (If, Is), because 'if' is a reserved word in the
|
||||
* C/C++ programming language.
|
||||
***************************************************************************/
|
||||
inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
double If, double Is,
|
||||
double wf, double ws,
|
||||
double af, double as,
|
||||
double ef, double es,
|
||||
double Mf, double Ms, double mjd)
|
||||
{
|
||||
NFirst = Nf; NSec = Ns;
|
||||
iFirst = If; iSec = Is;
|
||||
wFirst = wf; wSec = ws;
|
||||
aFirst = af; aSec = as;
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
updateOrbElements(mjd);
|
||||
}
|
||||
|
||||
inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
double If, double Is,
|
||||
double wf, double ws,
|
||||
double af, double as,
|
||||
double ef, double es,
|
||||
double Mf, double Ms)
|
||||
{
|
||||
NFirst = Nf; NSec = Ns;
|
||||
iFirst = If; iSec = Is;
|
||||
wFirst = wf; wSec = ws;
|
||||
aFirst = af; aSec = as;
|
||||
eFirst = ef; eSec = es;
|
||||
MFirst = Mf; MSec = Ms;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* inline void CelestialBody::updateOrbElements(double mjd)
|
||||
* given the current time, this private member calculates the actual
|
||||
* orbital elements
|
||||
*
|
||||
* Arguments: double mjd: the current modified julian date:
|
||||
*
|
||||
* return value: none
|
||||
***************************************************************************/
|
||||
inline void CelestialBody::updateOrbElements(double mjd)
|
||||
{
|
||||
double actTime = sgCalcActTime(mjd);
|
||||
M = SGD_DEGREES_TO_RADIANS * (MFirst + (MSec * actTime));
|
||||
w = SGD_DEGREES_TO_RADIANS * (wFirst + (wSec * actTime));
|
||||
N = SGD_DEGREES_TO_RADIANS * (NFirst + (NSec * actTime));
|
||||
i = SGD_DEGREES_TO_RADIANS * (iFirst + (iSec * actTime));
|
||||
e = eFirst + (eSec * actTime);
|
||||
a = aFirst + (aSec * actTime);
|
||||
}
|
||||
/*****************************************************************************
|
||||
* inline double CelestialBody::sgCalcActTime(double mjd)
|
||||
* this private member function returns the offset in days from the epoch for
|
||||
* wich the orbital elements are calculated (Jan, 1st, 2000).
|
||||
*
|
||||
* Argument: the current time
|
||||
*
|
||||
* return value: the (fractional) number of days until Jan 1, 2000.
|
||||
****************************************************************************/
|
||||
inline double CelestialBody::sgCalcActTime(double mjd)
|
||||
{
|
||||
return (mjd - 36523.5);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* inline void CelestialBody::getPos(double* ra, double* dec)
|
||||
* gives public access to Right Ascension and declination
|
||||
*
|
||||
****************************************************************************/
|
||||
inline void CelestialBody::getPos(double* ra, double* dec)
|
||||
{
|
||||
*ra = rightAscension;
|
||||
*dec = declination;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
|
||||
* gives public acces to the current Right ascension, declination, and
|
||||
* magnitude
|
||||
****************************************************************************/
|
||||
inline void CelestialBody::getPos(double* ra, double* dec, double* magn)
|
||||
{
|
||||
*ra = rightAscension;
|
||||
*dec = declination;
|
||||
*magn = magnitude;
|
||||
}
|
||||
|
||||
inline double CelestialBody::getRightAscension() { return rightAscension; }
|
||||
inline double CelestialBody::getDeclination() { return declination; }
|
||||
inline double CelestialBody::getMagnitude() { return magnitude; }
|
||||
@@ -210,14 +103,3 @@ inline double CelestialBody::getLat()
|
||||
|
||||
#endif // _CELESTIALBODY_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,3 +4,5 @@ Makefile.in
|
||||
decode_binobj
|
||||
lowtest
|
||||
socktest
|
||||
tcp_client
|
||||
tcp_server
|
||||
|
||||
+23
-7
@@ -20,11 +20,7 @@ libsgio_a_SOURCES = \
|
||||
sg_socket.cxx \
|
||||
sg_socket_udp.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
if IS_MINGW
|
||||
NETWORK_LIB = -lwsock32
|
||||
@@ -32,7 +28,27 @@ else
|
||||
NETWORK_LIB =
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS = decode_binobj socktest lowtest
|
||||
noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
|
||||
|
||||
tcp_server_SOURCES = tcp_server.cxx
|
||||
|
||||
tcp_server_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lplibnet -lplibul -lz $(NETWORK_LIB)
|
||||
|
||||
tcp_client_SOURCES = tcp_client.cxx
|
||||
|
||||
tcp_client_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lplibnet -lplibul -lz $(NETWORK_LIB)
|
||||
|
||||
socktest_SOURCES = socktest.cxx
|
||||
|
||||
@@ -42,7 +58,7 @@ socktest_LDADD = \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lz
|
||||
-lplibnet -lplibul -lz $(NETWORK_LIB)
|
||||
|
||||
lowtest_SOURCES = lowtest.cxx
|
||||
|
||||
@@ -57,4 +73,4 @@ decode_binobj_LDADD = \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
$(NETWORK_LIB) -lz
|
||||
-lz
|
||||
|
||||
@@ -58,25 +58,49 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "# triangle groups" << endl;
|
||||
cout << "# geometry groups" << endl;
|
||||
cout << endl;
|
||||
|
||||
string material;
|
||||
int_list vertex_index;
|
||||
int_list normal_index;
|
||||
int_list tex_index;
|
||||
|
||||
// generate points
|
||||
string_list pt_materials = obj.get_pt_materials();
|
||||
group_list pts_v = obj.get_pts_v();
|
||||
group_list pts_n = obj.get_pts_n();
|
||||
for ( i = 0; i < (int)pts_v.size(); ++i ) {
|
||||
material = pt_materials[i];
|
||||
vertex_index = pts_v[i];
|
||||
normal_index = pts_n[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "pt ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << normal_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// generate triangles
|
||||
string_list tri_materials = obj.get_tri_materials();
|
||||
group_list tris_v = obj.get_tris_v();
|
||||
group_list tris_n = obj.get_tris_n();
|
||||
group_list tris_tc = obj.get_tris_tc();
|
||||
for ( i = 0; i < (int)tris_v.size(); ++i ) {
|
||||
material = tri_materials[i];
|
||||
vertex_index = tris_v[i];
|
||||
normal_index = tris_n[i];
|
||||
tex_index = tris_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "f ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
cout << vertex_index[j];
|
||||
if ( normal_index.size() ) {
|
||||
cout << "/" << normal_index[j];
|
||||
}
|
||||
cout << "/" << tex_index[j];
|
||||
cout << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
@@ -84,15 +108,21 @@ int main( int argc, char **argv ) {
|
||||
// generate strips
|
||||
string_list strip_materials = obj.get_strip_materials();
|
||||
group_list strips_v = obj.get_strips_v();
|
||||
group_list strips_n = obj.get_strips_n();
|
||||
group_list strips_tc = obj.get_strips_tc();
|
||||
for ( i = 0; i < (int)strips_v.size(); ++i ) {
|
||||
material = strip_materials[i];
|
||||
vertex_index = strips_v[i];
|
||||
normal_index = strips_n[i];
|
||||
tex_index = strips_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "ts ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
cout << vertex_index[j];
|
||||
if ( normal_index.size() ) {
|
||||
cout << "/" << normal_index[j];
|
||||
}
|
||||
cout << "/" << tex_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
@@ -100,15 +130,21 @@ int main( int argc, char **argv ) {
|
||||
// generate fans
|
||||
string_list fan_materials = obj.get_fan_materials();
|
||||
group_list fans_v = obj.get_fans_v();
|
||||
group_list fans_n = obj.get_fans_n();
|
||||
group_list fans_tc = obj.get_fans_tc();
|
||||
for ( i = 0; i < (int)fans_v.size(); ++i ) {
|
||||
material = fan_materials[i];
|
||||
vertex_index = fans_v[i];
|
||||
normal_index = fans_n[i];
|
||||
tex_index = fans_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "tf ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
cout << vertex_index[j];
|
||||
if ( normal_index.size() ) {
|
||||
cout << "/" << normal_index[j];
|
||||
}
|
||||
cout << "/" << tex_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
|
||||
#include "iochannel.hxx"
|
||||
// #include "garmin.hxx"
|
||||
// #include "nmea.hxx"
|
||||
|
||||
|
||||
// constructor
|
||||
|
||||
@@ -23,6 +23,8 @@ int main() {
|
||||
}
|
||||
cout << "endian" << endl;
|
||||
|
||||
cout << "sizeof(short) = " << sizeof(short) << endl;
|
||||
|
||||
short s = 1111;
|
||||
cout << "short s = " << s << endl;
|
||||
sgEndianSwap((unsigned short *)&s);
|
||||
|
||||
+379
-157
@@ -22,6 +22,10 @@
|
||||
//
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -49,17 +53,29 @@ enum {
|
||||
SG_BOUNDING_SPHERE = 0,
|
||||
|
||||
SG_VERTEX_LIST = 1,
|
||||
SG_COLOR_LIST = 4,
|
||||
SG_NORMAL_LIST = 2,
|
||||
SG_TEXCOORD_LIST = 3,
|
||||
|
||||
SG_POINTS = 9,
|
||||
|
||||
SG_TRIANGLE_FACES = 10,
|
||||
SG_TRIANGLE_STRIPS = 11,
|
||||
SG_TRIANGLE_FANS = 12
|
||||
} tgObjectTypes;
|
||||
} sgObjectTypes;
|
||||
|
||||
enum {
|
||||
SG_MATERIAL = 0
|
||||
} tgPropertyTypes;
|
||||
SG_IDX_VERTICES = 0x01,
|
||||
SG_IDX_NORMALS = 0x02,
|
||||
SG_IDX_COLORS = 0x04,
|
||||
SG_IDX_TEXCOORDS = 0x08
|
||||
} sgIndexTypes;
|
||||
|
||||
enum {
|
||||
SG_MATERIAL = 0,
|
||||
SG_INDEX_TYPES = 1
|
||||
} sgPropertyTypes;
|
||||
|
||||
|
||||
|
||||
class sgSimpleBuffer {
|
||||
@@ -145,11 +161,131 @@ double sgCalcBoundingRadius( Point3D center, point_list& wgs84_nodes ) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// read object properties
|
||||
static void read_object( gzFile fp,
|
||||
int obj_type,
|
||||
int nproperties,
|
||||
int nelements,
|
||||
group_list *vertices,
|
||||
group_list *normals,
|
||||
group_list *colors,
|
||||
group_list *texcoords,
|
||||
string_list *materials )
|
||||
{
|
||||
unsigned int nbytes;
|
||||
unsigned char idx_mask;
|
||||
int idx_size;
|
||||
bool do_vertices, do_normals, do_colors, do_texcoords;
|
||||
int j, k, idx;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
char material[256];
|
||||
|
||||
// default values
|
||||
if ( obj_type == SG_POINTS ) {
|
||||
idx_size = 1;
|
||||
idx_mask = SG_IDX_VERTICES;
|
||||
do_vertices = true;
|
||||
do_normals = false;
|
||||
do_colors = false;
|
||||
do_texcoords = false;
|
||||
} else {
|
||||
idx_size = 2;
|
||||
idx_mask = (char)(SG_IDX_VERTICES | SG_IDX_TEXCOORDS);
|
||||
do_vertices = true;
|
||||
do_normals = false;
|
||||
do_colors = false;
|
||||
do_texcoords = true;
|
||||
}
|
||||
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
char prop_type;
|
||||
sgReadChar( fp, &prop_type );
|
||||
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "property size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
if ( prop_type == SG_MATERIAL ) {
|
||||
strncpy( material, ptr, nbytes );
|
||||
material[nbytes] = '\0';
|
||||
// cout << "material type = " << material << endl;
|
||||
} else if ( prop_type == SG_INDEX_TYPES ) {
|
||||
idx_mask = ptr[0];
|
||||
// cout << "idx_mask = " << (int)idx_mask << endl;
|
||||
idx_size = 0;
|
||||
do_vertices = false;
|
||||
do_normals = false;
|
||||
do_colors = false;
|
||||
do_texcoords = false;
|
||||
if ( idx_mask & SG_IDX_VERTICES ) {
|
||||
do_vertices = true;
|
||||
++idx_size;
|
||||
}
|
||||
if ( idx_mask & SG_IDX_NORMALS ) {
|
||||
do_normals = true;
|
||||
++idx_size;
|
||||
}
|
||||
if ( idx_mask & SG_IDX_COLORS ) {
|
||||
do_colors = true;
|
||||
++idx_size;
|
||||
}
|
||||
if ( idx_mask & SG_IDX_TEXCOORDS ) {
|
||||
do_texcoords = true;
|
||||
++idx_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0; j < nelements; ++j ) {
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "element size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (idx_size * sizeof(short));
|
||||
short *sptr = (short *)ptr;
|
||||
int_list vs; vs.clear();
|
||||
int_list ns; ns.clear();
|
||||
int_list cs; cs.clear();
|
||||
int_list tcs; tcs.clear();
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( idx = 0; idx < idx_size; ++idx ) {
|
||||
sgEndianSwap( (unsigned short *)&(sptr[idx]) );
|
||||
}
|
||||
}
|
||||
idx = 0;
|
||||
if ( do_vertices ) {
|
||||
vs.push_back( sptr[idx++] );
|
||||
}
|
||||
if ( do_normals ) {
|
||||
ns.push_back( sptr[idx++] );
|
||||
}
|
||||
if ( do_colors ) {
|
||||
cs.push_back( sptr[idx++] );
|
||||
}
|
||||
if ( do_texcoords ) {
|
||||
tcs.push_back( sptr[idx++] );
|
||||
}
|
||||
// cout << sptr[0] << " ";
|
||||
sptr += idx_size;
|
||||
}
|
||||
// cout << endl;
|
||||
vertices->push_back( vs );
|
||||
normals->push_back( ns );
|
||||
colors->push_back( cs );
|
||||
texcoords->push_back( tcs );
|
||||
materials->push_back( material );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// read a binary file and populate the provided structures.
|
||||
bool SGBinObject::read_bin( const string& file ) {
|
||||
Point3D p;
|
||||
int i, j, k;
|
||||
char material[256];
|
||||
unsigned int nbytes;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
|
||||
@@ -161,24 +297,36 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
normals.clear();
|
||||
texcoords.clear();
|
||||
|
||||
pts_v.clear();
|
||||
pts_n.clear();
|
||||
pts_c.clear();
|
||||
pts_tc.clear();
|
||||
pt_materials.clear();
|
||||
|
||||
tris_v.clear();
|
||||
tris_n.clear();
|
||||
tris_c.clear();
|
||||
tris_tc.clear();
|
||||
tri_materials.clear();
|
||||
|
||||
strips_v.clear();
|
||||
strips_n.clear();
|
||||
strips_c.clear();
|
||||
strips_tc.clear();
|
||||
strip_materials.clear();
|
||||
|
||||
fans_v.clear();
|
||||
fans_n.clear();
|
||||
fans_c.clear();
|
||||
fans_tc.clear();
|
||||
fan_materials.clear();
|
||||
|
||||
|
||||
gzFile fp;
|
||||
if ( (fp = gzopen( file.c_str(), "rb" )) == NULL ) {
|
||||
string filegz = file + ".gz";
|
||||
if ( (fp = gzopen( filegz.c_str(), "rb" )) == NULL ) {
|
||||
// cout << "ERROR: opening " << file << " or " << filegz
|
||||
// << "for reading!" << endl;
|
||||
cout << "ERROR: opening " << file << " or " << filegz
|
||||
<< "for reading!" << endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -203,10 +351,11 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
}
|
||||
|
||||
// read creation time
|
||||
time_t calendar_time;
|
||||
sgReadLong( fp, &calendar_time );
|
||||
unsigned int foo_calendar_time;
|
||||
sgReadUInt( fp, &foo_calendar_time );
|
||||
|
||||
#if 0
|
||||
time_t calendar_time = foo_calendar_time;
|
||||
// The following code has a global effect on the host application
|
||||
// and can screws up the time elsewhere. It should be avoided
|
||||
// unless you need this for debugging in which case you should
|
||||
@@ -295,18 +444,51 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(float) * 3);
|
||||
float *fptr = (float *)ptr;
|
||||
wgs84_nodes.reserve( count );
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int *)&(fptr[0]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[1]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[2]) );
|
||||
}
|
||||
p = Point3D( fptr[0], fptr[1], fptr[2] );
|
||||
// cout << "node = " << p << endl;
|
||||
wgs84_nodes.push_back( p );
|
||||
wgs84_nodes.push_back( Point3D(fptr[0], fptr[1], fptr[2]) );
|
||||
fptr += 3;
|
||||
}
|
||||
}
|
||||
} else if ( obj_type == SG_COLOR_LIST ) {
|
||||
// read color list properties
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
char prop_type;
|
||||
sgReadChar( fp, &prop_type );
|
||||
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "property size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
}
|
||||
|
||||
// read color list elements
|
||||
for ( j = 0; j < nelements; ++j ) {
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "element size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(float) * 4);
|
||||
float *fptr = (float *)ptr;
|
||||
colors.reserve(count);
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int *)&(fptr[0]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[1]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[2]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[3]) );
|
||||
}
|
||||
colors.push_back( Point3D( fptr[0], fptr[1], fptr[2] ) );
|
||||
fptr += 4;
|
||||
}
|
||||
}
|
||||
} else if ( obj_type == SG_NORMAL_LIST ) {
|
||||
// read normal list properties
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
@@ -328,6 +510,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
unsigned char *ptr = (unsigned char *)(buf.get_ptr());
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / 3;
|
||||
normals.reserve( count );
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
sgdVec3 normal;
|
||||
sgdSetVec3( normal,
|
||||
@@ -336,9 +519,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
(ptr[2]) / 127.5 - 1.0 );
|
||||
sgdNormalizeVec3( normal );
|
||||
|
||||
p = Point3D( normal[0], normal[1], normal[2] );
|
||||
// cout << "normal = " << p << endl;
|
||||
normals.push_back( p );
|
||||
normals.push_back(Point3D(normal[0], normal[1], normal[2]));
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
@@ -364,149 +545,33 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(float) * 2);
|
||||
float *fptr = (float *)ptr;
|
||||
texcoords.reserve(count);
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int *)&(fptr[0]) );
|
||||
sgEndianSwap( (unsigned int *)&(fptr[1]) );
|
||||
}
|
||||
p = Point3D( fptr[0], fptr[1], 0 );
|
||||
// cout << "texcoord = " << p << endl;
|
||||
texcoords.push_back( p );
|
||||
texcoords.push_back( Point3D( fptr[0], fptr[1], 0 ) );
|
||||
fptr += 2;
|
||||
}
|
||||
}
|
||||
} else if ( obj_type == SG_POINTS ) {
|
||||
// read point elements
|
||||
read_object( fp, SG_POINTS, nproperties, nelements,
|
||||
&pts_v, &pts_n, &pts_c, &pts_tc, &pt_materials );
|
||||
} else if ( obj_type == SG_TRIANGLE_FACES ) {
|
||||
// read triangle face properties
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
char prop_type;
|
||||
sgReadChar( fp, &prop_type );
|
||||
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "property size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
if ( prop_type == SG_MATERIAL ) {
|
||||
strncpy( material, ptr, nbytes );
|
||||
material[nbytes] = '\0';
|
||||
// cout << "material type = " << material << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// read triangle face elements
|
||||
for ( j = 0; j < nelements; ++j ) {
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "element size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(short) * 2);
|
||||
short *sptr = (short *)ptr;
|
||||
int_list vs, tcs;
|
||||
vs.clear(); tcs.clear();
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short *)&(sptr[0]) );
|
||||
sgEndianSwap( (unsigned short *)&(sptr[1]) );
|
||||
}
|
||||
vs.push_back( sptr[0] );
|
||||
tcs.push_back( sptr[1] );
|
||||
// cout << sptr[0] << "/" << sptr[1] << " ";
|
||||
sptr += 2;
|
||||
}
|
||||
// cout << endl;
|
||||
tris_v.push_back( vs );
|
||||
tris_tc.push_back( tcs );
|
||||
tri_materials.push_back( material );
|
||||
}
|
||||
read_object( fp, SG_TRIANGLE_FACES, nproperties, nelements,
|
||||
&tris_v, &tris_n, &tris_c, &tris_tc, &tri_materials );
|
||||
} else if ( obj_type == SG_TRIANGLE_STRIPS ) {
|
||||
// read triangle strip properties
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
char prop_type;
|
||||
sgReadChar( fp, &prop_type );
|
||||
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "property size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
if ( prop_type == SG_MATERIAL ) {
|
||||
strncpy( material, ptr, nbytes );
|
||||
material[nbytes] = '\0';
|
||||
// cout << "material type = " << material << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// read triangle strip elements
|
||||
for ( j = 0; j < nelements; ++j ) {
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "element size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(short) * 2);
|
||||
short *sptr = (short *)ptr;
|
||||
int_list vs, tcs;
|
||||
vs.clear(); tcs.clear();
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short *)&(sptr[0]) );
|
||||
sgEndianSwap( (unsigned short *)&(sptr[1]) );
|
||||
}
|
||||
vs.push_back( sptr[0] );
|
||||
tcs.push_back( sptr[1] );
|
||||
// cout << sptr[0] << "/" << sptr[1] << " ";
|
||||
sptr += 2;
|
||||
}
|
||||
// cout << endl;
|
||||
strips_v.push_back( vs );
|
||||
strips_tc.push_back( tcs );
|
||||
strip_materials.push_back( material );
|
||||
}
|
||||
read_object( fp, SG_TRIANGLE_STRIPS, nproperties, nelements,
|
||||
&strips_v, &strips_n, &strips_c, &strips_tc,
|
||||
&strip_materials );
|
||||
} else if ( obj_type == SG_TRIANGLE_FANS ) {
|
||||
// read triangle fan properties
|
||||
for ( j = 0; j < nproperties; ++j ) {
|
||||
char prop_type;
|
||||
sgReadChar( fp, &prop_type );
|
||||
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "property size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
if ( prop_type == SG_MATERIAL ) {
|
||||
strncpy( material, ptr, nbytes );
|
||||
material[nbytes] = '\0';
|
||||
// cout << "material type = " << material << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// read triangle fan elements
|
||||
for ( j = 0; j < nelements; ++j ) {
|
||||
sgReadUInt( fp, &nbytes );
|
||||
// cout << "element size = " << nbytes << endl;
|
||||
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
|
||||
char *ptr = buf.get_ptr();
|
||||
sgReadBytes( fp, nbytes, ptr );
|
||||
int count = nbytes / (sizeof(short) * 2);
|
||||
short *sptr = (short *)ptr;
|
||||
int_list vs, tcs;
|
||||
vs.clear(); tcs.clear();
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short *)&(sptr[0]) );
|
||||
sgEndianSwap( (unsigned short *)&(sptr[1]) );
|
||||
}
|
||||
vs.push_back( sptr[0] );
|
||||
tcs.push_back( sptr[1] );
|
||||
// cout << sptr[0] << "/" << sptr[1] << " ";
|
||||
sptr += 2;
|
||||
}
|
||||
// cout << endl;
|
||||
fans_v.push_back( vs );
|
||||
fans_tc.push_back( tcs );
|
||||
fan_materials.push_back( material );
|
||||
}
|
||||
read_object( fp, SG_TRIANGLE_FANS, nproperties, nelements,
|
||||
&fans_v, &fans_n, &fans_c, &fans_tc, &fan_materials );
|
||||
} else {
|
||||
// unknown object type, just skip
|
||||
|
||||
@@ -554,7 +619,10 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
Point3D p;
|
||||
sgVec2 t;
|
||||
sgVec3 pt;
|
||||
sgVec4 color;
|
||||
int i, j;
|
||||
unsigned char idx_mask;
|
||||
int idx_size;
|
||||
|
||||
string dir = base + "/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
@@ -575,6 +643,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
sgClearWriteError();
|
||||
|
||||
cout << "points size = " << pts_v.size() << " pt_materials = "
|
||||
<< pt_materials.size() << endl;
|
||||
cout << "triangles size = " << tris_v.size() << " tri_materials = "
|
||||
<< tri_materials.size() << endl;
|
||||
cout << "strips size = " << strips_v.size() << " strip_materials = "
|
||||
@@ -582,7 +652,9 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
cout << "fans size = " << fans_v.size() << " fan_materials = "
|
||||
<< fan_materials.size() << endl;
|
||||
|
||||
cout << "points = " << wgs84_nodes.size() << endl;
|
||||
cout << "nodes = " << wgs84_nodes.size() << endl;
|
||||
cout << "colors = " << colors.size() << endl;
|
||||
cout << "normals = " << normals.size() << endl;
|
||||
cout << "tex coords = " << texcoords.size() << endl;
|
||||
|
||||
// write header magic
|
||||
@@ -597,9 +669,24 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
short nobjects = 0;
|
||||
nobjects++; // for gbs
|
||||
nobjects++; // for vertices
|
||||
nobjects++; // for colors
|
||||
nobjects++; // for normals
|
||||
nobjects++; // for texcoords
|
||||
|
||||
// points
|
||||
short npts = 0;
|
||||
start = 0; end = 1;
|
||||
while ( start < (int)pt_materials.size() ) {
|
||||
material = pt_materials[start];
|
||||
while ( (end < (int)pt_materials.size()) &&
|
||||
(material == pt_materials[end]) ) {
|
||||
end++;
|
||||
}
|
||||
npts++;
|
||||
start = end; end = start + 1;
|
||||
}
|
||||
nobjects += npts;
|
||||
|
||||
// tris
|
||||
short ntris = 0;
|
||||
start = 0; end = 1;
|
||||
@@ -667,6 +754,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteVec3( fp, pt );
|
||||
}
|
||||
|
||||
// dump vertex color list
|
||||
sgWriteChar( fp, (char)SG_COLOR_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
|
||||
for ( i = 0; i < (int)colors.size(); ++i ) {
|
||||
p = colors[i];
|
||||
// Right now we have a place holder for color alpha but we
|
||||
// need to update the interface so the calling program can
|
||||
// provide the info.
|
||||
sgSetVec4( color, p.x(), p.y(), p.z(), 1.0 );
|
||||
sgWriteVec4( fp, color );
|
||||
}
|
||||
|
||||
// dump vertex normal list
|
||||
sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
@@ -692,6 +793,66 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteVec2( fp, t );
|
||||
}
|
||||
|
||||
// dump point groups if they exist
|
||||
if ( pts_v.size() > 0 ) {
|
||||
int start = 0;
|
||||
int end = 1;
|
||||
string material;
|
||||
while ( start < (int)pt_materials.size() ) {
|
||||
// find next group
|
||||
material = pt_materials[start];
|
||||
while ( (end < (int)pt_materials.size()) &&
|
||||
(material == pt_materials[end]) )
|
||||
{
|
||||
// cout << "end = " << end << endl;
|
||||
end++;
|
||||
}
|
||||
// cout << "group = " << start << " to " << end - 1 << endl;
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_POINTS ); // type
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
sgWriteBytes( fp, material.length(), material.c_str() );
|
||||
|
||||
idx_mask = 0;
|
||||
idx_size = 0;
|
||||
if ( pts_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
|
||||
if ( pts_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
|
||||
if ( pts_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
|
||||
if ( pts_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
|
||||
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
|
||||
sgWriteUInt( fp, 1 ); // nbytes
|
||||
sgWriteChar( fp, idx_mask );
|
||||
|
||||
// write strips
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, pts_v[i].size() * idx_size * sizeof(short) );
|
||||
for ( j = 0; j < (int)pts_v[i].size(); ++j ) {
|
||||
if ( pts_v.size() ) {
|
||||
sgWriteShort( fp, (short)pts_v[i][j] );
|
||||
}
|
||||
if ( pts_n.size() ) {
|
||||
sgWriteShort( fp, (short)pts_n[i][j] );
|
||||
}
|
||||
if ( pts_c.size() ) {
|
||||
sgWriteShort( fp, (short)pts_c[i][j] );
|
||||
}
|
||||
if ( pts_tc.size() ) {
|
||||
sgWriteShort( fp, (short)pts_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start = end;
|
||||
end = start + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// dump individual triangles if they exist
|
||||
if ( tris_v.size() > 0 ) {
|
||||
int start = 0;
|
||||
@@ -710,20 +871,41 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type
|
||||
sgWriteShort( fp, 1 ); // nproperties
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
sgWriteBytes( fp, material.length(), material.c_str() );
|
||||
|
||||
sgWriteUInt( fp, (end - start) * 3 * 2 * sizeof(short) ); // nbytes
|
||||
idx_mask = 0;
|
||||
idx_size = 0;
|
||||
if ( tris_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
|
||||
if ( tris_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
|
||||
if ( tris_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
|
||||
if ( tris_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
|
||||
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
|
||||
sgWriteUInt( fp, 1 ); // nbytes
|
||||
sgWriteChar( fp, idx_mask );
|
||||
|
||||
// nbytes
|
||||
sgWriteUInt( fp, (end - start) * 3 * idx_size * sizeof(short) );
|
||||
|
||||
// write group
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < 3; ++j ) {
|
||||
sgWriteShort( fp, (short)tris_v[i][j] );
|
||||
sgWriteShort( fp, (short)tris_tc[i][j] );
|
||||
if ( tris_v.size() ) {
|
||||
sgWriteShort( fp, (short)tris_v[i][j] );
|
||||
}
|
||||
if ( tris_n.size() ) {
|
||||
sgWriteShort( fp, (short)tris_n[i][j] );
|
||||
}
|
||||
if ( tris_c.size() ) {
|
||||
sgWriteShort( fp, (short)tris_c[i][j] );
|
||||
}
|
||||
if ( tris_tc.size() ) {
|
||||
sgWriteShort( fp, (short)tris_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,20 +932,40 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type
|
||||
sgWriteShort( fp, 1 ); // nproperties
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
sgWriteBytes( fp, material.length(), material.c_str() );
|
||||
|
||||
idx_mask = 0;
|
||||
idx_size = 0;
|
||||
if ( strips_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
|
||||
if ( strips_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
|
||||
if ( strips_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
|
||||
if ( strips_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size;}
|
||||
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
|
||||
sgWriteUInt( fp, 1 ); // nbytes
|
||||
sgWriteChar( fp, idx_mask );
|
||||
|
||||
// write strips
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, strips_v[i].size() * 2 * sizeof(short) );
|
||||
sgWriteUInt( fp, strips_v[i].size() * idx_size * sizeof(short));
|
||||
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
sgWriteShort( fp, (short)strips_v[i][j] );
|
||||
sgWriteShort( fp, (short)strips_tc[i][j] );
|
||||
if ( strips_v.size() ) {
|
||||
sgWriteShort( fp, (short)strips_v[i][j] );
|
||||
}
|
||||
if ( strips_n.size() ) {
|
||||
sgWriteShort( fp, (short)strips_n[i][j] );
|
||||
}
|
||||
if ( strips_c.size() ) {
|
||||
sgWriteShort( fp, (short)strips_c[i][j] );
|
||||
}
|
||||
if ( strips_tc.size() ) {
|
||||
sgWriteShort( fp, (short)strips_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,20 +992,40 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type
|
||||
sgWriteShort( fp, 1 ); // nproperties
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
sgWriteBytes( fp, material.length(), material.c_str() );
|
||||
|
||||
idx_mask = 0;
|
||||
idx_size = 0;
|
||||
if ( fans_v.size() ) { idx_mask |= SG_IDX_VERTICES; ++idx_size; }
|
||||
if ( fans_n.size() ) { idx_mask |= SG_IDX_NORMALS; ++idx_size; }
|
||||
if ( fans_c.size() ) { idx_mask |= SG_IDX_COLORS; ++idx_size; }
|
||||
if ( fans_tc.size() ) { idx_mask |= SG_IDX_TEXCOORDS; ++idx_size; }
|
||||
sgWriteChar( fp, (char)SG_INDEX_TYPES ); // property
|
||||
sgWriteUInt( fp, 1 ); // nbytes
|
||||
sgWriteChar( fp, idx_mask );
|
||||
|
||||
// write fans
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, fans_v[i].size() * 2 * sizeof(short) );
|
||||
sgWriteUInt( fp, fans_v[i].size() * idx_size * sizeof(short) );
|
||||
for ( j = 0; j < (int)fans_v[i].size(); ++j ) {
|
||||
sgWriteShort( fp, (short)fans_v[i][j] );
|
||||
sgWriteShort( fp, (short)fans_tc[i][j] );
|
||||
if ( fans_v.size() ) {
|
||||
sgWriteShort( fp, (short)fans_v[i][j] );
|
||||
}
|
||||
if ( fans_n.size() ) {
|
||||
sgWriteShort( fp, (short)fans_n[i][j] );
|
||||
}
|
||||
if ( fans_c.size() ) {
|
||||
sgWriteShort( fp, (short)fans_c[i][j] );
|
||||
}
|
||||
if ( fans_tc.size() ) {
|
||||
sgWriteShort( fp, (short)fans_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+84
-39
@@ -70,7 +70,7 @@ typedef group_list::const_iterator const_group_list_iterator;
|
||||
* - property: prop_typecode, nbytes, BYTE+
|
||||
*
|
||||
* - obj_typecode: bounding sphere | vertices | normals | texcoords |
|
||||
* triangles | fans | strips
|
||||
* points | triangles | fans | strips
|
||||
*
|
||||
* - prop_typecode: material_name | ???
|
||||
*
|
||||
@@ -91,58 +91,103 @@ class SGBinObject {
|
||||
|
||||
Point3D gbs_center;
|
||||
float gbs_radius;
|
||||
point_list wgs84_nodes;
|
||||
point_list normals;
|
||||
point_list texcoords;
|
||||
group_list tris_v;
|
||||
group_list tris_tc;
|
||||
string_list tri_materials;
|
||||
group_list strips_v;
|
||||
group_list strips_tc;
|
||||
string_list strip_materials;
|
||||
group_list fans_v;
|
||||
group_list fans_tc;
|
||||
string_list fan_materials;
|
||||
|
||||
point_list wgs84_nodes; // vertex list
|
||||
point_list colors; // color list
|
||||
point_list normals; // normal list
|
||||
point_list texcoords; // texture coordinate list
|
||||
|
||||
group_list pts_v; // points vertex index
|
||||
group_list pts_n; // points normal index
|
||||
group_list pts_c; // points color index
|
||||
group_list pts_tc; // points texture coordinate index
|
||||
string_list pt_materials; // points materials
|
||||
|
||||
group_list tris_v; // triangles vertex index
|
||||
group_list tris_n; // triangles normal index
|
||||
group_list tris_c; // triangles color index
|
||||
group_list tris_tc; // triangles texture coordinate index
|
||||
string_list tri_materials; // triangles materials
|
||||
|
||||
group_list strips_v; // tristrips vertex index
|
||||
group_list strips_n; // tristrips normal index
|
||||
group_list strips_c; // tristrips color index
|
||||
group_list strips_tc; // tristrips texture coordinate index
|
||||
string_list strip_materials;// tristrips materials
|
||||
|
||||
group_list fans_v; // fans vertex index
|
||||
group_list fans_n; // fans normal index
|
||||
group_list fans_c; // fans color index
|
||||
group_list fans_tc; // fans texture coordinate index
|
||||
string_list fan_materials; // fans materials
|
||||
|
||||
public:
|
||||
|
||||
inline unsigned short get_version() const { return version; }
|
||||
|
||||
inline Point3D get_gbs_center() const { return gbs_center; }
|
||||
inline void set_gbs_center( Point3D p ) { gbs_center = p; }
|
||||
inline const Point3D& get_gbs_center() const { return gbs_center; }
|
||||
inline void set_gbs_center( const Point3D& p ) { gbs_center = p; }
|
||||
|
||||
inline float get_gbs_radius() const { return gbs_radius; }
|
||||
inline void set_gbs_radius( float r ) { gbs_radius = r; }
|
||||
|
||||
inline point_list get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
||||
inline const point_list& get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( const point_list& n ) { wgs84_nodes = n; }
|
||||
|
||||
inline point_list get_normals() const { return normals; }
|
||||
inline void set_normals( point_list n ) { normals = n; }
|
||||
inline const point_list& get_colors() const { return colors; }
|
||||
inline void set_colors( const point_list& c ) { colors = c; }
|
||||
|
||||
inline point_list get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( point_list t ) { texcoords = t; }
|
||||
inline const point_list& get_normals() const { return normals; }
|
||||
inline void set_normals( const point_list& n ) { normals = n; }
|
||||
|
||||
inline group_list get_tris_v() const { return tris_v; }
|
||||
inline void set_tris_v( group_list g ) { tris_v = g; }
|
||||
inline group_list get_tris_tc() const { return tris_tc; }
|
||||
inline void set_tris_tc( group_list g ) { tris_tc = g; }
|
||||
inline string_list get_tri_materials() const { return tri_materials; }
|
||||
inline void set_tri_materials( string_list s ) { tri_materials = s; }
|
||||
inline const point_list& get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( const point_list& t ) { texcoords = t; }
|
||||
|
||||
inline const group_list& get_pts_v() const { return pts_v; }
|
||||
inline void set_pts_v( const group_list& g ) { pts_v = g; }
|
||||
inline const group_list& get_pts_n() const { return pts_n; }
|
||||
inline void set_pts_n( const group_list& g ) { pts_n = g; }
|
||||
inline const group_list& get_pts_c() const { return pts_c; }
|
||||
inline void set_pts_c( const group_list& g ) { pts_c = g; }
|
||||
inline const group_list& get_pts_tc() const { return pts_tc; }
|
||||
inline void set_pts_tc( const group_list& g ) { pts_tc = g; }
|
||||
inline const string_list& get_pt_materials() const { return pt_materials; }
|
||||
inline void set_pt_materials( const string_list& s ) { pt_materials = s; }
|
||||
|
||||
inline const group_list& get_tris_v() const { return tris_v; }
|
||||
inline void set_tris_v( const group_list& g ) { tris_v = g; }
|
||||
inline const group_list& get_tris_n() const { return tris_n; }
|
||||
inline void set_tris_n( const group_list& g ) { tris_n = g; }
|
||||
inline const group_list& get_tris_c() const { return tris_c; }
|
||||
inline void set_tris_c( const group_list& g ) { tris_c = g; }
|
||||
inline const group_list& get_tris_tc() const { return tris_tc; }
|
||||
inline void set_tris_tc( const group_list& g ) { tris_tc = g; }
|
||||
inline const string_list& get_tri_materials() const { return tri_materials; }
|
||||
inline void set_tri_materials( const string_list& s ) { tri_materials = s; }
|
||||
|
||||
inline group_list get_strips_v() const { return strips_v; }
|
||||
inline void set_strips_v( group_list g ) { strips_v = g; }
|
||||
inline group_list get_strips_tc() const { return strips_tc; }
|
||||
inline void set_strips_tc( group_list g ) { strips_tc = g; }
|
||||
inline string_list get_strip_materials() const { return strip_materials; }
|
||||
inline void set_strip_materials( string_list s ) { strip_materials = s; }
|
||||
inline const group_list& get_strips_v() const { return strips_v; }
|
||||
inline void set_strips_v( const group_list& g ) { strips_v = g; }
|
||||
inline const group_list& get_strips_n() const { return strips_n; }
|
||||
inline void set_strips_n( const group_list& g ) { strips_n = g; }
|
||||
inline const group_list& get_strips_c() const { return strips_c; }
|
||||
inline void set_strips_c( const group_list& g ) { strips_c = g; }
|
||||
|
||||
inline const group_list& get_strips_tc() const { return strips_tc; }
|
||||
inline void set_strips_tc( const group_list& g ) { strips_tc = g; }
|
||||
inline const string_list& get_strip_materials() const { return strip_materials; }
|
||||
inline void set_strip_materials( const string_list& s ) { strip_materials = s; }
|
||||
|
||||
inline group_list get_fans_v() const { return fans_v; }
|
||||
inline void set_fans_v( group_list g ) { fans_v = g; }
|
||||
inline group_list get_fans_tc() const { return fans_tc; }
|
||||
inline void set_fans_tc( group_list g ) { fans_tc = g; }
|
||||
inline string_list get_fan_materials() const { return fan_materials; }
|
||||
inline void set_fan_materials( string_list s ) { fan_materials = s; }
|
||||
inline const group_list& get_fans_v() const { return fans_v; }
|
||||
inline void set_fans_v( const group_list& g ) { fans_v = g; }
|
||||
inline const group_list& get_fans_n() const { return fans_n; }
|
||||
inline void set_fans_n( const group_list& g ) { fans_n = g; }
|
||||
inline const group_list& get_fans_c() const { return fans_c; }
|
||||
inline void set_fans_c( const group_list& g ) { fans_c = g; }
|
||||
|
||||
inline const group_list& get_fans_tc() const { return fans_tc; }
|
||||
inline void set_fans_tc( const group_list& g ) { fans_tc = g; }
|
||||
inline const string_list& get_fan_materials() const { return fan_materials; }
|
||||
inline void set_fan_materials( const string_list& s ) { fan_materials = s; }
|
||||
|
||||
/**
|
||||
* Read a binary file object and populate the provided structures.
|
||||
|
||||
+188
-344
@@ -1,6 +1,7 @@
|
||||
// sg_socket.cxx -- Socket I/O routines
|
||||
//
|
||||
// Written by Curtis Olson, started November 1999.
|
||||
// Modified by Bernie Bright <bbright@bigpond.net.au>, May 2002.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
@@ -23,16 +24,6 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||
# include <sys/time.h> // select()
|
||||
# include <sys/types.h> // socket(), bind(), select(), accept()
|
||||
# include <sys/socket.h> // socket(), bind(), listen(), accept()
|
||||
# include <netinet/in.h> // struct sockaddr_in
|
||||
# include <netdb.h> // gethostbyname()
|
||||
# include <unistd.h> // select(), fsync()/fdatasync(), fcntl()
|
||||
# include <fcntl.h> // fcntl()
|
||||
#endif
|
||||
|
||||
#if defined( sgi )
|
||||
#include <strings.h>
|
||||
#endif
|
||||
@@ -41,25 +32,30 @@
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
bool SGSocket::init = false;
|
||||
|
||||
SGSocket::SGSocket( const string& host, const string& port,
|
||||
SGSocket::SGSocket( const string& host, const string& port_,
|
||||
const string& style ) :
|
||||
hostname(host),
|
||||
port_str(port),
|
||||
save_len(0)
|
||||
port_str(port_),
|
||||
save_len(0),
|
||||
client(0),
|
||||
is_tcp(false),
|
||||
is_server(false),
|
||||
first_read(false)
|
||||
{
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
if (!wsock_init && !wsastartup()) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Winsock not available");
|
||||
if (!init)
|
||||
{
|
||||
netInit(NULL, NULL); // plib-1.4.2 compatible
|
||||
init = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( style == "udp" ) {
|
||||
sock_style = SOCK_DGRAM;
|
||||
} else if ( style == "tcp" ) {
|
||||
sock_style = SOCK_STREAM;
|
||||
} else {
|
||||
sock_style = SOCK_DGRAM;
|
||||
if ( style == "tcp" )
|
||||
{
|
||||
is_tcp = true;
|
||||
}
|
||||
else if ( style != (string)"udp" )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: SGSocket() unknown style = " << style );
|
||||
}
|
||||
@@ -68,126 +64,65 @@ SGSocket::SGSocket( const string& host, const string& port,
|
||||
}
|
||||
|
||||
|
||||
SGSocket::~SGSocket() {
|
||||
SGSocket::~SGSocket()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
||||
SGSocket::SocketType SGSocket::make_server_socket () {
|
||||
struct sockaddr_in name;
|
||||
|
||||
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) || defined( sgi ) || defined( _MSC_VER ) || defined(__MINGW32__) || defined( __APPLE__ )
|
||||
int length;
|
||||
#else
|
||||
socklen_t length;
|
||||
#endif
|
||||
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
bool
|
||||
SGSocket::make_server_socket()
|
||||
{
|
||||
if (!sock.open( is_tcp ))
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// Give the socket a name.
|
||||
name.sin_family = AF_INET;
|
||||
name.sin_addr.s_addr = INADDR_ANY;
|
||||
name.sin_port = htons(port); // set port to zero to let system pick
|
||||
name.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) != 0) {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bind() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the assigned port number
|
||||
length = sizeof(struct sockaddr_in);
|
||||
if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
|
||||
if (sock.bind( "", port ) < 0)
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: getsockname() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
"Error: bind() failed in make_server_socket()" );
|
||||
sock.close();
|
||||
return false;
|
||||
}
|
||||
port = ntohs(name.sin_port);
|
||||
|
||||
return sock;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SGSocket::SocketType SGSocket::make_client_socket () {
|
||||
struct sockaddr_in name;
|
||||
struct hostent *hp;
|
||||
|
||||
SG_LOG( SG_IO, SG_INFO, "Make client socket()" );
|
||||
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
bool
|
||||
SGSocket::make_client_socket()
|
||||
{
|
||||
if (!sock.open( is_tcp ))
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
"Error: socket() failed in make_client_socket()" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// specify address family
|
||||
name.sin_family = AF_INET;
|
||||
|
||||
// get the hosts official name/info
|
||||
hp = gethostbyname( hostname.c_str() );
|
||||
if (hp == NULL) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error: hostname lookup failed" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// Connect this socket to the host and the port specified on the
|
||||
// command line
|
||||
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
|
||||
bcopy(hp->h_addr, (char *)(&(name.sin_addr.s_addr)), hp->h_length);
|
||||
#else
|
||||
bcopy(hp->h_addr, &(name.sin_addr.s_addr), hp->h_length);
|
||||
#endif
|
||||
name.sin_port = htons(port);
|
||||
|
||||
if ( connect(sock, (struct sockaddr *) &name,
|
||||
sizeof(struct sockaddr_in)) != 0 )
|
||||
if (sock.connect( hostname.c_str(), port ) < 0)
|
||||
{
|
||||
closesocket(sock);
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: connect() failed in make_client_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
sock.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return sock;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Wrapper functions
|
||||
size_t SGSocket::readsocket( int fd, void *buf, size_t count ) {
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
return ::recv( fd, (char *)buf, count, 0 );
|
||||
#else
|
||||
return ::read( fd, buf, count );
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t SGSocket::writesocket( int fd, const void *buf, size_t count ) {
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
return ::send( fd, (const char*)buf, count, 0 );
|
||||
#else
|
||||
return ::write( fd, buf, count );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||
int SGSocket::closesocket( int fd ) {
|
||||
return ::close( fd );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// If specified as a server (in direction for now) open the master
|
||||
// listening socket. If specified as a client (out direction), open a
|
||||
// connection to a server.
|
||||
bool SGSocket::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
bool
|
||||
SGSocket::open( SGProtocolDir direction )
|
||||
{
|
||||
set_dir( direction );
|
||||
|
||||
is_server = is_tcp &&
|
||||
(direction == SG_IO_IN || direction == SG_IO_BI);
|
||||
|
||||
if ( port_str == "" || port_str == "any" ) {
|
||||
port = 0;
|
||||
@@ -195,69 +130,71 @@ bool SGSocket::open( const SGProtocolDir d ) {
|
||||
port = atoi( port_str.c_str() );
|
||||
}
|
||||
|
||||
// client_connections.clear();
|
||||
|
||||
if ( get_dir() == SG_IO_IN ) {
|
||||
if (direction == SG_IO_IN)
|
||||
{
|
||||
// this means server for now
|
||||
|
||||
// Setup socket to listen on. Set "port" before making this
|
||||
// call. A port of "0" indicates that we want to let the os
|
||||
// pick any available port.
|
||||
sock = make_server_socket();
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "socket creation failed" );
|
||||
if (!make_server_socket())
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT, "SG_IO_IN socket creation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
if ( sock_style == SOCK_DGRAM ) {
|
||||
if ( !is_tcp )
|
||||
{
|
||||
// Non-blocking UDP
|
||||
nonblock();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blocking TCP
|
||||
// Specify the maximum length of the connection queue
|
||||
listen( sock, SG_MAX_SOCKET_QUEUE );
|
||||
sock.listen( SG_MAX_SOCKET_QUEUE );
|
||||
}
|
||||
|
||||
} else if ( get_dir() == SG_IO_OUT ) {
|
||||
}
|
||||
else if (direction == SG_IO_OUT)
|
||||
{
|
||||
// this means client for now
|
||||
|
||||
sock = make_client_socket();
|
||||
// TODO: check for error.
|
||||
if (!make_client_socket())
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT, "SG_IO_OUT socket creation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( sock_style == SOCK_DGRAM ) {
|
||||
if ( !is_tcp )
|
||||
{
|
||||
// Non-blocking UDP
|
||||
nonblock();
|
||||
}
|
||||
} else if ( get_dir() == SG_IO_BI && sock_style == SOCK_STREAM ) {
|
||||
}
|
||||
else if (direction == SG_IO_BI && is_tcp)
|
||||
{
|
||||
// this means server for TCP sockets
|
||||
|
||||
// Setup socket to listen on. Set "port" before making this
|
||||
// call. A port of "0" indicates that we want to let the os
|
||||
// pick any available port.
|
||||
sock = make_server_socket();
|
||||
// TODO: check for error.
|
||||
|
||||
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
if (!make_server_socket())
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT, "SG_IO_BI socket creation failed" );
|
||||
return false;
|
||||
}
|
||||
// Blocking TCP
|
||||
// Specify the maximum length of the connection queue
|
||||
listen( sock, SG_MAX_SOCKET_QUEUE );
|
||||
} else {
|
||||
sock.listen( SG_MAX_SOCKET_QUEUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bidirection mode not available for UDP sockets." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( sock < 0 ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening socket: " << hostname
|
||||
<< ":" << port );
|
||||
return false;
|
||||
}
|
||||
|
||||
// extra SOCK_STREAM stuff
|
||||
msgsock = INVALID_SOCKET;
|
||||
first_read = false;
|
||||
|
||||
return true;
|
||||
@@ -266,40 +203,25 @@ bool SGSocket::open( const SGProtocolDir d ) {
|
||||
|
||||
// read data from socket (server)
|
||||
// read a block of data of specified size
|
||||
int SGSocket::read( char *buf, int length ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
int
|
||||
SGSocket::read( char *buf, int length )
|
||||
{
|
||||
if (sock.getHandle() == -1 &&
|
||||
(client == 0 || client->getHandle() == -1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
// check for potential input
|
||||
fd_set ready;
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(sock, &ready);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// test for any input available on sock (returning immediately, even if
|
||||
// nothing)
|
||||
select(32, &ready, 0, 0, &tv);
|
||||
int result = poll();
|
||||
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
// cout << "data ready" << endl;
|
||||
if (result > 0)
|
||||
{
|
||||
result = sock.recv( buf, length );
|
||||
|
||||
if ( sock_style == SOCK_STREAM ) {
|
||||
if ( msgsock == INVALID_SOCKET ) {
|
||||
msgsock = accept(sock, 0, 0);
|
||||
closesocket(sock);
|
||||
sock = msgsock;
|
||||
} else {
|
||||
result = readsocket( sock, buf, length );
|
||||
}
|
||||
} else {
|
||||
result = readsocket( sock, buf, length );
|
||||
}
|
||||
|
||||
if ( result != length ) {
|
||||
if ( result != length )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_INFO,
|
||||
"Warning: read() not enough bytes." );
|
||||
}
|
||||
@@ -310,92 +232,74 @@ int SGSocket::read( char *buf, int length ) {
|
||||
|
||||
|
||||
// read a line of data, length is max size of input buffer
|
||||
int SGSocket::readline( char *buf, int length ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
int
|
||||
SGSocket::readline( char *buf, int length )
|
||||
{
|
||||
if (sock.getHandle() == -1 &&
|
||||
(client == 0 || client->getHandle() == -1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// cout << "sock = " << sock << endl;
|
||||
|
||||
// check for potential input
|
||||
fd_set ready;
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(sock, &ready);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// test for any input read on sock (returning immediately, even if
|
||||
// nothing)
|
||||
int result = select(32, &ready, 0, 0, &tv);
|
||||
// cout << "result = " << result << endl;
|
||||
int result = this->poll();
|
||||
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
// cout << "fd change state\n";
|
||||
if (result > 0)
|
||||
{
|
||||
// read a chunk, keep in the save buffer until we have the
|
||||
// requested amount read
|
||||
|
||||
if ( sock_style == SOCK_STREAM ) {
|
||||
// cout << "sock_stream\n";
|
||||
if ( msgsock == INVALID_SOCKET ) {
|
||||
// cout << "msgsock == invalid\n";
|
||||
msgsock = sock;
|
||||
sock = accept(msgsock, 0, 0);
|
||||
} else {
|
||||
// cout << "ready to read\n";
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE
|
||||
- save_len );
|
||||
// cout << "read result = " << result << endl;
|
||||
|
||||
if ( result > 0 ) {
|
||||
first_read = true;
|
||||
}
|
||||
|
||||
save_len += result;
|
||||
|
||||
// Try and detect that the remote end died. This
|
||||
// could cause problems so if you see connections
|
||||
// dropping for unexplained reasons, LOOK HERE!
|
||||
if ( result == 0 && save_len == 0 && first_read == true ) {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Connection closed by foreign host." );
|
||||
close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_tcp)
|
||||
{
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
result = readsocket( sock, buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
result = client->recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
|
||||
if ( result > 0 )
|
||||
{
|
||||
first_read = true;
|
||||
}
|
||||
|
||||
save_len += result;
|
||||
|
||||
// Try and detect that the remote end died. This
|
||||
// could cause problems so if you see connections
|
||||
// dropping for unexplained reasons, LOOK HERE!
|
||||
if (result == 0 && save_len == 0 && first_read == true)
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Connection closed by foreign host." );
|
||||
delete client;
|
||||
client = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *buf_ptr = save_buf + save_len;
|
||||
result = sock.recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
|
||||
save_len += result;
|
||||
}
|
||||
|
||||
// cout << "current read = " << buf_ptr << endl;
|
||||
// cout << "current save_buf = " << save_buf << endl;
|
||||
// cout << "save_len = " << save_len << endl;
|
||||
} else {
|
||||
// cout << "no data ready\n";
|
||||
}
|
||||
|
||||
// look for the end of line in save_buf
|
||||
int i;
|
||||
for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
|
||||
for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i )
|
||||
;
|
||||
if ( save_buf[i] == '\n' ) {
|
||||
result = i + 1;
|
||||
} else {
|
||||
// no end of line yet
|
||||
// cout << "no eol found" << endl;
|
||||
return 0;
|
||||
}
|
||||
// cout << "line length = " << result << endl;
|
||||
|
||||
// we found an end of line
|
||||
|
||||
// copy to external buffer
|
||||
strncpy( buf, save_buf, result );
|
||||
buf[result] = '\0';
|
||||
// cout << "sg_socket line = " << buf << endl;
|
||||
|
||||
|
||||
// shift save buffer
|
||||
//memmove( save_buf+, save_buf+, ? );
|
||||
for ( i = result; i < save_len; ++i ) {
|
||||
save_buf[ i - result ] = save_buf[i];
|
||||
}
|
||||
@@ -406,66 +310,23 @@ int SGSocket::readline( char *buf, int length ) {
|
||||
|
||||
|
||||
// write data to socket (client)
|
||||
int SGSocket::write( const char *buf, const int length ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
int
|
||||
SGSocket::write( const char *buf, const int length )
|
||||
{
|
||||
netSocket* s = client == 0 ? &sock : client;
|
||||
if (s->getHandle() == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool error_condition = false;
|
||||
|
||||
if ( writesocket(sock, buf, length) < 0 ) {
|
||||
if ( s->send( buf, length ) < 0 )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// check for any new client connection requests
|
||||
fd_set ready;
|
||||
FD_ZERO(&ready);
|
||||
FD_SET(sock, &ready);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// test for any input on sock (returning immediately, even if
|
||||
// nothing)
|
||||
select(32, &ready, 0, 0, &tv);
|
||||
|
||||
// any new connections?
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
int msgsock = accept(sock, 0, 0);
|
||||
if ( msgsock < 0 ) {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: accept() failed in write()" );
|
||||
return 0;
|
||||
} else {
|
||||
client_connections.push_back( msgsock );
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG( SG_IO, SG_INFO, "Client connections = " <<
|
||||
client_connections.size() );
|
||||
for ( int i = 0; i < (int)client_connections.size(); ++i ) {
|
||||
int msgsock = client_connections[i];
|
||||
|
||||
// read and junk any possible incoming messages.
|
||||
// char junk[ SG_IO_MAX_MSG_SIZE ];
|
||||
// std::read( msgsock, junk, SG_IO_MAX_MSG_SIZE );
|
||||
|
||||
// write the interesting data to the socket
|
||||
if ( writesocket(msgsock, buf, length) == SOCKET_ERROR ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
} else {
|
||||
#ifdef _POSIX_SYNCHRONIZED_IO
|
||||
// fdatasync(msgsock);
|
||||
#else
|
||||
// fsync(msgsock);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( error_condition ) {
|
||||
return 0;
|
||||
}
|
||||
@@ -475,79 +336,62 @@ int SGSocket::write( const char *buf, const int length ) {
|
||||
|
||||
|
||||
// write null terminated string to socket (server)
|
||||
int SGSocket::writestring( const char *str ) {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SGSocket::writestring( const char *str )
|
||||
{
|
||||
int length = strlen( str );
|
||||
return write( str, length );
|
||||
return this->write( str, length );
|
||||
}
|
||||
|
||||
|
||||
// close the port
|
||||
bool SGSocket::close() {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
return 0;
|
||||
}
|
||||
bool
|
||||
SGSocket::close()
|
||||
{
|
||||
delete client;
|
||||
client = 0;
|
||||
|
||||
closesocket( sock );
|
||||
if ( sock_style == SOCK_STREAM && msgsock != INVALID_SOCKET ) {
|
||||
sock = msgsock;
|
||||
msgsock = INVALID_SOCKET;
|
||||
}
|
||||
sock.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// configure the socket as non-blocking
|
||||
bool SGSocket::nonblock() {
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
bool
|
||||
SGSocket::nonblock()
|
||||
{
|
||||
if (sock.getHandle() == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sock.setBlocking( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
SGSocket::poll()
|
||||
{
|
||||
netSocket* readers[2];
|
||||
|
||||
readers[0] = client != 0 ? client : &sock;
|
||||
readers[1] = 0;
|
||||
|
||||
netSocket* writers[1];
|
||||
writers[0] = 0;
|
||||
|
||||
int result = netSocket::select( readers, writers, 0 );
|
||||
|
||||
if (result > 0 && is_server && client == 0)
|
||||
{
|
||||
// Accept a new client connection
|
||||
netAddress addr;
|
||||
int new_fd = sock.accept( &addr );
|
||||
SG_LOG( SG_IO, SG_INFO, "Accepted connection from "
|
||||
<< addr.getHost() << ":" << addr.getPort() );
|
||||
client = new netSocket();
|
||||
client->setHandle( new_fd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
u_long arg = 1;
|
||||
if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
|
||||
int error_code = WSAGetLastError();
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error " << error_code << ": unable to set non-blocking mode"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
fcntl( sock, F_SETFL, O_NONBLOCK );
|
||||
#endif
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
|
||||
bool SGSocket::wsock_init = false;
|
||||
|
||||
bool
|
||||
SGSocket::wsastartup() {
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
|
||||
//wVersionRequested = MAKEWORD( 2, 2 );
|
||||
wVersionRequested = MAKEWORD( 1, 1 );
|
||||
int err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if (err != 0)
|
||||
{
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error: Couldn't load winsock" );
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Couldn't load a suitable winsock");
|
||||
WSACleanup( );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
wsock_init = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
+13
-30
@@ -39,11 +39,9 @@
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
#include <plib/netSocket.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# include <winsock.h>
|
||||
#endif
|
||||
SG_USING_STD(string);
|
||||
|
||||
#define SG_MAX_SOCKET_QUEUE 32
|
||||
|
||||
@@ -53,13 +51,6 @@ SG_USING_STD(string);
|
||||
*/
|
||||
class SGSocket : public SGIOChannel {
|
||||
public:
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
typedef SOCKET SocketType;
|
||||
#else
|
||||
typedef int SocketType;
|
||||
# define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
|
||||
private:
|
||||
string hostname;
|
||||
string port_str;
|
||||
@@ -67,31 +58,23 @@ private:
|
||||
char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ];
|
||||
int save_len;
|
||||
|
||||
SocketType sock;
|
||||
SocketType msgsock;
|
||||
short unsigned int port;
|
||||
int sock_style; // SOCK_STREAM or SOCK_DGRAM
|
||||
|
||||
netSocket sock;
|
||||
netSocket* client;
|
||||
unsigned short port;
|
||||
bool is_tcp;
|
||||
bool is_server;
|
||||
bool first_read;
|
||||
|
||||
static bool init;
|
||||
|
||||
// make a server (master listening) socket
|
||||
SocketType make_server_socket();
|
||||
bool make_server_socket();
|
||||
|
||||
// make a client socket
|
||||
SocketType make_client_socket();
|
||||
bool make_client_socket();
|
||||
|
||||
// wrapper functions
|
||||
size_t readsocket( int fd, void *buf, size_t count );
|
||||
size_t writesocket( int fd, const void *buf, size_t count );
|
||||
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||
int closesocket(int fd);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
// Ensure winsock has been initialised.
|
||||
static bool wsock_init;
|
||||
static bool wsastartup();
|
||||
#endif
|
||||
// Poll for new connections or data to read.
|
||||
int poll();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
using std::cout;
|
||||
#endif
|
||||
|
||||
class TcpClient
|
||||
{
|
||||
public:
|
||||
TcpClient( const char* host, const char* port );
|
||||
~TcpClient();
|
||||
|
||||
bool open();
|
||||
bool process();
|
||||
bool close();
|
||||
|
||||
private:
|
||||
SGIOChannel* channel;
|
||||
};
|
||||
|
||||
TcpClient::TcpClient( const char* host, const char* port )
|
||||
{
|
||||
channel = new SGSocket( host, port, "tcp" );
|
||||
}
|
||||
|
||||
TcpClient::~TcpClient()
|
||||
{
|
||||
delete channel;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpClient::open()
|
||||
{
|
||||
return channel->open( SG_IO_OUT );
|
||||
}
|
||||
|
||||
bool
|
||||
TcpClient::process()
|
||||
{
|
||||
char wbuf[1024];
|
||||
|
||||
sprintf( wbuf, "hello world\n" );
|
||||
int length = channel->writestring( wbuf );
|
||||
cout << "writestring returned " << length << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpClient::close()
|
||||
{
|
||||
return channel->close();
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
TcpClient client( "localhost", "5500" );
|
||||
if (!client.open())
|
||||
{
|
||||
cout << "client open failed\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
client.process();
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
sleep(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
//client.close();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include STL_STRING
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
using std::string;
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
using std::cout;
|
||||
#endif
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
public:
|
||||
TcpServer();
|
||||
bool open();
|
||||
bool process();
|
||||
bool close();
|
||||
|
||||
private:
|
||||
SGIOChannel* channel;
|
||||
};
|
||||
|
||||
TcpServer::TcpServer()
|
||||
{
|
||||
channel = new SGSocket( "", "5500", "tcp" );
|
||||
}
|
||||
|
||||
bool
|
||||
TcpServer::open()
|
||||
{
|
||||
channel->open( SG_IO_BI );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpServer::process()
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
int len;
|
||||
while ((len = channel->readline( buf, sizeof(buf) )) > 0)
|
||||
{
|
||||
cout << len << ": " << buf;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TcpServer::close()
|
||||
{
|
||||
return channel->close();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
TcpServer server;
|
||||
server.open();
|
||||
SG_LOG( SG_IO, SG_INFO, "Created TCP server" );
|
||||
|
||||
while (1)
|
||||
{
|
||||
server.process();
|
||||
}
|
||||
|
||||
server.close();
|
||||
return 0;
|
||||
}
|
||||
@@ -14,8 +14,4 @@ testmagvar_SOURCES = testmagvar.cxx
|
||||
|
||||
testmagvar_LDADD = $(top_builddir)/simgear/magvar/libsgmagvar.a
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
#include "magvar.hxx"
|
||||
|
||||
|
||||
SGMagVar::SGMagVar() {
|
||||
SGMagVar::SGMagVar()
|
||||
: magvar(0.0),
|
||||
magdip(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
SGMagVar::~SGMagVar() {
|
||||
|
||||
@@ -24,8 +24,4 @@ libsgmath_a_SOURCES = \
|
||||
sg_random.c \
|
||||
vector.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
+108
-26
@@ -22,6 +22,51 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
/*
|
||||
A C-program for MT19937, with initialization improved 2002/2/10.
|
||||
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
This is a faster version by taking Shawn Cokus's optimization,
|
||||
Matthe Bellew's simplification, Isaku Wada's real version.
|
||||
|
||||
Before using, initialize the state by using init_genrand(seed)
|
||||
or init_by_array(init_key, key_length).
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Any feedback is very welcome.
|
||||
http://www.math.keio.ac.jp/matumoto/emt.html
|
||||
email: matumoto@math.keio.ac.jp
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
@@ -32,50 +77,87 @@
|
||||
|
||||
#include "sg_random.h"
|
||||
|
||||
#ifndef HAVE_RAND
|
||||
# ifdef sgi
|
||||
# undef RAND_MAX
|
||||
# define RAND_MAX 2147483647
|
||||
# endif
|
||||
#endif
|
||||
/* Period parameters */
|
||||
#define N 624
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
|
||||
#define UMASK 0x80000000UL /* most significant w-r bits */
|
||||
#define LMASK 0x7fffffffUL /* least significant r bits */
|
||||
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
|
||||
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
|
||||
|
||||
#ifdef __SUNPRO_CC
|
||||
extern "C" {
|
||||
long int random();
|
||||
void srandom(unsigned int seed);
|
||||
static unsigned long state[N]; /* the array for the state vector */
|
||||
static int left = 1;
|
||||
static int initf = 0;
|
||||
static unsigned long *next;
|
||||
|
||||
/* initializes state[N] with a seed */
|
||||
void init_genrand(unsigned long s)
|
||||
{
|
||||
int j;
|
||||
state[0]= s & 0xffffffffUL;
|
||||
for (j=1; j<N; j++) {
|
||||
state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
|
||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||
/* In the previous versions, MSBs of the seed affect */
|
||||
/* only MSBs of the array state[]. */
|
||||
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||
state[j] &= 0xffffffffUL; /* for >32 bit machines */
|
||||
}
|
||||
#endif
|
||||
left = 1; initf = 1;
|
||||
}
|
||||
|
||||
static void next_state(void)
|
||||
{
|
||||
unsigned long *p=state;
|
||||
int j;
|
||||
|
||||
/* if init_genrand() has not been called, */
|
||||
/* a default initial seed is used */
|
||||
if (initf==0) init_genrand(5489UL);
|
||||
|
||||
left = N;
|
||||
next = state;
|
||||
|
||||
for (j=N-M+1; --j; p++)
|
||||
*p = p[M] ^ TWIST(p[0], p[1]);
|
||||
|
||||
for (j=M; --j; p++)
|
||||
*p = p[M-N] ^ TWIST(p[0], p[1]);
|
||||
|
||||
*p = p[M-N] ^ TWIST(p[0], state[0]);
|
||||
}
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void sg_srandom_time() {
|
||||
#ifdef HAVE_RAND
|
||||
srand(time(NULL));
|
||||
#else
|
||||
srandom(time(NULL));
|
||||
#endif
|
||||
init_genrand(time(NULL));
|
||||
}
|
||||
|
||||
|
||||
// Seed the random number generater with your own seed so can set up
|
||||
// repeatable randomization.
|
||||
void sg_srandom( unsigned int seed ) {
|
||||
#ifdef HAVE_RAND
|
||||
srand( seed );
|
||||
#else
|
||||
srandom( seed );
|
||||
#endif
|
||||
init_genrand( seed );
|
||||
}
|
||||
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double sg_random() {
|
||||
#ifdef HAVE_RAND
|
||||
return(rand() / (double)RAND_MAX);
|
||||
#else
|
||||
return(random() / (double)RAND_MAX);
|
||||
#endif
|
||||
unsigned long y;
|
||||
|
||||
if (--left == 0)
|
||||
next_state();
|
||||
y = *next++;
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & 0x9d2c5680UL;
|
||||
y ^= (y << 15) & 0xefc60000UL;
|
||||
y ^= (y >> 18);
|
||||
|
||||
return (double)y * (1.0/4294967295.0);
|
||||
/* divided by 2^32-1 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,11 @@ typedef vector < int > int_list;
|
||||
typedef int_list::iterator int_list_iterator;
|
||||
typedef int_list::const_iterator const_int_list_iterator;
|
||||
|
||||
/** STL vector list of doubles */
|
||||
typedef vector < double > double_list;
|
||||
typedef double_list::iterator double_list_iterator;
|
||||
typedef double_list::const_iterator const_double_list_iterator;
|
||||
|
||||
/** STL vector list of Point3D */
|
||||
typedef vector < Point3D > point_list;
|
||||
typedef point_list::iterator point_list_iterator;
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#pragma comment(compiler)
|
||||
#pragma comment(date)
|
||||
#pragma comment(timestamp)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma title("antoi - char array to integer")
|
||||
#pragma pagesize (80)
|
||||
|
||||
#pragma page(1)
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: antoi */
|
||||
@@ -78,4 +70,3 @@ int antoi(char * string, int len)
|
||||
|
||||
} /* end antoi */
|
||||
|
||||
#pragma page(1)
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("charcmp - characters compare with patterns ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: charcmp */
|
||||
@@ -34,7 +26,6 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
bool charcmp(char *str, char *pattern)
|
||||
{
|
||||
|
||||
+6
-121
@@ -1,9 +1,3 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
#include "Metar.h" /* standard header file */
|
||||
|
||||
@@ -11,9 +5,6 @@ float fracPart( char * );
|
||||
void DcdMTRmk( char **, Decoded_METAR * );
|
||||
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - Decode METAR report. ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: SaveTokenString */
|
||||
@@ -46,7 +37,6 @@ void DcdMTRmk( char **, Decoded_METAR * );
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static char **SaveTokenString ( char *string , char *delimeters )
|
||||
{
|
||||
@@ -99,9 +89,6 @@ static char **SaveTokenString ( char *string , char *delimeters )
|
||||
return token;
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - Decode METAR report. ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: freeTokens */
|
||||
@@ -124,7 +111,6 @@ static char **SaveTokenString ( char *string , char *delimeters )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static void freeTokens( char **token )
|
||||
{
|
||||
@@ -138,9 +124,6 @@ static void freeTokens( char **token )
|
||||
}
|
||||
return;
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: InitDcdMETAR */
|
||||
@@ -163,7 +146,6 @@ static void freeTokens( char **token )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static void InitDcdMETAR( Decoded_METAR *Mptr )
|
||||
{
|
||||
|
||||
@@ -439,9 +421,6 @@ static void InitDcdMETAR( Decoded_METAR *Mptr )
|
||||
return;
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: ResetMETARGroup */
|
||||
@@ -475,8 +454,7 @@ static void InitDcdMETAR( Decoded_METAR *Mptr )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static int ResetMETARGroup( int StartGroup,
|
||||
/*static int ResetMETARGroup( int StartGroup,
|
||||
int SaveStartGroup )
|
||||
{
|
||||
|
||||
@@ -495,11 +473,8 @@ static int ResetMETARGroup( int StartGroup,
|
||||
return (++SaveStartGroup);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: CodedHgt2Meters */
|
||||
@@ -523,7 +498,6 @@ static int ResetMETARGroup( int StartGroup,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static int CodedHgt2Meters( char *token, Decoded_METAR *Mptr )
|
||||
{
|
||||
@@ -537,10 +511,6 @@ static int CodedHgt2Meters( char *token, Decoded_METAR *Mptr )
|
||||
return (hgt*30);
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPartObscur */
|
||||
@@ -574,7 +544,6 @@ static int CodedHgt2Meters( char *token, Decoded_METAR *Mptr )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -617,10 +586,6 @@ static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCldLayer */
|
||||
@@ -650,7 +615,6 @@ static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isCldLayer( char *token )
|
||||
{
|
||||
@@ -671,10 +635,6 @@ static bool isCldLayer( char *token )
|
||||
nisdigit((token+3),3)) ? TRUE:FALSE;
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCAVOK */
|
||||
@@ -701,7 +661,6 @@ static bool isCldLayer( char *token )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isCAVOK( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -718,9 +677,6 @@ static bool isCAVOK( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: parseCldData */
|
||||
@@ -742,7 +698,6 @@ static bool isCAVOK( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static void parseCldData( char *token, Decoded_METAR *Mptr, int next)
|
||||
{
|
||||
@@ -766,9 +721,6 @@ static void parseCldData( char *token, Decoded_METAR *Mptr, int next)
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isSkyCond */
|
||||
@@ -790,7 +742,6 @@ static void parseCldData( char *token, Decoded_METAR *Mptr, int next)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isSkyCond( char **skycond, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -989,9 +940,6 @@ static bool isSkyCond( char **skycond, Decoded_METAR *Mptr,
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: prevailVSBY */
|
||||
@@ -1013,7 +961,6 @@ static bool isSkyCond( char **skycond, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static float prevailVSBY( char *visibility )
|
||||
{
|
||||
float Miles_vsby;
|
||||
@@ -1061,9 +1008,6 @@ static float prevailVSBY( char *visibility )
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVisibility */
|
||||
@@ -1086,7 +1030,6 @@ static float prevailVSBY( char *visibility )
|
||||
/* */
|
||||
/********************************************************************/
|
||||
|
||||
#pragma page(1)
|
||||
|
||||
static bool isVisibility( char **visblty, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -1329,9 +1272,6 @@ static bool isVisibility( char **visblty, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: vrblVsby */
|
||||
@@ -1353,7 +1293,7 @@ static bool isVisibility( char **visblty, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
#if 0
|
||||
static bool vrblVsby( char *string1, char *string2,
|
||||
Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -1429,11 +1369,9 @@ static bool vrblVsby( char *string1, char *string2,
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isMinMaxWinDir */
|
||||
@@ -1455,7 +1393,6 @@ static bool vrblVsby( char *string1, char *string2,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -1488,9 +1425,6 @@ static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isRVR */
|
||||
@@ -1512,7 +1446,6 @@ static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
|
||||
int ndex )
|
||||
@@ -1575,9 +1508,6 @@ static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isAltimStng */
|
||||
@@ -1599,7 +1529,6 @@ static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -1648,9 +1577,6 @@ static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTempGroup */
|
||||
@@ -1672,7 +1598,6 @@ static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -1768,9 +1693,6 @@ static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isWxToken */
|
||||
@@ -1792,9 +1714,8 @@ static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isWxToken( char *token )
|
||||
/*static bool isWxToken( char *token )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1807,12 +1728,9 @@ static bool isWxToken( char *token )
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPresentWX */
|
||||
@@ -1834,7 +1752,6 @@ static bool isWxToken( char *token )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPresentWX( char *token, Decoded_METAR *Mptr,
|
||||
int *NDEX, int *next )
|
||||
@@ -1929,9 +1846,6 @@ static bool isPresentWX( char *token, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isStnID */
|
||||
@@ -1953,7 +1867,6 @@ static bool isPresentWX( char *token, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -1976,9 +1889,6 @@ static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCodeName */
|
||||
@@ -2000,7 +1910,6 @@ static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2020,9 +1929,6 @@ static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isNIL */
|
||||
@@ -2044,7 +1950,6 @@ static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2063,9 +1968,6 @@ static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isAUTO */
|
||||
@@ -2087,7 +1989,6 @@ static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2106,9 +2007,6 @@ static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCOR */
|
||||
@@ -2130,7 +2028,6 @@ static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2149,9 +2046,6 @@ static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTimeUTC */
|
||||
@@ -2173,7 +2067,6 @@ static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -2228,9 +2121,6 @@ static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isWindData */
|
||||
@@ -2252,7 +2142,6 @@ static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -2322,9 +2211,6 @@ static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - Decode METAR report. ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: DcdMETAR */
|
||||
@@ -2349,7 +2235,6 @@ static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
|
||||
int DcdMETAR( char *string , Decoded_METAR *Mptr )
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#define SKY1_len 50
|
||||
float fracPart( char * );
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTS_LOC */
|
||||
@@ -48,7 +45,6 @@ float fracPart( char * );
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTS_LOC( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -134,9 +130,6 @@ static bool isTS_LOC( char **string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isDVR */
|
||||
@@ -158,7 +151,6 @@ static bool isTS_LOC( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isDVR( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -217,9 +209,6 @@ static bool isDVR( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTornadicActiv */
|
||||
@@ -260,7 +249,6 @@ static bool isDVR( char *token, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTornadicActiv( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -531,9 +519,6 @@ static bool isTornadicActiv( char **string, Decoded_METAR *Mptr,
|
||||
}
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPartObscur */
|
||||
@@ -576,7 +561,6 @@ static bool isTornadicActiv( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
int ndex, int *NDEX )
|
||||
{
|
||||
@@ -677,9 +661,6 @@ static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isA0indicator */
|
||||
@@ -720,7 +701,6 @@ static bool isPartObscur( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isA0indicator( char *indicator, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -763,9 +743,6 @@ static bool isA0indicator( char *indicator, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPeakWind */
|
||||
@@ -805,7 +782,6 @@ static bool isA0indicator( char *indicator, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isPeakWind( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -898,9 +874,6 @@ static bool isPeakWind( char **string, Decoded_METAR *Mptr,
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isWindShift */
|
||||
@@ -940,7 +913,6 @@ static bool isPeakWind( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isWindShift( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX)
|
||||
{
|
||||
@@ -1030,9 +1002,6 @@ static bool isWindShift( char **string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTowerVsby */
|
||||
@@ -1071,7 +1040,6 @@ static bool isWindShift( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isTowerVsby( char **token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
|
||||
@@ -1186,9 +1154,6 @@ static bool isTowerVsby( char **token, Decoded_METAR *Mptr, int *NDEX)
|
||||
}
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isSurfaceVsby */
|
||||
@@ -1227,7 +1192,6 @@ static bool isTowerVsby( char **token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isSurfaceVsby( char **token, Decoded_METAR *Mptr,
|
||||
int *NDEX)
|
||||
{
|
||||
@@ -1344,9 +1308,6 @@ static bool isSurfaceVsby( char **token, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVariableVsby */
|
||||
@@ -1386,7 +1347,6 @@ static bool isSurfaceVsby( char **token, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isVariableVsby( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -1596,9 +1556,6 @@ static bool isVariableVsby( char **string, Decoded_METAR *Mptr,
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVsby2ndSite */
|
||||
@@ -1642,7 +1599,6 @@ static bool isVariableVsby( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isVsby2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
int *NDEX)
|
||||
{
|
||||
@@ -1801,9 +1757,6 @@ static bool isVsby2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isLTGfreq */
|
||||
@@ -1847,7 +1800,6 @@ static bool isVsby2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
/* */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
bool static isLTGfreq( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -2088,16 +2040,8 @@ bool static isLTGfreq( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
|
||||
|
||||
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Metar.h" /* standard header file */
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isRecentWx */
|
||||
@@ -2141,7 +2085,6 @@ bool static isLTGfreq( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isRecentWX( char **token, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -2478,9 +2421,6 @@ static bool isRecentWX( char **token, Decoded_METAR *Mptr,
|
||||
}
|
||||
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVariableCIG */
|
||||
@@ -2511,7 +2451,6 @@ static bool isRecentWX( char **token, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isVariableCIG( char **token, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -2544,9 +2483,6 @@ static bool isVariableCIG( char **token, Decoded_METAR *Mptr,
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCeil2ndSite */
|
||||
@@ -2581,7 +2517,6 @@ static bool isVariableCIG( char **token, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isCIG2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
int *NDEX)
|
||||
{
|
||||
@@ -2620,9 +2555,6 @@ static bool isCIG2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPRESFR */
|
||||
@@ -2671,7 +2603,6 @@ static bool isCIG2ndSite( char **token, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPRESFR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2688,9 +2619,6 @@ static bool isPRESFR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
}
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPRESRR */
|
||||
@@ -2739,7 +2667,6 @@ static bool isPRESFR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPRESRR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -2757,9 +2684,6 @@ static bool isPRESRR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isSLP */
|
||||
@@ -2781,7 +2705,6 @@ static bool isPRESRR( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isSLP( char **token, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
@@ -2855,7 +2778,6 @@ static bool isSLP( char **token, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
static bool isSectorVsby( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -2933,9 +2855,6 @@ static bool isSectorVsby( char **string, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isGR */
|
||||
@@ -2984,7 +2903,6 @@ static bool isSectorVsby( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isGR( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
char *slash;
|
||||
@@ -3067,9 +2985,6 @@ static bool isGR( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
}
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVIRGA */
|
||||
@@ -3118,7 +3033,6 @@ static bool isGR( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isVIRGA( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -3154,7 +3068,6 @@ static bool isVIRGA( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
static bool isSfcObscuration( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -3242,7 +3155,6 @@ static bool isSfcObscuration( char *string, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
static bool isCeiling( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
|
||||
@@ -3282,7 +3194,6 @@ static bool isCeiling( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
}
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
static bool isVrbSky( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
static char *cldPtr[] = {"FEW", "SCT", "BKN", "OVC", NULL };
|
||||
@@ -3386,7 +3297,6 @@ static bool isVrbSky( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
static bool isObscurAloft( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -3470,7 +3380,6 @@ static bool isObscurAloft( char **string, Decoded_METAR *Mptr,
|
||||
}
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
static bool isNOSPECI( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
|
||||
@@ -3485,7 +3394,6 @@ static bool isNOSPECI( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#pragma page(1)
|
||||
static bool isLAST( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
|
||||
@@ -3500,9 +3408,6 @@ static bool isLAST( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isSynopClouds */
|
||||
@@ -3524,7 +3429,6 @@ static bool isLAST( char *string, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isSynopClouds( char *token, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -3557,7 +3461,6 @@ static bool isSynopClouds( char *token, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
static bool isSNINCR( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
{
|
||||
|
||||
@@ -3596,9 +3499,6 @@ static bool isSNINCR( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isSnowDepth */
|
||||
@@ -3620,7 +3520,6 @@ static bool isSNINCR( char **string, Decoded_METAR *Mptr, int *NDEX )
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isSnowDepth( char *token, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -3644,7 +3543,6 @@ static bool isSnowDepth( char *token, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
static bool isWaterEquivSnow( char *string,
|
||||
Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -3666,7 +3564,6 @@ static bool isWaterEquivSnow( char *string,
|
||||
}
|
||||
|
||||
}
|
||||
#pragma page(1)
|
||||
static bool isSunshineDur( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -3692,9 +3589,6 @@ static bool isSunshineDur( char *string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isHourlyPrecip */
|
||||
@@ -3743,7 +3637,6 @@ static bool isSunshineDur( char *string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isHourlyPrecip( char **string, Decoded_METAR *Mptr,
|
||||
int *NDEX)
|
||||
@@ -3790,9 +3683,6 @@ static bool isHourlyPrecip( char **string, Decoded_METAR *Mptr,
|
||||
}
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isP6Precip */
|
||||
@@ -3841,7 +3731,6 @@ static bool isHourlyPrecip( char **string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isP6Precip( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -3869,9 +3758,6 @@ static bool isP6Precip( char *string, Decoded_METAR *Mptr,
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isP24Precip */
|
||||
@@ -3920,7 +3806,6 @@ static bool isP6Precip( char *string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isP24Precip( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -3946,9 +3831,6 @@ static bool isP24Precip( char *string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTTdTenths */
|
||||
@@ -3997,7 +3879,6 @@ static bool isP24Precip( char *string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTTdTenths( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4058,9 +3939,6 @@ static bool isTTdTenths( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
}
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isMaxTemp */
|
||||
@@ -4082,7 +3960,6 @@ static bool isTTdTenths( char *token, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isMaxTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
char buf[ 6 ];
|
||||
@@ -4122,9 +3999,6 @@ static bool isMaxTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isMinTemp */
|
||||
@@ -4146,7 +4020,6 @@ static bool isMaxTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isMinTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
char buf[ 6 ];
|
||||
@@ -4185,9 +4058,6 @@ static bool isMinTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isT24MaxMinTemp */
|
||||
@@ -4209,7 +4079,6 @@ static bool isMinTemp(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
static bool isT24MaxMinTemp( char *string, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
{
|
||||
@@ -4265,9 +4134,6 @@ static bool isT24MaxMinTemp( char *string, Decoded_METAR *Mptr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPtendency */
|
||||
@@ -4289,7 +4155,6 @@ static bool isT24MaxMinTemp( char *string, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPtendency(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4330,9 +4195,6 @@ static bool isPtendency(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPWINO */
|
||||
@@ -4354,7 +4216,6 @@ static bool isPtendency(char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPWINO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4373,9 +4234,6 @@ static bool isPWINO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isPNO */
|
||||
@@ -4397,7 +4255,6 @@ static bool isPWINO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isPNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4416,9 +4273,6 @@ static bool isPNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isRVRNO */
|
||||
@@ -4440,7 +4294,6 @@ static bool isPNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isRVRNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4458,9 +4311,6 @@ static bool isRVRNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isCHINO */
|
||||
@@ -4482,7 +4332,6 @@ static bool isRVRNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isCHINO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4520,9 +4369,6 @@ static bool isCHINO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isVISNO */
|
||||
@@ -4544,7 +4390,6 @@ static bool isCHINO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isVISNO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4581,9 +4426,6 @@ static bool isVISNO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isFZRANO */
|
||||
@@ -4605,7 +4447,6 @@ static bool isVISNO( char **string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isFZRANO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4624,9 +4465,6 @@ static bool isFZRANO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isTSNO */
|
||||
@@ -4675,7 +4513,6 @@ static bool isFZRANO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isTSNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
{
|
||||
@@ -4693,9 +4530,6 @@ static bool isTSNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
|
||||
}
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: isDollarSign */
|
||||
@@ -4717,7 +4551,6 @@ static bool isTSNO( char *string, Decoded_METAR *Mptr, int *NDEX)
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
static bool isDollarSign( char *indicator, Decoded_METAR *Mptr,
|
||||
int *NDEX )
|
||||
@@ -4736,9 +4569,6 @@ static bool isDollarSign( char *indicator, Decoded_METAR *Mptr,
|
||||
}
|
||||
}
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: DcdMTRmk */
|
||||
@@ -4768,7 +4598,6 @@ static bool isDollarSign( char *indicator, Decoded_METAR *Mptr,
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
void DcdMTRmk( char **token, Decoded_METAR *Mptr )
|
||||
{
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "Metar.h"
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: dRVMETAR */
|
||||
@@ -29,10 +26,8 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
char bltn_prefix[20];
|
||||
static char *string[] =
|
||||
{
|
||||
"KAST 221156Z COR 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
@@ -516,7 +511,6 @@ NULL,
|
||||
Decoded_METAR *Mptr = &Metar;
|
||||
int j,
|
||||
ErReturn;
|
||||
static char *synopRTRN = NULL;
|
||||
|
||||
|
||||
/***************************************************/
|
||||
@@ -541,4 +535,5 @@ NULL,
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "Local.h" /* standard header file */
|
||||
#include "Metar.h"
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: fracPart */
|
||||
@@ -26,7 +23,6 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
float fracPart( char *string )
|
||||
{
|
||||
|
||||
@@ -11,8 +11,4 @@ libsgmetar_a_SOURCES = \
|
||||
MetarStation.cpp \
|
||||
Prtdmetr.cpp Stspack2.cpp Stspack3.cpp
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "Local.h" /* standard header file */
|
||||
#include "Metar.h"
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: prtDMETR */
|
||||
@@ -25,7 +23,6 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
void prtDMETR( Decoded_METAR *Mptr )
|
||||
{
|
||||
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("stspack2 - Local string test functions ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: stspack2 */
|
||||
@@ -75,7 +67,6 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
int nisalnum(char *s, int n) {
|
||||
|
||||
@@ -208,4 +199,3 @@ int nisxdigi(char *s, int n) {
|
||||
|
||||
} /* end nisxdigi */
|
||||
|
||||
#pragma page(1)
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("stspack3 - Local string test functions ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: stspack3 */
|
||||
@@ -75,7 +67,6 @@
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
char *nxtalnum(char *s) {
|
||||
|
||||
for (; !isalnum(*s) && *s; s++) ;
|
||||
@@ -208,4 +199,3 @@ char *nxtxdigi(char *s) {
|
||||
} /* end nxtxdigi */
|
||||
|
||||
|
||||
#pragma page(1)
|
||||
|
||||
@@ -6,6 +6,7 @@ include_HEADERS = \
|
||||
commands.hxx \
|
||||
exception.hxx \
|
||||
props.hxx \
|
||||
props_io.hxx \
|
||||
sg_path.hxx \
|
||||
sgstream.hxx \
|
||||
stopwatch.hxx \
|
||||
@@ -29,8 +30,4 @@ noinst_PROGRAMS = props_test
|
||||
props_test_SOURCES = props_test.cxx
|
||||
props_test_LDADD = libsgmisc.a ../xml/libsgxml.a ../debug/libsgdebug.a
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
+3
-103
@@ -5,36 +5,7 @@
|
||||
// $Id$
|
||||
|
||||
#include "commands.hxx"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of SGCommandState class.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SGCommandState::SGCommandState ()
|
||||
: _args(0)
|
||||
{
|
||||
}
|
||||
|
||||
SGCommandState::SGCommandState (const SGPropertyNode * args)
|
||||
: _args(0)
|
||||
{
|
||||
setArgs(args);
|
||||
}
|
||||
|
||||
SGCommandState::~SGCommandState ()
|
||||
{
|
||||
delete _args;
|
||||
}
|
||||
|
||||
void
|
||||
SGCommandState::setArgs (const SGPropertyNode * args)
|
||||
{
|
||||
delete _args;
|
||||
_args = new SGPropertyNode();
|
||||
copyProperties(args, _args);
|
||||
}
|
||||
#include "props_io.hxx"
|
||||
|
||||
|
||||
|
||||
@@ -80,84 +51,13 @@ SGCommandMgr::getCommandNames () const
|
||||
}
|
||||
|
||||
bool
|
||||
SGCommandMgr::execute (const string &name, const SGPropertyNode * arg,
|
||||
SGCommandState ** state) const
|
||||
SGCommandMgr::execute (const string &name, const SGPropertyNode * arg) const
|
||||
{
|
||||
command_t command = getCommand(name);
|
||||
if (command == 0)
|
||||
return false;
|
||||
else
|
||||
return (*command)(arg, state);
|
||||
return (*command)(arg);
|
||||
}
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, bool value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setBoolValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, int value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setIntValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, long value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setLongValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, float value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setFloatValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, double value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setDoubleValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, string value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setStringValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// end of commands.cxx
|
||||
|
||||
+4
-153
@@ -24,58 +24,13 @@ SG_USING_STD(map);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
|
||||
/**
|
||||
* Stored state for a command.
|
||||
*
|
||||
* <p>This class allows a command to cache parts of its state between
|
||||
* invocations with the same parameters. Nearly every command that
|
||||
* actually uses this will subclass it in some way. The command
|
||||
* allocates the structure, but it is up to the caller to delete it
|
||||
* when it is no longer necessary, unless the command deletes it
|
||||
* and replaces the value with 0 or another command-state object
|
||||
* first.</p>
|
||||
*
|
||||
* <p>Note that this class is for caching only; all of the information
|
||||
* in it must be recoverable by other means, since the state could
|
||||
* arbitrarily disappear between invocations if the caller decides to
|
||||
* delete it.</p>
|
||||
*
|
||||
* <p>By default, the command state includes a place to keep a copy of
|
||||
* the parameters.</p>
|
||||
*
|
||||
* @author David Megginson, david@megginson.com
|
||||
*/
|
||||
class SGCommandState
|
||||
{
|
||||
public:
|
||||
SGCommandState ();
|
||||
SGCommandState (const SGPropertyNode * args);
|
||||
virtual ~SGCommandState ();
|
||||
virtual void setArgs (const SGPropertyNode * args);
|
||||
virtual const SGPropertyNode * getArgs () const { return _args; }
|
||||
private:
|
||||
SGPropertyNode * _args;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Manage commands.
|
||||
*
|
||||
* <p>This class allows the application to register and unregister
|
||||
* commands, and provides shortcuts for executing them. Commands are
|
||||
* simple functions that take a const pointer to an SGPropertyNode and
|
||||
* a pointer to a pointer variable (which should be 0 initially) where
|
||||
* the function can store compiled copies of its arguments, etc. to
|
||||
* avoid expensive recalculations. If the command deletes the
|
||||
* SGCommandState, it must replace it with a new pointer or 0;
|
||||
* otherwise, the caller is free to delete and zero the pointer at any
|
||||
* time and the command will start fresh with the next invocation.
|
||||
* The command must return a bool value indicating success or failure.
|
||||
* The property node may be ignored, or it may contain values that the
|
||||
* command uses as parameters.</p>
|
||||
*
|
||||
* <p>There are convenience methods for invoking a command function
|
||||
* with no arguments or with a single, primitive argument.</p>
|
||||
* simple functions that take a const pointer to an SGPropertyNode:
|
||||
* the function may use the nodes children as parameters.</p>
|
||||
*
|
||||
* @author David Megginson, david@megginson.com
|
||||
*/
|
||||
@@ -86,8 +41,7 @@ public:
|
||||
/**
|
||||
* Type for a command function.
|
||||
*/
|
||||
typedef bool (*command_t) (const SGPropertyNode * arg,
|
||||
SGCommandState ** state);
|
||||
typedef bool (*command_t) (const SGPropertyNode * arg);
|
||||
|
||||
|
||||
/**
|
||||
@@ -136,9 +90,6 @@ public:
|
||||
/**
|
||||
* Execute a command.
|
||||
*
|
||||
* This is the primary method for invoking a command; the others
|
||||
* are convenience methods that invoke this one indirectly.
|
||||
*
|
||||
* @param name The name of the command.
|
||||
* @param arg A const pointer to an SGPropertyNode. The node
|
||||
* may have a value and/or children, etc., so that it is possible
|
||||
@@ -146,107 +97,7 @@ public:
|
||||
* @return true if the command is present and executes successfully,
|
||||
* false otherwise.
|
||||
*/
|
||||
virtual bool execute (const string &name,
|
||||
const SGPropertyNode * arg,
|
||||
SGCommandState ** state) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with no argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with no value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single bool argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a bool value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The bool argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, bool arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single int argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a int value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The int argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, int arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single long argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a long value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The long argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, long arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single float argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a float value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The float argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, float arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single double argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a double value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The double argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, double arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single string argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a string value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The string argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, string arg) const;
|
||||
|
||||
virtual bool execute (const string &name, const SGPropertyNode * arg) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+1083
-335
File diff suppressed because it is too large
Load Diff
+358
-170
@@ -12,23 +12,38 @@
|
||||
#ifndef __PROPS_HXX
|
||||
#define __PROPS_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#ifndef PROPS_STANDALONE
|
||||
#define PROPS_STANDALONE 0
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#if PROPS_STANDALONE
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
|
||||
#else
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include STL_STRING
|
||||
#include STL_IOSTREAM
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(istream);
|
||||
SG_USING_STD(ostream);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NONE
|
||||
#pragma warn A sloppy coder has defined NONE as a macro!
|
||||
#undef NONE
|
||||
@@ -82,40 +97,50 @@ SG_USING_STD(ostream);
|
||||
// This is the mechanism that information-providing routines can
|
||||
// use to link their own values to the property manager. Any
|
||||
// SGValue can be tied to a raw value and then untied again.
|
||||
//
|
||||
// Note: we are forced to use inlined methods here to ensure
|
||||
// that the templates will be instantiated. We're probably taking
|
||||
// a small performance hit for that.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Abstract base class for a raw value.
|
||||
*
|
||||
* The property manager is implemented in three layers. The {@link
|
||||
* <p>The property manager is implemented in two layers. The {@link
|
||||
* SGPropertyNode} is the highest and most abstract layer,
|
||||
* representing * an LValue/RValue pair: it * records the position
|
||||
* of the property in the property tree and * contains facilities
|
||||
* for navigation to other nodes. Each node * may contain an {@link
|
||||
* SGValue}, which is guaranteed persistent: the * {@link SGValue}
|
||||
* will not change during a session, even if the * property is bound
|
||||
* and unbound multiple times. The SGValue is the * abstraction of
|
||||
* an RValue: it allows for conversion among all of the different
|
||||
* types, and can be bound to external pointers, functions, methods,
|
||||
* or other data sources. Every SGValue contains an SGRawValue of
|
||||
* a specific type. The SGRawValue (this class) may change frequently
|
||||
* during a session as a value is retyped or bound and unbound to
|
||||
* various data source, but the abstract SGValue layer insulates
|
||||
* the application from those changes. The raw value contains no
|
||||
* facilities for data binding or for type conversion: it is simply
|
||||
* the abstraction of a primitive data type (or a compound data
|
||||
* type, in the case of a string).
|
||||
* representing an LValue/RValue pair: it records the position of the
|
||||
* property in the property tree and contains facilities for
|
||||
* navigation to other nodes. It is guaranteed to be persistent: the
|
||||
* {@link SGPropertyNode} will not change during a session, even if
|
||||
* the property is bound and unbound multiple times.</p>
|
||||
*
|
||||
* The SGValue class always keeps a *copy* of a raw value, not the
|
||||
* original one passed to it; if you override a derived class but do
|
||||
* not replace the {@link #clone} method, strange things will happen.
|
||||
* <p>When the property value is not managed internally in the
|
||||
* SGPropertyNode, the SGPropertyNode will contain a reference to an
|
||||
* SGRawValue (this class), which provides an abstract way to get,
|
||||
* set, and clone the underlying value. The SGRawValue may change
|
||||
* frequently during a session as a value is retyped or bound and
|
||||
* unbound to various data source, but the abstract SGPropertyNode
|
||||
* layer insulates the application from those changes. The raw value
|
||||
* contains no facilities for data binding or for type conversion: it
|
||||
* is simply the abstraction of a primitive data type (or a compound
|
||||
* data type, in the case of a string).</p>
|
||||
*
|
||||
* All raw values must implement {@link #getValue}, {@link #setValue},
|
||||
* and {@link #clone} for the appropriate type.
|
||||
* <p>The SGPropertyNode class always keeps a *copy* of a raw value,
|
||||
* not the original one passed to it; if you override a derived class
|
||||
* but do not replace the {@link #clone} method, strange things will
|
||||
* happen.</p>
|
||||
*
|
||||
* @see SGValue
|
||||
* @see SGPropertyNode */
|
||||
* <p>All derived SGRawValue classes must implement {@link #getValue},
|
||||
* {@link #setValue}, and {@link #clone} for the appropriate type.</p>
|
||||
*
|
||||
* @see SGPropertyNode
|
||||
* @see SGRawValuePointer
|
||||
* @see SGRawValueFunctions
|
||||
* @see SGRawValueFunctionsIndexed
|
||||
* @see SGRawValueMethods
|
||||
* @see SGRawValueMethodsIndexed
|
||||
*/
|
||||
template <class T>
|
||||
class SGRawValue
|
||||
{
|
||||
@@ -183,61 +208,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An unbound raw value, stored internally.
|
||||
*
|
||||
* Instances of this class are created automatically, by default,
|
||||
* by the SGValue class; ordinarily the application should not
|
||||
* need to touch it.
|
||||
*/
|
||||
template <class T>
|
||||
class SGRawValueInternal : public SGRawValue<T>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* Initialize with the default value for this type.
|
||||
*/
|
||||
SGRawValueInternal () {}
|
||||
|
||||
/**
|
||||
* Explicit value constructor.
|
||||
*
|
||||
* Initialize with the underlying value provided.
|
||||
*
|
||||
* @param value The initial value for this property.
|
||||
*/
|
||||
SGRawValueInternal (T value) : _value(value) {}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~SGRawValueInternal () {}
|
||||
|
||||
/**
|
||||
* Get the underlying value.
|
||||
*/
|
||||
virtual T getValue () const { return _value; }
|
||||
|
||||
/**
|
||||
* Set the underlying value.
|
||||
*/
|
||||
virtual bool setValue (T value) { _value = value; return true; }
|
||||
|
||||
/**
|
||||
* Create a deep copy of this raw value.
|
||||
*/
|
||||
virtual SGRawValue<T> * clone () const {
|
||||
return new SGRawValueInternal<T>(_value);
|
||||
}
|
||||
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A raw value bound to a pointer.
|
||||
*
|
||||
@@ -382,6 +352,8 @@ private:
|
||||
* not have a getter. An indexed value is useful for binding one
|
||||
* of a list of possible values (such as multiple engines for a
|
||||
* plane). The index is hard-coded at creation time.
|
||||
*
|
||||
* @see SGRawValue
|
||||
*/
|
||||
template <class T>
|
||||
class SGRawValueFunctionsIndexed : public SGRawValue<T>
|
||||
@@ -477,6 +449,100 @@ private:
|
||||
setter_t _setter;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The smart pointer that manage reference counting
|
||||
*/
|
||||
class SGPropertyNode;
|
||||
class SGPropertyNode_ptr
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
SGPropertyNode_ptr();
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*/
|
||||
SGPropertyNode_ptr( const SGPropertyNode_ptr &r );
|
||||
|
||||
/**
|
||||
* Constructor from a pointer to a node
|
||||
*/
|
||||
SGPropertyNode_ptr( SGPropertyNode *p );
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~SGPropertyNode_ptr();
|
||||
|
||||
/**
|
||||
* Assignement operator
|
||||
*/
|
||||
SGPropertyNode_ptr &operator=( const SGPropertyNode_ptr &r );
|
||||
|
||||
/**
|
||||
* Pointer access operator
|
||||
*/
|
||||
SGPropertyNode *operator->();
|
||||
|
||||
/**
|
||||
* Pointer access operator (const)
|
||||
*/
|
||||
const SGPropertyNode *operator->() const;
|
||||
|
||||
/**
|
||||
* Conversion to SGPropertyNode * operator
|
||||
*/
|
||||
operator SGPropertyNode *();
|
||||
|
||||
/**
|
||||
* Conversion to const SGPropertyNode * operator
|
||||
*/
|
||||
operator const SGPropertyNode *() const;
|
||||
|
||||
/**
|
||||
* Return the pointer.
|
||||
*/
|
||||
SGPropertyNode * ptr () { return _ptr; }
|
||||
|
||||
/**
|
||||
* Validity test
|
||||
*/
|
||||
bool valid() const;
|
||||
|
||||
private:
|
||||
|
||||
SGPropertyNode *_ptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The property change listener interface.
|
||||
*
|
||||
* <p>Any class that needs to listen for property changes must implement
|
||||
* this interface.</p>
|
||||
*/
|
||||
class SGPropertyChangeListener
|
||||
{
|
||||
public:
|
||||
virtual ~SGPropertyChangeListener ();
|
||||
virtual void valueChanged (SGPropertyNode * node);
|
||||
virtual void childAdded (SGPropertyNode * parent, SGPropertyNode * child);
|
||||
virtual void childRemoved (SGPropertyNode * parent, SGPropertyNode * child);
|
||||
|
||||
protected:
|
||||
friend class SGPropertyNode;
|
||||
virtual void register_property (SGPropertyNode * node);
|
||||
virtual void unregister_property (SGPropertyNode * node);
|
||||
|
||||
private:
|
||||
vector<SGPropertyNode *> _properties;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -484,9 +550,14 @@ private:
|
||||
*/
|
||||
class SGPropertyNode
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Public constants.
|
||||
*/
|
||||
enum {
|
||||
MAX_STRING_LEN = 1024
|
||||
};
|
||||
|
||||
/**
|
||||
* Property value types.
|
||||
@@ -514,11 +585,19 @@ public:
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
ARCHIVE = 4,
|
||||
TRACE_READ = 8,
|
||||
TRACE_WRITE = 16
|
||||
REMOVED = 8,
|
||||
TRACE_READ = 16,
|
||||
TRACE_WRITE = 32
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Last used attribute
|
||||
* Update as needed when enum Attribute is changed
|
||||
*/
|
||||
static const int LAST_USED_ATTRIBUTE;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
@@ -551,13 +630,19 @@ public:
|
||||
/**
|
||||
* Get the node's simple (XML) name.
|
||||
*/
|
||||
const string &getName () const { return _name; }
|
||||
const char * getName () const { return _name; }
|
||||
|
||||
|
||||
/**
|
||||
* Get the node's pretty display name, with subscript when needed.
|
||||
*/
|
||||
const char * getDisplayName (bool simplify = false) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the node's integer index.
|
||||
*/
|
||||
const int getIndex () const { return _index; }
|
||||
int getIndex () const { return _index; }
|
||||
|
||||
|
||||
/**
|
||||
@@ -580,7 +665,7 @@ public:
|
||||
/**
|
||||
* Get the number of child nodes.
|
||||
*/
|
||||
const int nChildren () const { return _children.size(); }
|
||||
int nChildren () const { return _children.size(); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -595,29 +680,39 @@ public:
|
||||
const SGPropertyNode * getChild (int position) const;
|
||||
|
||||
|
||||
/**
|
||||
* Test whether a named child exists.
|
||||
*/
|
||||
bool hasChild (const char * name, int index = 0) const
|
||||
{
|
||||
return (getChild(name, index) != 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a child node by name and index.
|
||||
*/
|
||||
SGPropertyNode * getChild (const string &name, int index = 0,
|
||||
SGPropertyNode * getChild (const char * name, int index = 0,
|
||||
bool create = false);
|
||||
|
||||
|
||||
/**
|
||||
* Get a const child node by name and index.
|
||||
*/
|
||||
const SGPropertyNode * getChild (const string &name, int index = 0) const;
|
||||
const SGPropertyNode * getChild (const char * name, int index = 0) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get a vector of all children with the specified name.
|
||||
*/
|
||||
vector<SGPropertyNode *> getChildren (const string &name);
|
||||
vector<SGPropertyNode_ptr> getChildren (const char * name) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get a vector all all children (const) with the specified name.
|
||||
* Remove a child node
|
||||
*/
|
||||
vector<const SGPropertyNode *> getChildren (const string &name) const;
|
||||
SGPropertyNode_ptr removeChild (const char * name, int index = 0,
|
||||
bool keep = true);
|
||||
|
||||
|
||||
//
|
||||
@@ -634,7 +729,7 @@ public:
|
||||
/**
|
||||
* Alias this node's leaf value to another's by relative path.
|
||||
*/
|
||||
bool alias (const string &path);
|
||||
bool alias (const char * path);
|
||||
|
||||
|
||||
/**
|
||||
@@ -669,7 +764,7 @@ public:
|
||||
/**
|
||||
* Get the path to this node from the root.
|
||||
*/
|
||||
string getPath (bool simplify = false) const;
|
||||
const char * getPath (bool simplify = false) const;
|
||||
|
||||
|
||||
/**
|
||||
@@ -687,7 +782,7 @@ public:
|
||||
/**
|
||||
* Get a pointer to another node by relative path.
|
||||
*/
|
||||
SGPropertyNode * getNode (const string &relative_path, bool create = false);
|
||||
SGPropertyNode * getNode (const char * relative_path, bool create = false);
|
||||
|
||||
|
||||
/**
|
||||
@@ -700,14 +795,14 @@ public:
|
||||
* provided overrides any given in the path itself for the last
|
||||
* component.
|
||||
*/
|
||||
SGPropertyNode * getNode (const string &relative_path, int index,
|
||||
SGPropertyNode * getNode (const char * relative_path, int index,
|
||||
bool create = false);
|
||||
|
||||
|
||||
/**
|
||||
* Get a const pointer to another node by relative path.
|
||||
*/
|
||||
const SGPropertyNode * getNode (const string &relative_path) const;
|
||||
const SGPropertyNode * getNode (const char * relative_path) const;
|
||||
|
||||
|
||||
/**
|
||||
@@ -716,7 +811,7 @@ public:
|
||||
* This method leaves the index off the last member of the path,
|
||||
* so that the user can specify it separate.
|
||||
*/
|
||||
const SGPropertyNode * getNode (const string &relative_path,
|
||||
const SGPropertyNode * getNode (const char * relative_path,
|
||||
int index) const;
|
||||
|
||||
|
||||
@@ -794,7 +889,7 @@ public:
|
||||
/**
|
||||
* Get a string value for this node.
|
||||
*/
|
||||
string getStringValue () const;
|
||||
const char * getStringValue () const;
|
||||
|
||||
|
||||
|
||||
@@ -831,13 +926,13 @@ public:
|
||||
/**
|
||||
* Set a string value for this node.
|
||||
*/
|
||||
bool setStringValue (string value);
|
||||
bool setStringValue (const char * value);
|
||||
|
||||
|
||||
/**
|
||||
* Set a value of unspecified type for this node.
|
||||
*/
|
||||
bool setUnspecifiedValue (string value);
|
||||
bool setUnspecifiedValue (const char * value);
|
||||
|
||||
|
||||
//
|
||||
@@ -884,7 +979,7 @@ public:
|
||||
/**
|
||||
* Bind this node to an external string source.
|
||||
*/
|
||||
bool tie (const SGRawValue<string> &rawValue, bool useDefault = true);
|
||||
bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
@@ -902,164 +997,213 @@ public:
|
||||
/**
|
||||
* Get another node's type.
|
||||
*/
|
||||
Type getType (const string &relative_path) const;
|
||||
Type getType (const char * relative_path) const;
|
||||
|
||||
|
||||
/**
|
||||
* Test whether another node has a leaf value.
|
||||
*/
|
||||
bool hasValue (const string &relative_path) const;
|
||||
bool hasValue (const char * relative_path) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as a bool.
|
||||
*/
|
||||
bool getBoolValue (const string &relative_path,
|
||||
bool getBoolValue (const char * relative_path,
|
||||
bool defaultValue = false) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as an int.
|
||||
*/
|
||||
int getIntValue (const string &relative_path,
|
||||
int getIntValue (const char * relative_path,
|
||||
int defaultValue = 0) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as a long int.
|
||||
*/
|
||||
long getLongValue (const string &relative_path,
|
||||
long getLongValue (const char * relative_path,
|
||||
long defaultValue = 0L) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as a float.
|
||||
*/
|
||||
float getFloatValue (const string &relative_path,
|
||||
float getFloatValue (const char * relative_path,
|
||||
float defaultValue = 0.0) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as a double.
|
||||
*/
|
||||
double getDoubleValue (const string &relative_path,
|
||||
double getDoubleValue (const char * relative_path,
|
||||
double defaultValue = 0.0L) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get another node's value as a string.
|
||||
*/
|
||||
string getStringValue (const string &relative_path,
|
||||
string defaultValue = "") const;
|
||||
const char * getStringValue (const char * relative_path,
|
||||
const char * defaultValue = "") const;
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as a bool.
|
||||
*/
|
||||
bool setBoolValue (const string &relative_path, bool value);
|
||||
bool setBoolValue (const char * relative_path, bool value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as an int.
|
||||
*/
|
||||
bool setIntValue (const string &relative_path, int value);
|
||||
bool setIntValue (const char * relative_path, int value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as a long int.
|
||||
*/
|
||||
bool setLongValue (const string &relative_path, long value);
|
||||
bool setLongValue (const char * relative_path, long value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as a float.
|
||||
*/
|
||||
bool setFloatValue (const string &relative_path, float value);
|
||||
bool setFloatValue (const char * relative_path, float value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as a double.
|
||||
*/
|
||||
bool setDoubleValue (const string &relative_path, double value);
|
||||
bool setDoubleValue (const char * relative_path, double value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value as a string.
|
||||
*/
|
||||
bool setStringValue (const string &relative_path, string value);
|
||||
bool setStringValue (const char * relative_path, const char * value);
|
||||
|
||||
|
||||
/**
|
||||
* Set another node's value with no specified type.
|
||||
*/
|
||||
bool setUnspecifiedValue (const string &relative_path, string value);
|
||||
bool setUnspecifiedValue (const char * relative_path, const char * value);
|
||||
|
||||
|
||||
/**
|
||||
* Test whether another node is bound to an external data source.
|
||||
*/
|
||||
bool isTied (const string &relative_path) const;
|
||||
bool isTied (const char * relative_path) const;
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external bool source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<bool> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<bool> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external int source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<int> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<int> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external long int source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<long> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<long> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external float source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<float> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<float> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external double source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<double> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<double> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind another node to an external string source.
|
||||
*/
|
||||
bool tie (const string &relative_path, const SGRawValue<string> &rawValue,
|
||||
bool tie (const char * relative_path, const SGRawValue<const char *> &rawValue,
|
||||
bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Unbind another node from any external data source.
|
||||
*/
|
||||
bool untie (const string &relative_path);
|
||||
bool untie (const char * relative_path);
|
||||
|
||||
|
||||
/**
|
||||
* Add a change listener to the property.
|
||||
*/
|
||||
void addChangeListener (SGPropertyChangeListener * listener);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a change listener from the property.
|
||||
*/
|
||||
void removeChangeListener (SGPropertyChangeListener * listener);
|
||||
|
||||
|
||||
/**
|
||||
* Fire a value change event to all listeners.
|
||||
*/
|
||||
void fireValueChanged ();
|
||||
|
||||
|
||||
/**
|
||||
* Fire a child-added event to all listeners.
|
||||
*/
|
||||
void fireChildAdded (SGPropertyNode * child);
|
||||
|
||||
|
||||
/**
|
||||
* Fire a child-removed event to all listeners.
|
||||
*/
|
||||
void fireChildRemoved (SGPropertyNode * child);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void fireValueChanged (SGPropertyNode * node);
|
||||
void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child);
|
||||
void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child);
|
||||
|
||||
/**
|
||||
* Protected constructor for making new nodes on demand.
|
||||
*/
|
||||
SGPropertyNode (const string &name, int index, SGPropertyNode * parent);
|
||||
SGPropertyNode (const char * name, int index, SGPropertyNode * parent);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Get the raw value
|
||||
bool get_bool () const;
|
||||
int get_int () const;
|
||||
long get_long () const;
|
||||
float get_float () const;
|
||||
double get_double () const;
|
||||
const char * get_string () const;
|
||||
|
||||
// Set the raw value
|
||||
bool set_bool (bool value);
|
||||
bool set_int (int value);
|
||||
bool set_long (long value);
|
||||
bool set_float (float value);
|
||||
bool set_double (double value);
|
||||
bool set_string (const char * value);
|
||||
|
||||
|
||||
/**
|
||||
* Clear any existing value and set the type to NONE.
|
||||
@@ -1070,29 +1214,50 @@ private:
|
||||
/**
|
||||
* Get the value as a string.
|
||||
*/
|
||||
string get_string () const;
|
||||
const char * make_string () const;
|
||||
|
||||
|
||||
/**
|
||||
* Trace a read access.
|
||||
*/
|
||||
void trace_read (Type accessType) const;
|
||||
void trace_read () const;
|
||||
|
||||
|
||||
/**
|
||||
* Trace a write access.
|
||||
*/
|
||||
void trace_write (Type accessType) const;
|
||||
void trace_write () const;
|
||||
|
||||
string _name;
|
||||
|
||||
/**
|
||||
* Increment reference counter
|
||||
*/
|
||||
void incrementRef();
|
||||
|
||||
/**
|
||||
* Decrement reference counter
|
||||
*/
|
||||
int decrementRef();
|
||||
|
||||
friend class SGPropertyNode_ptr;
|
||||
|
||||
|
||||
mutable char _buffer[MAX_STRING_LEN+1];
|
||||
|
||||
class hash_table;
|
||||
|
||||
char * _name;
|
||||
mutable char * _display_name;
|
||||
int _index;
|
||||
SGPropertyNode * _parent;
|
||||
vector<SGPropertyNode *> _children;
|
||||
typedef map<const string,SGPropertyNode *> cache_map;
|
||||
cache_map * _path_cache;
|
||||
vector<SGPropertyNode_ptr> _children;
|
||||
vector<SGPropertyNode_ptr> _removedChildren;
|
||||
mutable char * _path;
|
||||
hash_table * _path_cache;
|
||||
Type _type;
|
||||
bool _tied;
|
||||
int _attr;
|
||||
int _count;
|
||||
|
||||
// The right kind of pointer...
|
||||
union {
|
||||
@@ -1102,49 +1267,72 @@ private:
|
||||
SGRawValue<long> * long_val;
|
||||
SGRawValue<float> * float_val;
|
||||
SGRawValue<double> * double_val;
|
||||
SGRawValue<string> * string_val;
|
||||
SGRawValue<const char *> * string_val;
|
||||
} _value;
|
||||
|
||||
union {
|
||||
bool bool_val;
|
||||
int int_val;
|
||||
long long_val;
|
||||
float float_val;
|
||||
double double_val;
|
||||
char * string_val;
|
||||
} _local_val;
|
||||
|
||||
};
|
||||
vector <SGPropertyChangeListener *> * _listeners;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// I/O functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* A very simple hash table with no remove functionality.
|
||||
*/
|
||||
class hash_table {
|
||||
public:
|
||||
|
||||
/**
|
||||
* An entry in a bucket in a hash table.
|
||||
*/
|
||||
class entry {
|
||||
public:
|
||||
entry ();
|
||||
virtual ~entry ();
|
||||
virtual const char * get_key () { return _key; }
|
||||
virtual void set_key (const char * key);
|
||||
virtual SGPropertyNode * get_value () { return _value; }
|
||||
virtual void set_value (SGPropertyNode * value);
|
||||
private:
|
||||
char * _key;
|
||||
SGPropertyNode * _value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from an XML input stream.
|
||||
*/
|
||||
void readProperties (istream &input, SGPropertyNode * start_node,
|
||||
const string &base = "");
|
||||
/**
|
||||
* A bucket in a hash table.
|
||||
*/
|
||||
class bucket {
|
||||
public:
|
||||
bucket ();
|
||||
virtual ~bucket ();
|
||||
virtual entry * get_entry (const char * key, bool create = false);
|
||||
private:
|
||||
int _length;
|
||||
entry ** _entries;
|
||||
};
|
||||
|
||||
friend class bucket;
|
||||
|
||||
/**
|
||||
* Read properties from an XML file.
|
||||
*/
|
||||
void readProperties (const string &file, SGPropertyNode * start_node);
|
||||
hash_table ();
|
||||
virtual ~hash_table ();
|
||||
virtual SGPropertyNode * get (const char * key);
|
||||
virtual void put (const char * key, SGPropertyNode * value);
|
||||
|
||||
private:
|
||||
unsigned int hashcode (const char * key);
|
||||
unsigned int _data_length;
|
||||
bucket ** _data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write properties to an XML output stream.
|
||||
*/
|
||||
void writeProperties (ostream &output, const SGPropertyNode * start_node);
|
||||
|
||||
|
||||
/**
|
||||
* Write properties to an XML file.
|
||||
*/
|
||||
void writeProperties (const string &file, const SGPropertyNode * start_node);
|
||||
|
||||
|
||||
/**
|
||||
* Copy properties from one node to another.
|
||||
*/
|
||||
bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
|
||||
|
||||
};
|
||||
|
||||
#endif // __PROPS_HXX
|
||||
|
||||
|
||||
+33
-16
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "sg_path.hxx"
|
||||
#include "props.hxx"
|
||||
#include "props_io.hxx"
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
@@ -139,6 +140,7 @@ void
|
||||
PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
{
|
||||
State &st = state();
|
||||
const char * attval;
|
||||
|
||||
if (_level == 0) {
|
||||
if (string(name) != (string)"PropertyList") {
|
||||
@@ -147,12 +149,23 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
message += "; expected PropertyList";
|
||||
throw sg_io_exception(message, "SimGear Property Reader");
|
||||
}
|
||||
|
||||
// Check for an include.
|
||||
attval = atts.getValue("include");
|
||||
if (attval != 0) {
|
||||
SGPath path(SGPath(_base).dir());
|
||||
path.append(attval);
|
||||
try {
|
||||
readProperties(path.str(), _root);
|
||||
} catch (sg_io_exception &e) {
|
||||
setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
push_state(_root, "", DEFAULT_MODE);
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
const char * attval;
|
||||
// Get the index.
|
||||
attval = atts.getValue("n");
|
||||
int index = 0;
|
||||
@@ -234,9 +247,9 @@ PropsVisitor::endElement (const char * name)
|
||||
} else if (st.type == "double") {
|
||||
ret = st.node->setDoubleValue(strtod(_data.c_str(), 0));
|
||||
} else if (st.type == "string") {
|
||||
ret = st.node->setStringValue(_data);
|
||||
ret = st.node->setStringValue(_data.c_str());
|
||||
} else if (st.type == "unspecified") {
|
||||
ret = st.node->setUnspecifiedValue(_data);
|
||||
ret = st.node->setUnspecifiedValue(_data.c_str());
|
||||
} else {
|
||||
string message = "Unrecognized data type '";
|
||||
message += st.type;
|
||||
@@ -343,6 +356,9 @@ getTypeName (SGPropertyNode::Type type)
|
||||
return "double";
|
||||
case SGPropertyNode::STRING:
|
||||
return "string";
|
||||
case SGPropertyNode::ALIAS:
|
||||
case SGPropertyNode::NONE:
|
||||
return "unspecified";
|
||||
}
|
||||
|
||||
// keep the compiler from squawking
|
||||
@@ -425,21 +441,21 @@ isArchivable (const SGPropertyNode * node)
|
||||
|
||||
|
||||
static bool
|
||||
writeNode (ostream &output, const SGPropertyNode * node, int indent)
|
||||
writeNode (ostream &output, const SGPropertyNode * node,
|
||||
bool write_all, int indent)
|
||||
{
|
||||
// Don't write the node or any of
|
||||
// its descendants unless it is
|
||||
// allowed to be archived.
|
||||
if (!isArchivable(node))
|
||||
if (!write_all && !isArchivable(node))
|
||||
return true; // Everything's OK, but we won't write.
|
||||
|
||||
const string &name = node->getName();
|
||||
int index = node->getIndex();
|
||||
const string name = node->getName();
|
||||
int nChildren = node->nChildren();
|
||||
|
||||
// If there is a literal value,
|
||||
// write it first.
|
||||
if (node->hasValue() && node->getAttribute(SGPropertyNode::ARCHIVE)) {
|
||||
if (node->hasValue() && (write_all || node->getAttribute(SGPropertyNode::ARCHIVE))) {
|
||||
doIndent(output, indent);
|
||||
output << '<' << name;
|
||||
writeAtts(output, node);
|
||||
@@ -455,15 +471,14 @@ writeNode (ostream &output, const SGPropertyNode * node, int indent)
|
||||
}
|
||||
}
|
||||
|
||||
// If there are children, write them
|
||||
// next.
|
||||
// If there are children, write them next.
|
||||
if (nChildren > 0 || node->isAlias()) {
|
||||
doIndent(output, indent);
|
||||
output << '<' << name;
|
||||
writeAtts(output, node);
|
||||
output << '>' << endl;
|
||||
for (int i = 0; i < nChildren; i++)
|
||||
writeNode(output, node->getChild(i), indent + INDENT_STEP);
|
||||
writeNode(output, node->getChild(i), write_all, indent + INDENT_STEP);
|
||||
doIndent(output, indent);
|
||||
output << "</" << name << '>' << endl;
|
||||
}
|
||||
@@ -473,7 +488,8 @@ writeNode (ostream &output, const SGPropertyNode * node, int indent)
|
||||
|
||||
|
||||
void
|
||||
writeProperties (ostream &output, const SGPropertyNode * start_node)
|
||||
writeProperties (ostream &output, const SGPropertyNode * start_node,
|
||||
bool write_all)
|
||||
{
|
||||
int nChildren = start_node->nChildren();
|
||||
|
||||
@@ -481,7 +497,7 @@ writeProperties (ostream &output, const SGPropertyNode * start_node)
|
||||
output << "<PropertyList>" << endl;
|
||||
|
||||
for (int i = 0; i < nChildren; i++) {
|
||||
writeNode(output, start_node->getChild(i), INDENT_STEP);
|
||||
writeNode(output, start_node->getChild(i), write_all, INDENT_STEP);
|
||||
}
|
||||
|
||||
output << "</PropertyList>" << endl;
|
||||
@@ -489,11 +505,12 @@ writeProperties (ostream &output, const SGPropertyNode * start_node)
|
||||
|
||||
|
||||
void
|
||||
writeProperties (const string &file, const SGPropertyNode * start_node)
|
||||
writeProperties (const string &file, const SGPropertyNode * start_node,
|
||||
bool write_all)
|
||||
{
|
||||
ofstream output(file.c_str());
|
||||
if (output.good()) {
|
||||
writeProperties(output, start_node);
|
||||
writeProperties(output, start_node, write_all);
|
||||
} else {
|
||||
throw sg_io_exception("Cannot open file", sg_location(file));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* \file props_io.hxx
|
||||
* Interface definition for property list io.
|
||||
* Started Fall 2000 by David Megginson, david@megginson.com
|
||||
* This code is released into the Public Domain.
|
||||
*
|
||||
* See props.html for documentation [replace with URL when available].
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __PROPS_IO_HXX
|
||||
#define __PROPS_IO_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/misc/props.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(istream);
|
||||
SG_USING_STD(ostream);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read properties from an XML input stream.
|
||||
*/
|
||||
void readProperties (istream &input, SGPropertyNode * start_node,
|
||||
const string &base = "");
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from an XML file.
|
||||
*/
|
||||
void readProperties (const string &file, SGPropertyNode * start_node);
|
||||
|
||||
|
||||
/**
|
||||
* Write properties to an XML output stream.
|
||||
*/
|
||||
void writeProperties (ostream &output, const SGPropertyNode * start_node,
|
||||
bool write_all = false);
|
||||
|
||||
|
||||
/**
|
||||
* Write properties to an XML file.
|
||||
*/
|
||||
void writeProperties (const string &file, const SGPropertyNode * start_node,
|
||||
bool write_all = false);
|
||||
|
||||
|
||||
/**
|
||||
* Copy properties from one node to another.
|
||||
*/
|
||||
bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out);
|
||||
|
||||
|
||||
#endif // __PROPS_IO_HXX
|
||||
|
||||
// end of props_io.hxx
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include "props.hxx"
|
||||
#include "props_io.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
@@ -52,7 +53,7 @@ static double getNum (int index) { return 1.0 / index; }
|
||||
static void
|
||||
show_values (const SGPropertyNode * node)
|
||||
{
|
||||
cout << "Bool: " << node->getBoolValue() << endl;
|
||||
cout << "Bool: " << (node->getBoolValue() ? "true" : "false") << endl;
|
||||
cout << "Int: " << node->getIntValue() << endl;
|
||||
cout << "Float: " << node->getFloatValue() << endl;
|
||||
cout << "Double: " << node->getDoubleValue() << endl;
|
||||
@@ -274,7 +275,7 @@ test_value ()
|
||||
static void
|
||||
dump_node (const SGPropertyNode * node)
|
||||
{
|
||||
writeProperties(cout, node);
|
||||
writeProperties(cout, node, true);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -312,7 +313,7 @@ test_property_nodes ()
|
||||
cout << endl;
|
||||
|
||||
cout << "Looking for all /hack[0]/bar children" << endl;
|
||||
vector<SGPropertyNode *> bar = child->getChildren("bar");
|
||||
vector<SGPropertyNode_ptr> bar = child->getChildren("bar");
|
||||
cout << "There are " << bar.size() << " matches" << endl;
|
||||
for (int i = 0; i < (int)bar.size(); i++)
|
||||
cout << bar[i]->getName() << '[' << bar[i]->getIndex() << ']' << endl;
|
||||
@@ -332,11 +333,15 @@ int main (int ac, char ** av)
|
||||
test_property_nodes();
|
||||
|
||||
for (int i = 1; i < ac; i++) {
|
||||
cout << "Reading " << av[i] << endl;
|
||||
SGPropertyNode root;
|
||||
readProperties(av[i], &root);
|
||||
writeProperties(cout, &root);
|
||||
cout << endl;
|
||||
try {
|
||||
cout << "Reading " << av[i] << endl;
|
||||
SGPropertyNode root;
|
||||
readProperties(av[i], &root);
|
||||
writeProperties(cout, &root, true);
|
||||
cout << endl;
|
||||
} catch (string &message) {
|
||||
cout << "Aborted with " << message << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+153
-38
@@ -1,8 +1,8 @@
|
||||
// String utilities.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
// Written by Bernie Bright, started 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@bigpond.net.au
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
@@ -21,48 +21,163 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <ctype.h>
|
||||
#include "strutils.hxx"
|
||||
|
||||
const string whitespace = " \n\r\t";
|
||||
namespace simgear {
|
||||
namespace strutils {
|
||||
|
||||
//
|
||||
string
|
||||
trimleft( const string& s, const string& trimmings )
|
||||
{
|
||||
string result;
|
||||
string::size_type pos = s.find_first_not_of( trimmings );
|
||||
if ( pos != string::npos )
|
||||
{
|
||||
result.assign( s.substr( pos ) );
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static vector<string>
|
||||
split_whitespace( const string& str, int maxsplit )
|
||||
{
|
||||
vector<string> result;
|
||||
string::size_type len = str.length();
|
||||
string::size_type i = 0;
|
||||
string::size_type j;
|
||||
int countsplit = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
while (i < len)
|
||||
{
|
||||
while (i < len && isspace(str[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
//
|
||||
string
|
||||
trimright( const string& s, const string& trimmings )
|
||||
{
|
||||
string result;
|
||||
j = i;
|
||||
|
||||
string::size_type pos = s.find_last_not_of( trimmings );
|
||||
if ( pos == string::npos )
|
||||
{
|
||||
// Not found, return the original string.
|
||||
result = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.assign( s.substr( 0, pos+1 ) );
|
||||
}
|
||||
while (i < len && !isspace(str[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
if (j < i)
|
||||
{
|
||||
result.push_back( str.substr(j, i-j) );
|
||||
++countsplit;
|
||||
while (i < len && isspace(str[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
//
|
||||
string
|
||||
trim( const string& s, const string& trimmings )
|
||||
{
|
||||
return trimright( trimleft( s, trimmings ), trimmings );
|
||||
}
|
||||
if (maxsplit && (countsplit >= maxsplit) && i < len)
|
||||
{
|
||||
result.push_back( str.substr( i, len-i ) );
|
||||
i = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
vector<string>
|
||||
split( const string& str, const char* sep, int maxsplit )
|
||||
{
|
||||
if (sep == 0)
|
||||
return split_whitespace( str, maxsplit );
|
||||
|
||||
vector<string> result;
|
||||
int n = strlen( sep );
|
||||
if (n == 0)
|
||||
{
|
||||
// Error: empty separator string
|
||||
return result;
|
||||
}
|
||||
const char* s = str.c_str();
|
||||
string::size_type len = str.length();
|
||||
string::size_type i = 0;
|
||||
string::size_type j = 0;
|
||||
int splitcount = 0;
|
||||
|
||||
while (i+n <= len)
|
||||
{
|
||||
if (s[i] == sep[0] && (n == 1 || memcmp(s+i, sep, n) == 0))
|
||||
{
|
||||
result.push_back( str.substr(j,i-j) );
|
||||
i = j = i + n;
|
||||
++splitcount;
|
||||
if (maxsplit && (splitcount >= maxsplit))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back( str.substr(j,len-j) );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lstrip(), rstrip() and strip() functions are implemented
|
||||
* in do_strip() which uses an additional parameter to indicate what
|
||||
* type of strip should occur.
|
||||
*/
|
||||
const int LEFTSTRIP = 0;
|
||||
const int RIGHTSTRIP = 1;
|
||||
const int BOTHSTRIP = 2;
|
||||
|
||||
static string
|
||||
do_strip( const string& s, int striptype )
|
||||
{
|
||||
// if (s.empty())
|
||||
// return s;
|
||||
|
||||
string::size_type len = s.length();
|
||||
string::size_type i = 0;
|
||||
if (striptype != RIGHTSTRIP)
|
||||
{
|
||||
while (i < len && isspace(s[i]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
string::size_type j = len;
|
||||
if (striptype != LEFTSTRIP)
|
||||
{
|
||||
do
|
||||
{
|
||||
--j;
|
||||
}
|
||||
while (j >= 1 && isspace(s[j]));
|
||||
++j;
|
||||
}
|
||||
|
||||
if (i == 0 && j == len)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
return s.substr( i, j - i );
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
lstrip( const string& s )
|
||||
{
|
||||
return do_strip( s, LEFTSTRIP );
|
||||
}
|
||||
|
||||
string
|
||||
rstrip( const string& s )
|
||||
{
|
||||
return do_strip( s, RIGHTSTRIP );
|
||||
}
|
||||
|
||||
string
|
||||
strip( const string& s )
|
||||
{
|
||||
return do_strip( s, BOTHSTRIP );
|
||||
}
|
||||
|
||||
} // end namespace strutils
|
||||
} // end namespace simgear
|
||||
|
||||
+48
-23
@@ -3,9 +3,9 @@
|
||||
* String utilities.
|
||||
*/
|
||||
|
||||
// Written by Bernie Bright, 1998
|
||||
// Written by Bernie Bright, started 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@bigpond.net.au
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <vector>
|
||||
SG_USING_STD(vector);
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cstdlib>
|
||||
#else
|
||||
@@ -40,32 +43,54 @@
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
namespace simgear {
|
||||
namespace strutils {
|
||||
|
||||
/** Default characters to remove. */
|
||||
extern const string whitespace;
|
||||
// /**
|
||||
// * atof() wrapper for "string" type
|
||||
// */
|
||||
// inline double
|
||||
// atof( const string& str )
|
||||
// {
|
||||
// return ::atof( str.c_str() );
|
||||
// }
|
||||
|
||||
/** Returns a string with trailing characters removed. */
|
||||
string trimleft( const string& s, const string& trimmings = whitespace );
|
||||
// /**
|
||||
// * atoi() wrapper for "string" type
|
||||
// */
|
||||
// inline int
|
||||
// atoi( const string& str )
|
||||
// {
|
||||
// return ::atoi( str.c_str() );
|
||||
// }
|
||||
|
||||
/** Returns a string with leading characters removed. */
|
||||
string trimright( const string& s, const string& trimmings = whitespace );
|
||||
/**
|
||||
* Strip leading and/or trailing whitespace from s.
|
||||
* @param s String to strip.
|
||||
* @return The stripped string.
|
||||
*/
|
||||
string lstrip( const string& s );
|
||||
string rstrip( const string& s );
|
||||
string strip( const string& s );
|
||||
|
||||
/** Returns a string with leading and trailing characters removed. */
|
||||
string trim( const string& s, const string& trimmings = whitespace );
|
||||
/**
|
||||
* Split a string into a words using 'sep' as the delimiter string.
|
||||
* Produces a result similar to the perl and python functions of the
|
||||
* same name.
|
||||
*
|
||||
* @param s The string to split into words,
|
||||
* @param sep Word delimiters. If not specified then any whitespace is a separator,
|
||||
* @param maxsplit If given, splits at no more than maxsplit places,
|
||||
* resulting in at most maxsplit+1 words.
|
||||
* @return Array of words.
|
||||
*/
|
||||
vector<string>
|
||||
split( const string& s,
|
||||
const char* sep = 0,
|
||||
int maxsplit = 0 );
|
||||
|
||||
/** atof() wrapper for "string" type */
|
||||
inline double
|
||||
atof( const string& str )
|
||||
{
|
||||
return ::atof( str.c_str() );
|
||||
}
|
||||
|
||||
/** atoi() wrapper for "string" type */
|
||||
inline int
|
||||
atoi( const string& str )
|
||||
{
|
||||
return ::atoi( str.c_str() );
|
||||
}
|
||||
} // end namespace strutils
|
||||
} // end namespace simgear
|
||||
|
||||
#endif // STRUTILS_H
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@ libsgroute_a_SOURCES = \
|
||||
route.cxx \
|
||||
waypoint.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS = waytest routetest
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
includedir = @includedir@/sky
|
||||
|
||||
SUBDIRS = clouds3d
|
||||
|
||||
lib_LIBRARIES = libsgsky.a
|
||||
|
||||
include_HEADERS = \
|
||||
@@ -20,8 +22,4 @@ libsgsky_a_SOURCES = \
|
||||
sphere.cxx \
|
||||
stars.cxx
|
||||
|
||||
if OLD_AUTOMAKE
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
else
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
endif
|
||||
@@ -28,35 +28,135 @@
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include "cloud.hxx"
|
||||
|
||||
ssgSimpleState *
|
||||
SGCloudLayer::layer_states[SGCloudLayer::SG_MAX_CLOUD_TYPES];
|
||||
|
||||
|
||||
// Constructor
|
||||
SGCloudLayer::SGCloudLayer( void ) {
|
||||
SGCloudLayer::SGCloudLayer( const string &tex_path )
|
||||
: layer_root(new ssgRoot),
|
||||
layer_transform(new ssgTransform),
|
||||
layer(0),
|
||||
texture_path(tex_path),
|
||||
layer_span(0),
|
||||
layer_asl(0),
|
||||
layer_thickness(0),
|
||||
layer_transition(0),
|
||||
layer_type(SG_CLOUD_CLEAR)
|
||||
{
|
||||
layer_root->addKid(layer_transform);
|
||||
rebuild();
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
SGCloudLayer::~SGCloudLayer( void ) {
|
||||
SGCloudLayer::~SGCloudLayer()
|
||||
{
|
||||
delete layer_root; // deletes layer_transform and layer as well
|
||||
}
|
||||
|
||||
float
|
||||
SGCloudLayer::getSpan_m () const
|
||||
{
|
||||
return layer_span;
|
||||
}
|
||||
|
||||
void
|
||||
SGCloudLayer::setSpan_m (float span_m)
|
||||
{
|
||||
if (span_m != layer_span) {
|
||||
layer_span = span_m;
|
||||
rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
SGCloudLayer::getElevation_m () const
|
||||
{
|
||||
return layer_asl;
|
||||
}
|
||||
|
||||
void
|
||||
SGCloudLayer::setElevation_m (float elevation_m)
|
||||
{
|
||||
layer_asl = elevation_m;
|
||||
}
|
||||
|
||||
float
|
||||
SGCloudLayer::getThickness_m () const
|
||||
{
|
||||
return layer_thickness;
|
||||
}
|
||||
|
||||
void
|
||||
SGCloudLayer::setThickness_m (float thickness_m)
|
||||
{
|
||||
layer_thickness = thickness_m;
|
||||
}
|
||||
|
||||
float
|
||||
SGCloudLayer::getTransition_m () const
|
||||
{
|
||||
return layer_transition;
|
||||
}
|
||||
|
||||
void
|
||||
SGCloudLayer::setTransition_m (float transition_m)
|
||||
{
|
||||
layer_transition = transition_m;
|
||||
}
|
||||
|
||||
SGCloudLayer::Type
|
||||
SGCloudLayer::getType () const
|
||||
{
|
||||
return layer_type;
|
||||
}
|
||||
|
||||
void
|
||||
SGCloudLayer::setType (Type type)
|
||||
{
|
||||
if (type != layer_type) {
|
||||
layer_type = type;
|
||||
rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build the cloud object
|
||||
void SGCloudLayer::build( double s, double asl, double thickness,
|
||||
double transition, ssgSimpleState *state )
|
||||
void
|
||||
SGCloudLayer::rebuild()
|
||||
{
|
||||
// Initialize states and sizes if necessary.
|
||||
if (layer_states[0] == 0) {
|
||||
SGPath cloud_path;
|
||||
|
||||
cloud_path.set(texture_path.str());
|
||||
cloud_path.append("overcast.rgb");
|
||||
layer_states[SG_CLOUD_OVERCAST] = SGCloudMakeState(cloud_path.str());
|
||||
|
||||
cloud_path.set(texture_path.str());
|
||||
cloud_path.append("mostlycloudy.rgba");
|
||||
layer_states[SG_CLOUD_MOSTLY_CLOUDY] =
|
||||
SGCloudMakeState(cloud_path.str());
|
||||
|
||||
cloud_path.set(texture_path.str());
|
||||
cloud_path.append("mostlysunny.rgba");
|
||||
layer_states[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState(cloud_path.str());
|
||||
|
||||
cloud_path.set(texture_path.str());
|
||||
cloud_path.append("cirrus.rgba");
|
||||
layer_states[SG_CLOUD_CIRRUS] = SGCloudMakeState(cloud_path.str());
|
||||
|
||||
layer_states[SG_CLOUD_CLEAR] = 0;
|
||||
}
|
||||
|
||||
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 );
|
||||
@@ -67,7 +167,7 @@ void SGCloudLayer::build( double s, double asl, double thickness,
|
||||
sgVec2 tc;
|
||||
sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
sgSetVec3( vertex, -size, -size, 0.0f );
|
||||
sgSetVec3( vertex, -layer_span, -layer_span, 0.0f );
|
||||
sgVec2 base;
|
||||
sgSetVec2( base, sg_random(), sg_random() );
|
||||
sgSetVec2( tc, base[0], base[1] );
|
||||
@@ -75,40 +175,35 @@ void SGCloudLayer::build( double s, double asl, double thickness,
|
||||
vl->add( vertex );
|
||||
tl->add( tc );
|
||||
|
||||
sgSetVec3( vertex, size, -size, 0.0f );
|
||||
sgSetVec2( tc, base[0] + size / scale, base[1] );
|
||||
sgSetVec3( vertex, layer_span, -layer_span, 0.0f );
|
||||
sgSetVec2( tc, base[0] + layer_span / 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 );
|
||||
sgSetVec3( vertex, -layer_span, layer_span, 0.0f );
|
||||
sgSetVec2( tc, base[0], base[1] + layer_span / 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 );
|
||||
sgSetVec3( vertex, layer_span, layer_span, 0.0f );
|
||||
sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / 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 );
|
||||
if (layer != 0)
|
||||
layer_transform->removeKid(layer); // automatic delete
|
||||
layer = new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl );
|
||||
if (layer_states[layer_type] != 0)
|
||||
layer->setState( layer_states[layer_type] );
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +309,7 @@ bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
|
||||
base[0] -= (int)base[0];
|
||||
} else {
|
||||
base[0] = 0.0;
|
||||
SG_LOG(SG_ASTRO, SG_ALERT,
|
||||
SG_LOG(SG_ASTRO, SG_DEBUG,
|
||||
"Error: base = " << base[0] << "," << base[1]);
|
||||
}
|
||||
|
||||
@@ -234,13 +329,13 @@ bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
|
||||
// cout << "base = " << base[0] << "," << base[1] << endl;
|
||||
|
||||
tc = tl->get( 1 );
|
||||
sgSetVec2( tc, base[0] + size / scale, base[1] );
|
||||
sgSetVec2( tc, base[0] + layer_span / scale, base[1] );
|
||||
|
||||
tc = tl->get( 2 );
|
||||
sgSetVec2( tc, base[0], base[1] + size / scale );
|
||||
sgSetVec2( tc, base[0], base[1] + layer_span / scale );
|
||||
|
||||
tc = tl->get( 3 );
|
||||
sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
|
||||
sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale );
|
||||
|
||||
last_lon = lon;
|
||||
last_lat = lat;
|
||||
@@ -251,7 +346,8 @@ bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
|
||||
|
||||
|
||||
void SGCloudLayer::draw() {
|
||||
ssgCullAndDraw( layer_root );
|
||||
if (layer_type != SG_CLOUD_CLEAR)
|
||||
ssgCullAndDraw( layer_root );
|
||||
}
|
||||
|
||||
|
||||
@@ -272,5 +368,9 @@ ssgSimpleState *SGCloudMakeState( const string &path ) {
|
||||
state->enable( GL_ALPHA_TEST );
|
||||
state->setAlphaClamp( 0.01 );
|
||||
|
||||
// ref() the state so it doesn't get deleted if the last layer of
|
||||
// it's type is deleted.
|
||||
state->ref();
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -33,53 +33,42 @@
|
||||
SG_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,
|
||||
SG_CLOUD_MOSTLY_SUNNY,
|
||||
SG_CLOUD_CIRRUS
|
||||
};
|
||||
|
||||
|
||||
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 );
|
||||
enum Type {
|
||||
SG_CLOUD_OVERCAST = 0,
|
||||
SG_CLOUD_MOSTLY_CLOUDY,
|
||||
SG_CLOUD_MOSTLY_SUNNY,
|
||||
SG_CLOUD_CIRRUS,
|
||||
SG_CLOUD_CLEAR,
|
||||
SG_MAX_CLOUD_TYPES
|
||||
};
|
||||
|
||||
// Constructors
|
||||
SGCloudLayer( const string &tex_path );
|
||||
|
||||
// Destructor
|
||||
~SGCloudLayer( void );
|
||||
|
||||
float getSpan_m () const;
|
||||
void setSpan_m (float span_m);
|
||||
|
||||
float getElevation_m () const;
|
||||
void setElevation_m (float elevation_m);
|
||||
|
||||
float getThickness_m () const;
|
||||
void setThickness_m (float thickness_m);
|
||||
|
||||
float getTransition_m () const;
|
||||
void setTransition_m (float transition_m);
|
||||
|
||||
Type getType () const;
|
||||
void setType (Type type);
|
||||
|
||||
// build the cloud object
|
||||
void build( double size, double asl, double thickness,
|
||||
double transition, ssgSimpleState *state );
|
||||
void rebuild();
|
||||
|
||||
// repaint the cloud colors based on current value of sun_angle,
|
||||
// sky, and fog colors. This updates the color arrays for
|
||||
@@ -101,9 +90,34 @@ public:
|
||||
// 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; }
|
||||
private:
|
||||
|
||||
static ssgSimpleState *layer_states[SG_MAX_CLOUD_TYPES];
|
||||
static int layer_sizes[SG_MAX_CLOUD_TYPES];
|
||||
|
||||
ssgRoot *layer_root;
|
||||
ssgTransform *layer_transform;
|
||||
ssgLeaf * layer;
|
||||
|
||||
ssgColourArray *cl;
|
||||
ssgVertexArray *vl;
|
||||
ssgTexCoordArray *tl;
|
||||
|
||||
// height above sea level (meters)
|
||||
SGPath texture_path;
|
||||
float layer_span;
|
||||
float layer_asl;
|
||||
float layer_thickness;
|
||||
float layer_transition;
|
||||
Type layer_type;
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -0,0 +1,42 @@
|
||||
includedir = @includedir@/sky/clouds3d
|
||||
|
||||
# enable the following line once extgl.c get's added to the distro
|
||||
EXTRA_DIST = extgl.c extgl.h
|
||||
|
||||
if EXTGL_NEEDED
|
||||
EXTGL_SOURCE = extgl.c extgl.h
|
||||
else
|
||||
EXTGL_SOURCE =
|
||||
endif
|
||||
|
||||
lib_LIBRARIES = libsgclouds3d.a
|
||||
|
||||
include_HEADERS = \
|
||||
SkySceneLoader.hpp \
|
||||
SkyUtil.hpp
|
||||
|
||||
libsgclouds3d_a_SOURCES = \
|
||||
$(EXTGL_SOURCE) \
|
||||
vec3fv.cpp \
|
||||
mat16fv.cpp \
|
||||
tri.cpp \
|
||||
plane.cpp \
|
||||
camera.cpp \
|
||||
camutils.cpp \
|
||||
minmaxbox.cpp \
|
||||
SkyMinMaxBox.cpp \
|
||||
SkyLight.cpp \
|
||||
SkyMaterial.cpp \
|
||||
SkyTextureManager.cpp \
|
||||
SkyTextureState.cpp \
|
||||
SkyDynamicTextureManager.cpp \
|
||||
SkyRenderableInstanceCloud.cpp \
|
||||
SkyRenderableInstanceGroup.cpp \
|
||||
SkyCloud.cpp \
|
||||
SkyArchive.cpp \
|
||||
SkyUtil.cpp \
|
||||
SkyContext.cpp \
|
||||
SkySceneManager.cpp \
|
||||
SkySceneLoader.cpp
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
@@ -0,0 +1,19 @@
|
||||
//============================================================================
|
||||
// File : SkyAABBTree.hpp
|
||||
//
|
||||
// Author : Wesley Hunt
|
||||
//
|
||||
// Content : axis-aligned bounding box tree
|
||||
//
|
||||
//============================================================================
|
||||
#ifndef __SKYAABBTREE_HPP__
|
||||
#define __SKYAABBTREE_HPP__
|
||||
|
||||
#include "SkyBVTree.hpp"
|
||||
#include "SkyBVTreeSplitter.hpp"
|
||||
|
||||
template <class object>
|
||||
class SkyAABBTree : public SkyBVTree<object, SkyMinMaxBox, SkyAABBTreeSplitter<object> >
|
||||
{};
|
||||
|
||||
#endif //__SKYAABBTREE_HPP__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyArchive.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyArchive.hpp
|
||||
*
|
||||
* A hierarchical archive Class for storing data.
|
||||
*/
|
||||
#ifndef __SKYARCHIVE_HPP__
|
||||
#define __SKYARCHIVE_HPP__
|
||||
|
||||
// #pragma warning( disable : 4786 )
|
||||
|
||||
#include "vec2f.hpp"
|
||||
#include "vec3f.hpp"
|
||||
#include "vec4f.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
#include <map> // for std::multimap
|
||||
|
||||
//! Types supported by the archive system
|
||||
enum SkyArchiveTypeCode
|
||||
{
|
||||
BOOL_TYPE,
|
||||
INT8_TYPE,
|
||||
INT16_TYPE,
|
||||
INT32_TYPE,
|
||||
UINT8_TYPE,
|
||||
UINT16_TYPE,
|
||||
UINT32_TYPE,
|
||||
FLOAT32_TYPE,
|
||||
FLOAT64_TYPE,
|
||||
STRING_TYPE,
|
||||
VEC2F_TYPE,
|
||||
VEC3F_TYPE,
|
||||
VEC4F_TYPE,
|
||||
ARCHIVE_TYPE,
|
||||
ANY_TYPE,
|
||||
NULL_TYPE
|
||||
};
|
||||
|
||||
struct SkyArchiveEntry;
|
||||
|
||||
struct StringLessFunctor
|
||||
{
|
||||
bool operator() (const char* p1, const char* p2) const
|
||||
{
|
||||
return ::strcmp( p1, p2) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Class : SkyArchive
|
||||
//
|
||||
//! A simple hierarchical archive file useful for loading and saving data.
|
||||
//
|
||||
/*! SkyArchive bundles information so that an application can store,
|
||||
manipulate, and retrieve data in a storage-independent manner. Information
|
||||
stored in an SkyArchive file can be modified without breaking
|
||||
compatibility with the code that retrieves the data. In essence, it can be
|
||||
thought of as a very basic database mechanism.
|
||||
|
||||
A SkyArchive is simply a container. The class defines methods that allow
|
||||
you to put information in a SkyArchive, determine the information in a
|
||||
SkyArchive, and retrieve information from a SkyArchive. It's important
|
||||
to note that the SkyArchive is a recursive storage mechanism; a
|
||||
SkyArchive itself can hold one or more other SkyArchives.
|
||||
|
||||
Data are added to an archive in fields. The datum in a field is associated
|
||||
with a name, number of bytes, and a type code. The name can be anything you
|
||||
choose and is not required to be unique. The number of bytes must be accurate.
|
||||
The type code must be one of the SkyArchiveTypeCode enums. Several of the Add
|
||||
functions have been specialized for the common base types. It isn't necessary
|
||||
to provide the number of bytes when using the specialized functions, since it can be
|
||||
inferred from the type code.
|
||||
|
||||
The functions that retrieve fields from an archive are similar to the ones
|
||||
that add data, only their roles are reversed. As with the Add functions,
|
||||
there are several specialized functions for the common base types while
|
||||
custom information can be retrieved using the generic FindData function.
|
||||
|
||||
Querying the contents of an archive is provided through the GetInfo
|
||||
functions. These functions are important as they allow you to write
|
||||
code that can intelligently determine how to retrieve information at
|
||||
run-time: you no longer have to hardcode the order in which you retrieve
|
||||
data from your files.
|
||||
|
||||
archive data fields are held in using an STL multimap. The multimap key
|
||||
is a QString (field name) and the data is held in a SkyArchiveEntry
|
||||
structure (see SkyArchive.cpp for details of this structure).
|
||||
The fields are stored in alphabetical order based on the key names.
|
||||
*/
|
||||
class SkyArchive
|
||||
{
|
||||
public:
|
||||
//=========================================================================
|
||||
// Creation & Destruction
|
||||
//=========================================================================
|
||||
// Empty archive: no name, no data fields.
|
||||
SkyArchive();
|
||||
// Creates a named archive with no data fields.
|
||||
SkyArchive( const char* pName);
|
||||
// Deep copy the contents of one archive to another.
|
||||
SkyArchive( const SkyArchive& src);
|
||||
// Deep copy the contents of one archive to another.
|
||||
SkyArchive& operator=( const SkyArchive& src);
|
||||
|
||||
~SkyArchive();
|
||||
|
||||
//=========================================================================
|
||||
// Basic SkyArchive Information
|
||||
//=========================================================================
|
||||
// Returns true if the archive contains no data fields.
|
||||
bool IsEmpty() const;
|
||||
//! Returns the archive's name.
|
||||
const char* GetName() const { return _pName; };
|
||||
|
||||
//=========================================================================
|
||||
// Adding Content to SkyArchive
|
||||
//=========================================================================
|
||||
// Adds a new datafield to the archive.
|
||||
SKYRESULT AddData(const char* pName,
|
||||
SkyArchiveTypeCode eType,
|
||||
const void* pData,
|
||||
unsigned int iNumBytes,
|
||||
unsigned int iNumItems = 1);
|
||||
|
||||
SKYRESULT AddBool( const char* pName, bool aBool);
|
||||
SKYRESULT AddInt8( const char* pName, char anInt8);
|
||||
SKYRESULT AddInt16( const char* pName, short anInt16);
|
||||
SKYRESULT AddInt32( const char* pName, int anInt32);
|
||||
SKYRESULT AddUInt8( const char* pName, unsigned char anUInt8);
|
||||
SKYRESULT AddUInt16( const char* pName, unsigned short anUInt16);
|
||||
SKYRESULT AddUInt32( const char* pName, unsigned int anUInt32);
|
||||
SKYRESULT AddFloat32( const char* pName, float aFloat32);
|
||||
SKYRESULT AddFloat64( const char* pName, double aFloat64);
|
||||
SKYRESULT AddString( const char* pName, const char* pString);
|
||||
|
||||
SKYRESULT AddArchive( const SkyArchive& anArchive);
|
||||
|
||||
// Vector types (MJH:: only supports float versions for now!!!)
|
||||
SKYRESULT AddVec2f( const char* pName, const Vec2f& aPoint2f);
|
||||
SKYRESULT AddVec3f( const char* pName, const Vec3f& aPoint3f);
|
||||
SKYRESULT AddVec4f( const char* pName, const Vec4f& aPoint4f);
|
||||
|
||||
//=========================================================================
|
||||
// Retrieving Content from SkyArchive
|
||||
//=========================================================================
|
||||
// Retrieves the specified datafield the archive, if it exists.
|
||||
SKYRESULT FindData( const char* pName,
|
||||
SkyArchiveTypeCode eType,
|
||||
void** const pData,
|
||||
unsigned int* pNumBytes,
|
||||
unsigned int index = 0) const;
|
||||
|
||||
SKYRESULT FindBool( const char* pName, bool* pBool, unsigned int index = 0) const;
|
||||
SKYRESULT FindInt8( const char* pName, char* pInt8, unsigned int index = 0) const;
|
||||
SKYRESULT FindInt16( const char* pName, short* pInt16, unsigned int index = 0) const;
|
||||
SKYRESULT FindInt32( const char* pName, int* pInt32, unsigned int index = 0) const;
|
||||
SKYRESULT FindUInt8( const char* pName, unsigned char* pUInt8, unsigned int index = 0) const;
|
||||
SKYRESULT FindUInt16( const char* pName, unsigned short* pUInt16, unsigned int index = 0) const;
|
||||
SKYRESULT FindUInt32( const char* pName, unsigned int* pUInt32, unsigned int index = 0) const;
|
||||
SKYRESULT FindFloat32(const char* pName, float* pFloat32, unsigned int index = 0) const;
|
||||
SKYRESULT FindFloat64(const char* pName, double* pFloat64, unsigned int index = 0) const;
|
||||
SKYRESULT FindString( const char* pName, char** const pString, unsigned int index = 0) const;
|
||||
SKYRESULT FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index = 0) const;
|
||||
|
||||
SKYRESULT FindVec2f( const char* pName, Vec2f* pVec2f, unsigned int index = 0) const;
|
||||
SKYRESULT FindVec3f( const char* pName, Vec3f* pVec3f, unsigned int index = 0) const;
|
||||
SKYRESULT FindVec4f( const char* pName, Vec4f* pVec4f, unsigned int index = 0) const;
|
||||
|
||||
SKYRESULT AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index = 0) const;
|
||||
|
||||
//=========================================================================
|
||||
// Querying Contents of SkyArchive
|
||||
//=========================================================================
|
||||
// Computes the number of fields that contain the given name and type.
|
||||
SKYRESULT GetInfo(const char* pName,
|
||||
SkyArchiveTypeCode eType,
|
||||
unsigned int* pNumFound = NULL) const;
|
||||
|
||||
// Returns information about the key at the specified index.
|
||||
SKYRESULT GetInfo(unsigned int iNameIndex,
|
||||
char** pNameFound,
|
||||
SkyArchiveTypeCode* pTypeCode,
|
||||
unsigned int* pNumFound);
|
||||
|
||||
// Computes the number of unique key names in _dataTableable.
|
||||
unsigned int GetNumUniqueNames() const;
|
||||
|
||||
|
||||
// Remove the contents of the SkyArchive.
|
||||
SKYRESULT MakeEmpty();
|
||||
|
||||
// Loads the contents from a file.
|
||||
SKYRESULT Load(const char* pFileName);
|
||||
|
||||
// Commits the contents of a SkyArchive to file storage.
|
||||
SKYRESULT Save(const char* pFileName) const;
|
||||
|
||||
private:
|
||||
|
||||
char* _pName; // this archive's name
|
||||
|
||||
//=========================================================================
|
||||
// Data storage
|
||||
//=========================================================================
|
||||
typedef std::multimap<char*, SkyArchiveEntry*, StringLessFunctor> SkyArchiveMMap;
|
||||
typedef SkyArchiveMMap::const_iterator SkyMMapConstIter;
|
||||
typedef SkyArchiveMMap::iterator SkyMMapIter;
|
||||
|
||||
SkyArchiveMMap _dataTable; // this is where the data reside.
|
||||
|
||||
// Performs a deep-copy of one archive's archive_mmap_t to another.
|
||||
void _CopyDataTable( const SkyArchiveMMap& src);
|
||||
|
||||
// Locates an archive entry in _dataTable
|
||||
const SkyArchiveEntry* _FindEntry( const char* pName,
|
||||
unsigned int index,
|
||||
SkyArchiveTypeCode eType) const;
|
||||
|
||||
// Saves the archive to a file stream.
|
||||
SKYRESULT _Save(FILE* pDestFile) const;
|
||||
// Initializes the archive from a file stream.
|
||||
SKYRESULT _Load(FILE* pSrcFile);
|
||||
};
|
||||
|
||||
#endif //__SKYARCHIVE_HPP__
|
||||
@@ -0,0 +1,297 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyBVTree.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// Empyrean / SkyWorks : Copyright 2002 Mark J. Harris
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @file SkyBVTree.hpp
|
||||
*
|
||||
* This source was written by Wesley Hunt. Many thanks to him for providing it.
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
// SkyBVTree.hpp
|
||||
//
|
||||
// Author: Wesley Hunt (hunt@cs.unc.edu)
|
||||
// Date: 2000/12/19
|
||||
//-----------------------------------------------------------------------------
|
||||
// Overview
|
||||
// --------
|
||||
// declare an SkyBVTree with whatever object type and bounding volume type you
|
||||
// want. The hard part is to pass in a NodeSplitter class that determines how
|
||||
// to split a node up. See below for a description of its requirements.
|
||||
// Finally, use that tree like so:
|
||||
// * BeginTree()
|
||||
// * AddObject(Object, ObjectBV)
|
||||
// * ...
|
||||
// * EndTree()
|
||||
// < Do whatever you want with GetRoot() >
|
||||
// < Use GetLeftChild() and GetRightChild() to traverse the nodes >
|
||||
//
|
||||
// The class hierarchy is designed for a flexible, simple public interface.
|
||||
// This pushes some extra complexity into the class hierarchy, but there are two
|
||||
// main advantages to the final approach:
|
||||
// 1. There are no interface requirements for the Object and BoundingVolume
|
||||
// template parameters. This means you don't have to modify your existing
|
||||
// class interfaces to use them with the tree.
|
||||
// 2. All the dependent logic for dealing with the bounding volumes is pushed
|
||||
// into the NodeSplitter class. So there is one centralized location for
|
||||
// adapting your bounding volume classes to work with the tree. See the
|
||||
// description of the NodeSplitter template requirements for more details.
|
||||
//
|
||||
// Class Descriptions
|
||||
// ------------------
|
||||
//
|
||||
// SkyBaseBVTree
|
||||
// -------------
|
||||
// declares the node class that the tree holds. It exposes
|
||||
// the public functions of the nodes and defines protected accessors that
|
||||
// the derived tree class can use to manipulate nodes and build the tree.
|
||||
//
|
||||
// Node
|
||||
// ----
|
||||
// This is the class that gives access to the tree. You can access each
|
||||
// object and bounding volume owned by a node, along with that node's
|
||||
// children.
|
||||
//
|
||||
// NodeObject
|
||||
// ----------------
|
||||
// An aggregation of an object and its associated bounding volume.
|
||||
// Each node in the tree essentially owns an array of NodeObjects. This
|
||||
// array is passed to the NodeSplitter class to allow it to examine a
|
||||
// node's contained objects before making a decision on how to split the
|
||||
// node up.
|
||||
//
|
||||
// SkyBVTree
|
||||
// ---------
|
||||
// The main tree class. To use it, supply and object type, a bounding volume
|
||||
// type, and a NodeSplitter class that is used to split the nodes up during
|
||||
// tree construction.
|
||||
//
|
||||
// Template class requirements
|
||||
// ---------------------------
|
||||
//
|
||||
// Object
|
||||
// ------
|
||||
// None
|
||||
//
|
||||
// BoundingVolume
|
||||
// --------------
|
||||
// None
|
||||
//
|
||||
// NodeSplitter
|
||||
// ------------
|
||||
// This is the user-supplied class that decides how to split a node during
|
||||
// tree construction. It is given an array of NodeObjects that the node owns and
|
||||
// is responsible for determining the node's bounding volume as well as how to
|
||||
// split the node up into left and right children.
|
||||
// The required API is as follows:
|
||||
//
|
||||
// * a constructor that takes an array of NodeObject and an unsigned int giving
|
||||
// the size of the array. These are the objects owned by the node to be split.
|
||||
// * a method GetNodeBV() that returns the BoundingVolume of the node.
|
||||
// Typically this is the union of the bounding volumes of the objects owned
|
||||
// by the node.
|
||||
// * A unary function operator used to partition the objects in the node. The
|
||||
// operator must take a single NodeObject as a parameter and return as
|
||||
// a bool whether to place the NodeObject in the left or right child.
|
||||
// Basically, it should be compatible with std::partition using NodeObjects.
|
||||
// * A binary function operator used to sort the objects. If a partition fails,
|
||||
// the nodes are then sorted based on this function and half are sent to each child.
|
||||
// This operator must define a total ordering of the NodeObjects.
|
||||
// Basically, it should be compatible with std::sort using NodeObjects.
|
||||
//
|
||||
// Example:
|
||||
// struct NodeSplitter
|
||||
// {
|
||||
// NodeSplitter(const NodeObject* objs, unsigned int numObjs);
|
||||
// BoundingVolume& GetNodeBV() const;
|
||||
// // Partition predicate
|
||||
// bool operator()(const NodeObject& obj) const;
|
||||
// // Sort predicate
|
||||
// bool operator()(const NodeObject& obj1, const NodeObject& obj2) const;
|
||||
// };
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef __SKYBVTREE_HPP__
|
||||
#define __SKYBVTREE_HPP__
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SkyBaseBVTree<Object, BoundingVolume>
|
||||
//-----------------------------------------------------------------------------
|
||||
// See header description for details.
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class Object, class BoundingVolume>
|
||||
class SkyBaseBVTree
|
||||
{
|
||||
public:
|
||||
typedef BoundingVolume BV;
|
||||
class NodeObject;
|
||||
|
||||
public:
|
||||
class Node
|
||||
{
|
||||
friend class SkyBaseBVTree<Object, BoundingVolume>;
|
||||
public:
|
||||
Node() : _pObjs(NULL), _iNumObjs(0) {}
|
||||
Node(NodeObject* pObjs, unsigned int iNumObjs) : _pObjs(pObjs), _iNumObjs(iNumObjs) {}
|
||||
|
||||
// Public interface
|
||||
const Object& GetObj(unsigned int index) const { assert(_iNumObjs != 0 && _pObjs != NULL && index < _iNumObjs); return _pObjs[index].GetObj(); }
|
||||
const BV& GetBV(unsigned int index) const { assert(_iNumObjs != 0 && _pObjs != NULL && index < _iNumObjs); return _pObjs[index].GetBV(); }
|
||||
unsigned int GetNumObjs() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _iNumObjs; }
|
||||
const BV& GetNodeBV() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _volume; }
|
||||
const Node* GetLeftChild() const { assert(_iNumObjs != 0 && _pObjs != NULL); return this+1; }
|
||||
const Node* GetRightChild() const { assert(_iNumObjs != 0 && _pObjs != NULL); return this+(GetLeftChild()->GetNumObjs()<<1); }
|
||||
bool IsLeaf() const { assert(_iNumObjs != 0 && _pObjs != NULL); return _iNumObjs == 1; }
|
||||
|
||||
private:
|
||||
// List of Objects owned by the node
|
||||
NodeObject *_pObjs;
|
||||
unsigned int _iNumObjs;
|
||||
BV _volume;
|
||||
};
|
||||
|
||||
public:
|
||||
class NodeObject
|
||||
{
|
||||
public:
|
||||
NodeObject(const Object& o, const BV& v) : _obj(o), _volume(v) {}
|
||||
|
||||
const Object& GetObj() const { return _obj; }
|
||||
const BV& GetBV() const { return _volume; }
|
||||
private:
|
||||
Object _obj;
|
||||
BV _volume;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Give non-const access to the node for descendant classes to build the tree
|
||||
BV& GetNodeBV(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode->_volume; }
|
||||
Node* GetLeftChild(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode+1; }
|
||||
Node* GetRightChild(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode+(GetLeftChild(pNode)->GetNumObjs()<<1); }
|
||||
NodeObject* GetObjs(Node* pNode) { assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL); return pNode->_pObjs; }
|
||||
|
||||
// Links a node's children by assigning the given number of objects to each child
|
||||
// assumes the node has already had it's objects partitioned
|
||||
void LinkNodeChildren(Node* pNode, unsigned int iLeftNumObjs)
|
||||
{
|
||||
assert(pNode->_iNumObjs != 0 && pNode->_pObjs != NULL);
|
||||
GetLeftChild(pNode)->_pObjs = pNode->_pObjs;
|
||||
GetLeftChild(pNode)->_iNumObjs = iLeftNumObjs;
|
||||
GetRightChild(pNode)->_pObjs = pNode->_pObjs + iLeftNumObjs;
|
||||
GetRightChild(pNode)->_iNumObjs = pNode->_iNumObjs - iLeftNumObjs;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : ClearVector
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn ClearVector(std::vector<T>& vec)
|
||||
* @brief This utility function uses the std::vector::swap trick to free the memory of a vector
|
||||
*
|
||||
* This is necessary since clear() doesn't actually free anything.
|
||||
*/
|
||||
template<class T>
|
||||
void ClearVector(std::vector<T>& vec)
|
||||
{
|
||||
std::vector<T>().swap(vec);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SkyBVTree<Object, BoundingVolume, NodeSplitter>
|
||||
//-----------------------------------------------------------------------------
|
||||
// See header description for details.
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class Object, class BoundingVolume, class NodeSplitter>
|
||||
class SkyBVTree : public SkyBaseBVTree<Object, BoundingVolume>
|
||||
{
|
||||
public:
|
||||
typedef SkyBaseBVTree<Object, BoundingVolume> BaseTree;
|
||||
typedef BaseTree::BV BV;
|
||||
typedef BaseTree::NodeObject NodeObject;
|
||||
typedef BaseTree::Node Node;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
BeginTree();
|
||||
}
|
||||
|
||||
void BeginTree(unsigned int iNumObjs = 0)
|
||||
{
|
||||
ClearVector(_objList);
|
||||
ClearVector(_nodes);
|
||||
if (iNumObjs > 0) _objList.reserve(iNumObjs);
|
||||
}
|
||||
|
||||
void AddObject(const Object &obj, const BV& volume)
|
||||
{
|
||||
_objList.push_back(NodeObject(obj, volume));
|
||||
}
|
||||
|
||||
void EndTree()
|
||||
{
|
||||
if (_objList.size() == 0) return;
|
||||
// Initialize the root node with all the objects
|
||||
_nodes.push_back(Node(&_objList[0], _objList.size()));
|
||||
// create room for the other nodes. They are initialized in BuildTree().
|
||||
_nodes.reserve(_objList.size()*2-1);
|
||||
_nodes.resize(_objList.size()*2-1);
|
||||
BuildTree(&_nodes[0]);
|
||||
}
|
||||
|
||||
const Node *GetRoot() const { return _nodes.empty() ? NULL : &_nodes[0]; }
|
||||
|
||||
// Memory usage info
|
||||
unsigned int CalcMemUsage() const
|
||||
{
|
||||
unsigned int usage = 0;
|
||||
usage += sizeof(*this);
|
||||
usage += _objList.capacity() * sizeof(_objList[0]);
|
||||
usage += _nodes.capacity() * sizeof(_nodes[0]);
|
||||
return usage;
|
||||
}
|
||||
|
||||
public:
|
||||
private:
|
||||
// Does the real work
|
||||
void BuildTree(Node *pCurNode)
|
||||
{
|
||||
int iLeftNumObjs;
|
||||
{
|
||||
// Initialize the node splitter with the current node
|
||||
NodeSplitter splitter(GetObjs(pCurNode), pCurNode->GetNumObjs());
|
||||
|
||||
// set the node's bounding volume using the splitter
|
||||
GetNodeBV(pCurNode) = splitter.GetNodeBV();
|
||||
|
||||
// When a node has one object we can stop
|
||||
if (pCurNode->GetNumObjs() == 1) return;
|
||||
|
||||
// Try and partition the objects
|
||||
iLeftNumObjs = std::partition(GetObjs(pCurNode), &GetObjs(pCurNode)[pCurNode->GetNumObjs()], splitter) - GetObjs(pCurNode);
|
||||
|
||||
if ((iLeftNumObjs == 0) || (iLeftNumObjs == pCurNode->GetNumObjs()))
|
||||
{
|
||||
// Partition failed. Sort and split again to force a complete tree
|
||||
std::sort(GetObjs(pCurNode), &GetObjs(pCurNode)[pCurNode->GetNumObjs()], splitter);
|
||||
iLeftNumObjs = pCurNode->GetNumObjs() / 2;
|
||||
}
|
||||
}
|
||||
|
||||
LinkNodeChildren(pCurNode, iLeftNumObjs);
|
||||
BuildTree(GetLeftChild(pCurNode));
|
||||
BuildTree(GetRightChild(pCurNode));
|
||||
}
|
||||
|
||||
std::vector<Node> _nodes;
|
||||
std::vector<NodeObject> _objList;
|
||||
};
|
||||
|
||||
#endif //__SKYBVTREE_HPP__
|
||||
@@ -0,0 +1,242 @@
|
||||
//============================================================================
|
||||
// File : SkyBVTreeSplitter.hpp
|
||||
//
|
||||
// Author : Wesley Hunt
|
||||
//
|
||||
// Content : NodeSplitter classes for SkyBVTrees using SkyBoundingBox or
|
||||
// SkyBoundingSphere (not implemented).
|
||||
//
|
||||
//============================================================================
|
||||
#ifndef __SKYBVTREESPLITTER_HPP__
|
||||
#define __SKYBVTREESPLITTER_HPP__
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//-- Includes ----------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
#include "SkyBVTree.hpp"
|
||||
#include "SkyMinMaxBox.hpp"
|
||||
//#include <Mlx/MlxBoundingSphere.hpp>
|
||||
//#if _MSC_VER == 1200
|
||||
//#include <Auxlib/AuxCompileTimeChecker.hpp>
|
||||
//#endif
|
||||
//----------------------------------------------------------------------------
|
||||
//-- Forward Declarations ----------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
// A strategy for splitting nodes compatible with bounding boxes and spheres.
|
||||
template<class Object> class SkyBoundingBoxSplitter;
|
||||
// SkyBVTree compatible node splitters implemented using the above strategy.
|
||||
template<class Object> class SkyAABBTreeSplitter;
|
||||
//template<class Object> class SkySphereTreeSplitter;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//-- Defines, Constants, Enumerated Types ------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
const float rLongObjectPercentageTolerance = 0.75f;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SkyBoundingBoxSplitter
|
||||
//----------------------------------------------------------------------------
|
||||
// This class defines a NodeSplitter strategy that has the functionality
|
||||
// required by SkyBVTree's NodeSplitter template class. Can be used with
|
||||
// SkyMinMaxBox and SkyBoundingSphere.
|
||||
//
|
||||
// It defines a two-tiered split strategy:
|
||||
//
|
||||
// * First it tries to separate large objects from any smaller objects.
|
||||
// * If there are no large objects, it splits along the midpoint of the longest
|
||||
// axis defined by the objects.
|
||||
// * Finally, if all else fails, it defines a total ordering along the longest
|
||||
// axis based on the center of each node.
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Object>
|
||||
class SkyBoundingBoxSplitter
|
||||
{
|
||||
public:
|
||||
typedef SkyBaseBVTree<Object, SkyMinMaxBox>::NodeObject NodeObjectBox;
|
||||
//typedef SkyBaseBVTree<Object, SkyBoundingSphere>::NodeObject NodeObjectSphere;
|
||||
|
||||
#if _MSC_VER == 1200
|
||||
// !!! WRH HACK MSVC++6 SP5 Workaround.
|
||||
// VC6 can't disambiguate this constructor because it doesn't consider the two
|
||||
// NodeObject templates to be different classes for the purposes of
|
||||
// overloading. It won't recognize that the second template parameters are
|
||||
// different. Forcing them to be explicit template specializations fixes
|
||||
// the problem.
|
||||
template<class BV>
|
||||
SkyBoundingBoxSplitter(const SkyBaseBVTree<Object, BV>::NodeObject*, unsigned int)
|
||||
{
|
||||
//AUX_STATIC_CHECK(false, VisualC_6_WorkAround); ???
|
||||
}
|
||||
template<>
|
||||
#endif
|
||||
SkyBoundingBoxSplitter(const NodeObjectBox* pObjs, unsigned int iNumObjs)
|
||||
{
|
||||
for (unsigned int i = 0; i < iNumObjs; ++i)
|
||||
{
|
||||
_nodeBBox.Union(pObjs[i].GetBV());
|
||||
}
|
||||
Init(pObjs, iNumObjs);
|
||||
}
|
||||
/*#if _MSC_VER == 1200
|
||||
template<>
|
||||
#endif
|
||||
SkyBoundingBoxSplitter(const NodeObjectSphere* objs,
|
||||
#ifdef _PLATFORM_XBOX
|
||||
Int32
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
numObjs)
|
||||
{
|
||||
for (int i=0; i<numObjs; ++i)
|
||||
{
|
||||
SkyMinMaxBox box;
|
||||
box.AddPoint(objs[i].GetBV().GetCenter());
|
||||
box.Bloat(objs[i].GetBV().GetRadius());
|
||||
_nodeBBox.Union(box);
|
||||
}
|
||||
Init(objs, numObjs);
|
||||
}*/
|
||||
|
||||
template<class nodeObj>
|
||||
bool SplitLeft(const nodeObj& obj) const
|
||||
{
|
||||
if (_bIsolateLongObjects)
|
||||
return GetSplitAxisLength(obj.GetBV()) < _rMaxObjectLength;
|
||||
else
|
||||
return GetSplitAxisCenter(obj.GetBV()) < _rSplitValue;
|
||||
}
|
||||
|
||||
template<class nodeObj>
|
||||
bool LessThan(const nodeObj& obj1, const nodeObj& obj2) const
|
||||
{
|
||||
return GetSplitAxisCenter(obj1.GetBV()) < GetSplitAxisCenter(obj2.GetBV());
|
||||
}
|
||||
|
||||
const SkyMinMaxBox& GetNodeBBox() const { return _nodeBBox; }
|
||||
|
||||
private:
|
||||
template<class nodeObj>
|
||||
void Init(const nodeObj* pObjs, unsigned int iNumObjs)
|
||||
{
|
||||
_iSplitAxis = FindSplitAxis(_nodeBBox);
|
||||
_rSplitValue = FindSplitValue(_nodeBBox, _iSplitAxis);
|
||||
_rMaxObjectLength = GetSplitAxisLength(_nodeBBox) * rLongObjectPercentageTolerance;
|
||||
|
||||
_bIsolateLongObjects = false;
|
||||
for (unsigned int i = 0; i < iNumObjs; ++i)
|
||||
{
|
||||
if (GetSplitAxisLength(pObjs[i].GetBV()) > _rMaxObjectLength)
|
||||
{
|
||||
_bIsolateLongObjects = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FindSplitAxis(const SkyMinMaxBox& bbox)
|
||||
{
|
||||
int iAxis = 0, i;
|
||||
Vec3f vecExt = bbox.GetMax() - bbox.GetMin();
|
||||
for (i = 1; i < 3; ++i) if (vecExt[i] > vecExt[iAxis]) iAxis = i;
|
||||
return iAxis;
|
||||
}
|
||||
float FindSplitValue(const SkyMinMaxBox& bbox, int iSplitAxis)
|
||||
{
|
||||
return (bbox.GetMin()[iSplitAxis] + bbox.GetMax()[iSplitAxis])*0.5f;
|
||||
}
|
||||
|
||||
/*float GetSplitAxisLength(const SkyBoundingSphere& sphere) const
|
||||
{
|
||||
return 2.f*sphere.GetRadius();
|
||||
}*/
|
||||
float GetSplitAxisLength(const SkyMinMaxBox& bbox) const
|
||||
{
|
||||
return bbox.GetMax()[_iSplitAxis] - bbox.GetMin()[_iSplitAxis];
|
||||
}
|
||||
|
||||
float GetSplitAxisCenter(const SkyMinMaxBox& bbox) const
|
||||
{
|
||||
return (bbox.GetMin()[_iSplitAxis] + bbox.GetMax()[_iSplitAxis]) * 0.5f;
|
||||
}
|
||||
/*float GetSplitAxisCenter(const SkyBoundingSphere& sphere) const
|
||||
{
|
||||
return sphere.GetCenter()[SplitAxis];
|
||||
}*/
|
||||
|
||||
int _iSplitAxis;
|
||||
float _rSplitValue;
|
||||
bool _bIsolateLongObjects;
|
||||
float _rMaxObjectLength;
|
||||
|
||||
SkyMinMaxBox _nodeBBox;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SkyAABBTreeSplitter
|
||||
//----------------------------------------------------------------------------
|
||||
// A NodeSplitter that is compatible with SkyBVTree for SkyMinMaxBox.
|
||||
// Implemented using the SkyBoundingBoxSplitter strategy.
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Object>
|
||||
class SkyAABBTreeSplitter
|
||||
{
|
||||
public:
|
||||
typedef SkyMinMaxBox BV;
|
||||
typedef SkyBaseBVTree<Object, BV>::NodeObject NodeObject;
|
||||
|
||||
SkyAABBTreeSplitter(const NodeObject* pObjs, unsigned int iNumObjs) : _splitter(pObjs, iNumObjs) {}
|
||||
|
||||
const BV& GetNodeBV() const { return _splitter.GetNodeBBox(); }
|
||||
|
||||
bool operator()(const NodeObject& obj) const
|
||||
{
|
||||
return _splitter.SplitLeft(obj);
|
||||
}
|
||||
|
||||
bool operator()(const NodeObject& obj1, const NodeObject& obj2) const
|
||||
{
|
||||
return _splitter.LessThan(obj1, obj2);
|
||||
}
|
||||
|
||||
private:
|
||||
SkyBoundingBoxSplitter<Object> _splitter;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SkySphereTreeSplitter
|
||||
//----------------------------------------------------------------------------
|
||||
// A NodeSplitter that is compatible with SkyBVTree for SkyBoundingSphere.
|
||||
// Implemented using the SkyBoundingBoxSplitter strategy.
|
||||
//----------------------------------------------------------------------------
|
||||
/*template<class Object>
|
||||
class SkySphereTreeSplitter
|
||||
{
|
||||
public:
|
||||
typedef SkyBoundingSphere BV;
|
||||
typedef SkyBaseBVTree<Object, BV>::NodeObject NodeObject;
|
||||
|
||||
MlxSphereTreeSplitter(const NodeObject* pObjs, unsigned int iNumObjs) : _splitter(pObjs, iNumObjs)
|
||||
{
|
||||
_nodeBV = pObjs[0].GetBV();
|
||||
for (unsigned int i = 1; i < iNumObjs; ++i) _nodeBV.Union(pObjs[i].GetBV());
|
||||
}
|
||||
|
||||
const BV& GetNodeBV() const { return _nodeBV; }
|
||||
|
||||
bool operator()(const NodeObject& obj) const
|
||||
{
|
||||
return _splitter.SplitLeft(obj);
|
||||
}
|
||||
|
||||
bool operator()(const NodeObject& obj1, const NodeObject& obj2) const
|
||||
{
|
||||
return _splitter.LessThan(obj1, obj2);
|
||||
}
|
||||
|
||||
private:
|
||||
BV _nodeBV;
|
||||
SkyBoundingBoxSplitter<Object> _splitter;
|
||||
};*/
|
||||
|
||||
#endif //__SKYBVTREESPLITTER_HPP__
|
||||
@@ -0,0 +1,151 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyBoundingVolume.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyBoundingVolume.hpp
|
||||
*
|
||||
* Base class interface definition for a bounding volume.
|
||||
*/
|
||||
#ifndef __SKYBOUNDINGVOLUME_HPP__
|
||||
#define __SKYBOUNDINGVOLUME_HPP__
|
||||
|
||||
#include "vec3f.hpp"
|
||||
#include "mat44.hpp"
|
||||
|
||||
// forward to reduce unnecessary dependencies
|
||||
class Camera;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyBoundingVolume
|
||||
* @brief An abstract base class for bounding volumes (AABB,OBB,Sphere,etc.)
|
||||
*
|
||||
* This base class maintains a center and a radius, so it is effectively a bounding
|
||||
* sphere. Derived classes may represent other types of bounding volumes, but they
|
||||
* should be sure to update the radius and center, because some objects will treat
|
||||
* all bounding volumes as spheres.
|
||||
*
|
||||
*/
|
||||
class SkyBoundingVolume
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
SkyBoundingVolume() : _vecCenter(0, 0, 0), _rRadius(0) {}
|
||||
//! Destructor
|
||||
virtual ~SkyBoundingVolume() {}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SetCenter
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SetCenter(const Vec3f ¢er)
|
||||
* @brief Sets the center of the bounding volume.
|
||||
*/
|
||||
virtual void SetCenter(const Vec3f ¢er) { _vecCenter = center; }
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SetRadius
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SetRadius(float radius)
|
||||
* @brief Sets the radius of the bounding volume.
|
||||
*/
|
||||
virtual void SetRadius(float radius) { _rRadius = radius; }
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Vec3f& GetCenter
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn Vec3f& GetCenter() const
|
||||
* @brief Returns the center of the bounding volume.
|
||||
*/
|
||||
virtual const Vec3f& GetCenter() const { return _vecCenter; }
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : GetRadius
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn GetRadius() const
|
||||
* @brief Returns the radius ofthe bounding volume.
|
||||
*/
|
||||
virtual float GetRadius() const { return _rRadius; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : ViewFrustumCull
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn ViewFrustumCull( const Camera &cam, const Mat44f &mat )
|
||||
* @brief Cull a bounding volume.
|
||||
*
|
||||
* Returns false if the bounding volume is entirely outside the camera's frustum,
|
||||
* true otherwise.
|
||||
*/
|
||||
virtual bool ViewFrustumCull( const Camera &cam, const Mat44f &mat ) = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : AddPoint
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* @fn AddPoint( const Vec3f &pt )
|
||||
* @brief Add a point to a bounding volume.
|
||||
*
|
||||
* One way to create a bounding volume is to add points. What should/could happen
|
||||
* is that the BV will store an object space BV and then when a call to SetPosition
|
||||
* is called, the stored values will be transformed and stored separately, so that
|
||||
* the original values always exist.
|
||||
*
|
||||
*/
|
||||
//virtual void AddPoint( const Vec3f &point ) = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : AddPoint
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* @fn AddPoint( float x, float y, float z )
|
||||
* @brief Add a point to a bounding volume.
|
||||
*
|
||||
* @see AddPoint(const Vec3f &pt)
|
||||
*/
|
||||
//virtual void AddPoint( float x, float y, float z ) = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Clear
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* @fn Clear()
|
||||
* @brief Clear all data from the bounding volume.
|
||||
*/
|
||||
//virtual void Clear() = 0;
|
||||
|
||||
protected:
|
||||
Vec3f _vecCenter;
|
||||
float _rRadius;
|
||||
};
|
||||
|
||||
#endif //__SKYBOUNDINGVOLUME_HPP__
|
||||
@@ -0,0 +1,980 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyCloud.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Adapted from skyworks program writen by Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
// : by J. Wojnaroski Sep 2002
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyCloud.cpp
|
||||
*
|
||||
* Implementation of class SkyCloud.
|
||||
*/
|
||||
|
||||
// warning for truncation of template name for browse info
|
||||
#pragma warning( disable : 4786)
|
||||
|
||||
#include "SkyCloud.hpp"
|
||||
#include "SkyRenderableInstance.hpp"
|
||||
#include "SkyContext.hpp"
|
||||
#include "SkyMaterial.hpp"
|
||||
#include "SkyLight.hpp"
|
||||
#include "SkyTextureManager.hpp"
|
||||
#include "SkySceneManager.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
//! The version used for cloud archive files.
|
||||
#define CLOUD_ARCHIVE_VERSION 0.1f
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Static initialization
|
||||
//------------------------------------------------------------------------------
|
||||
SkyMaterial* SkyCloud::s_pMaterial = NULL;
|
||||
SkyMaterial* SkyCloud::s_pShadeMaterial = NULL;
|
||||
unsigned int SkyCloud::s_iShadeResolution = 32;
|
||||
float SkyCloud::s_rAlbedo = 0.9f;
|
||||
float SkyCloud::s_rExtinction = 80.0f;
|
||||
float SkyCloud::s_rTransparency = exp(-s_rExtinction);
|
||||
float SkyCloud::s_rScatterFactor = s_rAlbedo * s_rExtinction * SKY_INV_4PI;
|
||||
float SkyCloud::s_rSortAngleErrorTolerance = 0.8f;
|
||||
float SkyCloud::s_rSortSquareDistanceTolerance = 100;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::SkyCloud
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::SkyCloud()
|
||||
* @brief Constructor.
|
||||
*/
|
||||
SkyCloud::SkyCloud()
|
||||
: SkyRenderable(),
|
||||
_bUsePhaseFunction(true),
|
||||
_vecLastSortViewDir(Vec3f::ZERO),
|
||||
_vecLastSortCamPos(Vec3f::ZERO)
|
||||
{
|
||||
if (!s_pShadeMaterial)
|
||||
{
|
||||
s_pShadeMaterial = new SkyMaterial;
|
||||
s_pShadeMaterial->SetAmbient(Vec4f(0.1f, 0.1f, 0.1f, 1));
|
||||
s_pShadeMaterial->EnableDepthTest(false);
|
||||
s_pShadeMaterial->SetBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
s_pShadeMaterial->EnableBlending(true);
|
||||
s_pShadeMaterial->SetAlphaFunc(GL_GREATER);
|
||||
s_pShadeMaterial->SetAlphaRef(0);
|
||||
s_pShadeMaterial->EnableAlphaTest(true);
|
||||
s_pShadeMaterial->SetColorMaterialMode(GL_DIFFUSE);
|
||||
s_pShadeMaterial->EnableColorMaterial(true);
|
||||
s_pShadeMaterial->EnableLighting(false);
|
||||
s_pShadeMaterial->SetTextureApplicationMode(GL_MODULATE);
|
||||
}
|
||||
if (!s_pMaterial)
|
||||
{
|
||||
s_pMaterial = new SkyMaterial;
|
||||
s_pMaterial->SetAmbient(Vec4f(0.3f, 0.3f, 0.3f, 1));
|
||||
s_pMaterial->SetDepthMask(false);
|
||||
s_pMaterial->SetBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
s_pMaterial->EnableBlending(true);
|
||||
s_pMaterial->SetAlphaFunc(GL_GREATER);
|
||||
s_pMaterial->SetAlphaRef(0);
|
||||
s_pMaterial->EnableAlphaTest(true);
|
||||
s_pMaterial->SetColorMaterialMode(GL_DIFFUSE);
|
||||
s_pMaterial->EnableColorMaterial(true);
|
||||
s_pMaterial->EnableLighting(false);
|
||||
s_pMaterial->SetTextureApplicationMode(GL_MODULATE);
|
||||
_CreateSplatTexture(32); // will assign the texture to both static materials
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::~SkyCloud
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::~SkyCloud()
|
||||
* @brief Destructor.
|
||||
*/
|
||||
SkyCloud::~SkyCloud()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Update
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Update(const Camera &cam, SkyRenderableInstance* pInstance)
|
||||
* @brief Currently does nothing.
|
||||
*/
|
||||
SKYRESULT SkyCloud::Update(const Camera &cam, SkyRenderableInstance* pInstance)
|
||||
{
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : DrawQuad
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
|
||||
* @brief Draw a quad.
|
||||
*/
|
||||
inline void DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
|
||||
{
|
||||
glColor4fv(&(color.x));
|
||||
Vec3f left = pos; left -= y;
|
||||
Vec3f right = left; right += x;
|
||||
left -= x;
|
||||
glTexCoord2f(0, 0); glVertex3fv(&(left.x));
|
||||
glTexCoord2f(1, 0); glVertex3fv(&(right.x));
|
||||
left += y; left += y;
|
||||
right += y; right += y;
|
||||
glTexCoord2f(1, 1); glVertex3fv(&(right.x));
|
||||
glTexCoord2f(0, 1); glVertex3fv(&(left.x));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Display
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Display(const Camera &camera, SkyRenderableInstance *pInstance)
|
||||
* @brief Renders the cloud.
|
||||
*
|
||||
* The cloud is rendered by splatting the particles from back to front with respect
|
||||
* to @a camera. Since instances of clouds each have their own particles, which
|
||||
* are pre-transformed into world space, @a pInstance is not used.
|
||||
*
|
||||
* An alternative method is to store the particles untransformed, and transform the
|
||||
* camera and light into cloud space for rendering. This is more complicated,
|
||||
* and not as straightforward. Since I have to store the particles with each instance
|
||||
* anyway, I decided to pre-transform them instead.
|
||||
*/
|
||||
SKYRESULT SkyCloud::Display(const Camera &camera, SkyRenderableInstance *pInstance)
|
||||
{
|
||||
// copy the current camera
|
||||
Camera cam(camera);
|
||||
|
||||
// This cosine computation, along with the if() below, are an optimization. The goal
|
||||
// is to avoid sorting when it will make no visual difference. This will be true when the
|
||||
// cloud particles are almost sorted for the current viewpoint. This is the case most of the
|
||||
// time, since the viewpoint does not move very far in a single frame. Each time we sort,
|
||||
// we cache the current view direction. Then, each time the cloud is displayed, if the
|
||||
// current view direction is very close to the current view direction (dot product is nearly 1)
|
||||
// then we do not resort the particles.
|
||||
float rCosAngleSinceLastSort =
|
||||
_vecLastSortViewDir * cam.ViewDir(); // dot product
|
||||
|
||||
float rSquareDistanceSinceLastSort =
|
||||
(cam.Orig - _vecLastSortCamPos).LengthSqr();
|
||||
|
||||
if (rCosAngleSinceLastSort < s_rSortAngleErrorTolerance ||
|
||||
rSquareDistanceSinceLastSort > s_rSortSquareDistanceTolerance)
|
||||
{
|
||||
// compute the sort position for particles.
|
||||
// don't just use the camera position -- if it is too far away from the cloud, then
|
||||
// precision limitations may cause the STL sort to hang. Instead, put the sort position
|
||||
// just outside the bounding sphere of the cloud in the direction of the camera.
|
||||
_vecSortPos = -cam.ViewDir();
|
||||
_vecSortPos *= (1.1 * _boundingBox.GetRadius());
|
||||
_vecSortPos += _boundingBox.GetCenter();
|
||||
|
||||
// sort the particles from back to front wrt the camera position.
|
||||
_SortParticles(cam.ViewDir(), _vecSortPos, SKY_CLOUD_SORT_TOWARD);
|
||||
|
||||
//_vecLastSortViewDir = GLVU::GetCurrent()->GetCurrentCam()->ViewDir();
|
||||
//_vecLastSortCamPos = GLVU::GetCurrent()->GetCurrentCam()->Orig;
|
||||
_vecLastSortViewDir = cam.ViewDir();
|
||||
_vecLastSortCamPos = cam.Orig;
|
||||
}
|
||||
|
||||
// set the material state / properties that clouds use for rendering:
|
||||
// Enables blending, with blend func (ONE, ONE_MINUS_SRC_ALPHA).
|
||||
// Enables alpha test to discard completely transparent fragments.
|
||||
// Disables depth test.
|
||||
// Enables texturing, with modulation, and the texture set to the shared splat texture.
|
||||
s_pMaterial->Activate();
|
||||
|
||||
Vec4f color;
|
||||
Vec3f eyeDir;
|
||||
|
||||
// Draw the particles using immediate mode.
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
int i = 0;
|
||||
for (ParticleIterator iter = _particles.begin(); iter != _particles.end(); iter++)
|
||||
{
|
||||
i++;
|
||||
SkyCloudParticle *p = *iter;
|
||||
|
||||
// Start with ambient light
|
||||
color = p->GetBaseColor();
|
||||
|
||||
if (_bUsePhaseFunction) // use the phase function for anisotropic scattering.
|
||||
{
|
||||
eyeDir = cam.Orig;
|
||||
eyeDir -= p->GetPosition();
|
||||
eyeDir.Normalize();
|
||||
float pf;
|
||||
|
||||
// add the color contribution to this particle from each light source, modulated by
|
||||
// the phase function. See _PhaseFunction() documentation for details.
|
||||
for (int i = 0; i < p->GetNumLitColors(); i++)
|
||||
{
|
||||
pf = _PhaseFunction(_lightDirections[i], eyeDir);
|
||||
// expand this to avoid temporary vector creation in the inner loop
|
||||
color.x += p->GetLitColor(i).x * pf;
|
||||
color.y += p->GetLitColor(i).y * pf;
|
||||
color.z += p->GetLitColor(i).z * pf;
|
||||
}
|
||||
}
|
||||
else // just use isotropic scattering instead.
|
||||
{
|
||||
for (int i = 0; i < (*iter)->GetNumLitColors(); ++i)
|
||||
{
|
||||
color += p->GetLitColor(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the transparency independently of the colors
|
||||
color.w = 1 - s_rTransparency;
|
||||
|
||||
// draw the particle as a textured billboard.
|
||||
DrawQuad((*iter)->GetPosition(), cam.X * p->GetRadius(), cam.Y * p->GetRadius(), color);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::DisplaySplit
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::DisplaySplit(const Camera &camera, const Vec3f &vecSplitPoint, bool bBackHalf, SkyRenderableInstance *pInstance)
|
||||
* @brief The same as Display(), except it displays only the particles in front of or behind the split point.
|
||||
*
|
||||
* This is used to render clouds into two impostor images for displaying clouds that contain objects.
|
||||
*
|
||||
* @see SkyRenderableInstanceCloud
|
||||
*/
|
||||
SKYRESULT SkyCloud::DisplaySplit(const Camera &camera,
|
||||
const Vec3f &vecSplitPoint,
|
||||
bool bBackHalf,
|
||||
SkyRenderableInstance *pInstance /* = NULL */)
|
||||
{
|
||||
// copy the current camera
|
||||
Camera cam(camera);
|
||||
|
||||
Vec3f vecCloudSpaceSplit = vecSplitPoint;
|
||||
|
||||
if (bBackHalf) // only sort when rendering the back half. Reuse sort for front half.
|
||||
{
|
||||
// compute the sort position for particles.
|
||||
// don't just use the camera position -- if it is too far away from the cloud, then
|
||||
// precision limitations may cause the STL sort to hang. Instead, put the sort position
|
||||
// just outside the bounding sphere of the cloud in the direction of the camera.
|
||||
_vecSortPos = -cam.ViewDir();
|
||||
_vecSortPos *= (1.1 * _boundingBox.GetRadius());
|
||||
_vecSortPos += _boundingBox.GetCenter();
|
||||
|
||||
// sort the particles from back to front wrt the camera position.
|
||||
_SortParticles(cam.ViewDir(), _vecSortPos, SKY_CLOUD_SORT_TOWARD);
|
||||
|
||||
// we can't use the view direction optimization when the cloud is split, or we get a lot
|
||||
// of popping of objects in and out of cloud cover. For consistency, though, we need to update
|
||||
// the cached sort direction, since we just sorted the particles.
|
||||
// _vecLastSortViewDir = GLVU::GetCurrent()->GetCurrentCam()->ViewDir();
|
||||
// _vecLastSortCamPos = GLVU::GetCurrent()->GetCurrentCam()->Orig;
|
||||
|
||||
// compute the split distance.
|
||||
vecCloudSpaceSplit -= _vecSortPos;
|
||||
_rSplitDistance = vecCloudSpaceSplit * cam.ViewDir();
|
||||
}
|
||||
|
||||
// set the material state / properties that clouds use for rendering:
|
||||
// Enables blending, with blend func (ONE, ONE_MINUS_SRC_ALPHA).
|
||||
// Enables alpha test to discard completely transparent fragments.
|
||||
// Disables depth test.
|
||||
// Enables texturing, with modulation, and the texture set to the shared splat texture.
|
||||
s_pMaterial->Activate();
|
||||
|
||||
Vec4f color;
|
||||
Vec3f eyeDir;
|
||||
|
||||
// Draw the particles using immediate mode.
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
// if bBackHalf is false, then we just continue where we left off. If it is true, we
|
||||
// reset the iterator to the beginning of the sorted list.
|
||||
static ParticleIterator iter;
|
||||
if (bBackHalf)
|
||||
iter = _particles.begin();
|
||||
|
||||
// iterate over the particles and render them.
|
||||
for (; iter != _particles.end(); ++iter)
|
||||
{
|
||||
SkyCloudParticle *p = *iter;
|
||||
|
||||
if (bBackHalf && (p->GetSquareSortDistance() < _rSplitDistance))
|
||||
break;
|
||||
|
||||
// Start with ambient light
|
||||
color = p->GetBaseColor();
|
||||
|
||||
if (_bUsePhaseFunction) // use the phase function for anisotropic scattering.
|
||||
{
|
||||
eyeDir = cam.Orig;
|
||||
eyeDir -= p->GetPosition();
|
||||
eyeDir.Normalize();
|
||||
float pf;
|
||||
|
||||
// add the color contribution to this particle from each light source, modulated by
|
||||
// the phase function. See _PhaseFunction() documentation for details.
|
||||
for (int i = 0; i < p->GetNumLitColors(); i++)
|
||||
{
|
||||
pf = _PhaseFunction(_lightDirections[i], eyeDir);
|
||||
// expand this to avoid temporary vector creation in the inner loop
|
||||
color.x += p->GetLitColor(i).x * pf;
|
||||
color.y += p->GetLitColor(i).y * pf;
|
||||
color.z += p->GetLitColor(i).z * pf;
|
||||
}
|
||||
}
|
||||
else // just use isotropic scattering instead.
|
||||
{
|
||||
for (int i = 0; i < p->GetNumLitColors(); ++i)
|
||||
{
|
||||
color += p->GetLitColor(i);
|
||||
}
|
||||
}
|
||||
|
||||
// set the transparency independently of the colors.
|
||||
color.w = 1 - s_rTransparency;
|
||||
|
||||
// draw the particle as a textured billboard.
|
||||
DrawQuad((*iter)->GetPosition(), cam.X * p->GetRadius(), cam.Y * p->GetRadius(), color);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Illuminate
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Illuminate(SkyLight *pLight, SkyRenderableInstance* pInstance, bool bReset)
|
||||
* @brief Compute the illumination of the cloud by the lightsource @a pLight
|
||||
*
|
||||
* This method uses graphics hardware to compute multiple forward scattering at each cloud
|
||||
* in the cloud of light from the directional light source @a pLight. The algorithm works
|
||||
* by successively subtracting "light" from an initially white (fully lit) frame buffer by
|
||||
* using hardware blending and read back. The method stores the illumination from each light
|
||||
* source passed to it separately at each particle, unless @a bReset is true, in which case
|
||||
* the lists of illumination in the particles are reset before the lighting is computed.
|
||||
*
|
||||
*/
|
||||
SKYRESULT SkyCloud::Illuminate(SkyLight *pLight, SkyRenderableInstance* pInstance, bool bReset)
|
||||
{
|
||||
int iOldVP[4];
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, iOldVP);
|
||||
glViewport(0, 0, s_iShadeResolution, s_iShadeResolution);
|
||||
|
||||
Vec3f vecDir(pLight->GetDirection());
|
||||
|
||||
// if this is the first pass through the lights, reset will be true, and the cached light
|
||||
// directions should be updated. Light directions are cached in cloud space to accelerate
|
||||
// computation of the phase function, which depends on light direction and view direction.
|
||||
if (bReset)
|
||||
_lightDirections.clear();
|
||||
_lightDirections.push_back(vecDir); // cache the (unit-length) light direction
|
||||
|
||||
// compute the light/sort position for particles from the light direction.
|
||||
// don't just use the camera position -- if it is too far away from the cloud, then
|
||||
// precision limitations may cause the STL sort to hang. Instead, put the sort position
|
||||
// just outside the bounding sphere of the cloud in the direction of the camera.
|
||||
Vec3f vecLightPos(vecDir);
|
||||
vecLightPos *= (1.1*_boundingBox.GetRadius());
|
||||
vecLightPos += _boundingBox.GetCenter();
|
||||
|
||||
// Set up a camera to look at the cloud from the light position. Since the sun is an infinite
|
||||
// light source, this camera will use an orthographic projection tightly fit to the bounding
|
||||
// sphere of the cloud.
|
||||
Camera cam;
|
||||
|
||||
// Avoid degenerate camera bases.
|
||||
Vec3f vecUp(0, 1, 0);
|
||||
if (fabs(vecDir * vecUp) - 1 < 1e-6) // check that the view and up directions are not parallel.
|
||||
vecUp.Set(1, 0, 0);
|
||||
|
||||
cam.LookAt(vecLightPos, _boundingBox.GetCenter(), vecUp);
|
||||
|
||||
// sort the particles away from the light source.
|
||||
_SortParticles(cam.ViewDir(), vecLightPos, SKY_CLOUD_SORT_AWAY);
|
||||
|
||||
// projected dist to cntr along viewdir
|
||||
float DistToCntr = (_boundingBox.GetCenter() - vecLightPos) * cam.ViewDir();
|
||||
|
||||
// calc tight-fitting near and far distances for the orthographic frustum
|
||||
float rNearDist = DistToCntr - _boundingBox.GetRadius();
|
||||
float rFarDist = DistToCntr + _boundingBox.GetRadius();
|
||||
|
||||
// set the modelview matrix from this camera.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
float M[16];
|
||||
|
||||
|
||||
cam.GetModelviewMatrix(M);
|
||||
glLoadMatrixf(M);
|
||||
|
||||
// switch to parallel projection
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(-_boundingBox.GetRadius(), _boundingBox.GetRadius(),
|
||||
-_boundingBox.GetRadius(), _boundingBox.GetRadius(),
|
||||
rNearDist, rFarDist);
|
||||
|
||||
// set the material state / properties that clouds use for shading:
|
||||
// Enables blending, with blend func (ONE, ONE_MINUS_SRC_ALPHA).
|
||||
// Enables alpha test to discard completely transparent fragments.
|
||||
// Disables depth test.
|
||||
// Enables texturing, with modulation, and the texture set to the shared splat texture.
|
||||
s_pShadeMaterial->Activate();
|
||||
|
||||
// these are used for projecting the particle position to determine where to read pixels.
|
||||
double MM[16], PM[16];
|
||||
int VP[4] = { 0, 0, s_iShadeResolution, s_iShadeResolution };
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, MM);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, PM);
|
||||
|
||||
// initialize back buffer to all white -- modulation darkens areas where cloud particles
|
||||
// absorb light, and lightens it where they scatter light in the forward direction.
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
float rPixelsPerLength = s_iShadeResolution / (2 * _boundingBox.GetRadius());
|
||||
|
||||
// the solid angle over which we will sample forward-scattered light.
|
||||
float rSolidAngle = 0.09;
|
||||
int i = 0;
|
||||
int iNumFailed = 0;
|
||||
for (ParticleIterator iter = _particles.begin(); iter != _particles.end(); ++iter, ++i)
|
||||
{
|
||||
Vec3f vecParticlePos = (*iter)->GetPosition();
|
||||
|
||||
Vec3f vecOffset(vecLightPos);
|
||||
vecOffset -= vecParticlePos;
|
||||
|
||||
// compute the pixel area to read back in order to integrate the illumination of the particle
|
||||
// over a constant solid angle.
|
||||
float rDistance = fabs(cam.ViewDir() * vecOffset) - rNearDist;
|
||||
|
||||
float rArea = rSolidAngle * rDistance * rDistance;
|
||||
int iPixelDim = sqrt(rArea) * rPixelsPerLength;
|
||||
int iNumPixels = iPixelDim * iPixelDim;
|
||||
if (iNumPixels < 1)
|
||||
{
|
||||
iNumPixels = 1;
|
||||
iPixelDim = 1;
|
||||
}
|
||||
|
||||
// the scale factor to convert the read back pixel colors to an average illumination of the area.
|
||||
float rColorScaleFactor = rSolidAngle / (iNumPixels * 255.0f);
|
||||
|
||||
unsigned char *c = new unsigned char[4 * iNumPixels];
|
||||
|
||||
Vec3d vecWinPos;
|
||||
|
||||
// find the position in the buffer to which the particle position projects.
|
||||
if (!gluProject(vecParticlePos.x, vecParticlePos.y, vecParticlePos.z,
|
||||
MM, PM, VP,
|
||||
&(vecWinPos.x), &(vecWinPos.y), &(vecWinPos.z)))
|
||||
{
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL,
|
||||
"Error: SkyCloud::Illuminate(): failed to project particle position.");
|
||||
}
|
||||
|
||||
// offset the projected window position by half the size of the readback region.
|
||||
vecWinPos.x -= 0.5 * iPixelDim;
|
||||
if (vecWinPos.x < 0) vecWinPos.x = 0;
|
||||
vecWinPos.y -= 0.5 * iPixelDim;
|
||||
if (vecWinPos.y < 0) vecWinPos.y = 0;
|
||||
|
||||
// read back illumination of this particle from the buffer.
|
||||
glReadBuffer(GL_BACK);
|
||||
glReadPixels(vecWinPos.x, vecWinPos.y, iPixelDim, iPixelDim, GL_RGBA, GL_UNSIGNED_BYTE, c);
|
||||
|
||||
// scattering coefficient vector.
|
||||
Vec4f vecScatter(s_rScatterFactor, s_rScatterFactor, s_rScatterFactor, 1);
|
||||
|
||||
// add up the read back pixels (only need one component -- its grayscale)
|
||||
int iSum = 0;
|
||||
for (int k = 0; k < 4 * iNumPixels; k+=4)
|
||||
iSum += c[k];
|
||||
delete [] c;
|
||||
|
||||
// compute the amount of light scattered to this particle by particles closer to the light.
|
||||
// this is the illumination over the solid angle that we measured (using glReadPixels) times
|
||||
// the scattering coefficient (vecScatter);
|
||||
Vec4f vecScatteredAmount(iSum * rColorScaleFactor,
|
||||
iSum * rColorScaleFactor,
|
||||
iSum * rColorScaleFactor,
|
||||
1 - s_rTransparency);
|
||||
vecScatteredAmount &= vecScatter;
|
||||
|
||||
// the color of th particle (iter) contributed by this light source (pLight) is the
|
||||
// scattered light from the part of the cloud closer to the light, times the diffuse color
|
||||
// of the light source. The alpha is 1 - the uniform transparency of all particles (modulated
|
||||
// by the splat texture).
|
||||
Vec4f vecColor = vecScatteredAmount;
|
||||
vecColor &= pLight->GetDiffuse();
|
||||
vecColor.w = 1 - s_rTransparency;
|
||||
|
||||
// add this color to the list of lit colors for the particle. The contribution from each light
|
||||
// is kept separate because the phase function we apply at runtime depends on the light vector
|
||||
// for each light source separately. This view-dependent effect is impossible without knowing
|
||||
// the amount of light contributed for each light. This, of course, assumes the clouds will
|
||||
// be lit by a reasonably small number of lights (The sun plus some simulation of light reflected
|
||||
// from the sky and / or ground.) This technique works very well for simulating anisotropic
|
||||
// illumination by skylight.
|
||||
if (bReset)
|
||||
{
|
||||
(*iter)->SetBaseColor(s_pMaterial->GetAmbient());
|
||||
(*iter)->ClearLitColors();
|
||||
(*iter)->AddLitColor(vecColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*iter)->AddLitColor(vecColor);
|
||||
}
|
||||
|
||||
// the following computation (scaling of the scattered amount by the phase function) is done
|
||||
// after the lit color is stored so we don't add the scattering to this particle twice.
|
||||
vecScatteredAmount *= 1.5; // rayleigh scattering phase function for angle of zero or 180 = 1.5!
|
||||
|
||||
// clamp the color
|
||||
if (vecScatteredAmount.x > 1) vecScatteredAmount.x = 1;
|
||||
if (vecScatteredAmount.y > 1) vecScatteredAmount.y = 1;
|
||||
if (vecScatteredAmount.z > 1) vecScatteredAmount.z = 1;
|
||||
vecScatteredAmount.w = 1 - s_rTransparency;
|
||||
|
||||
vecScatteredAmount.x = 0.50; vecScatteredAmount.y = 0.60; vecScatteredAmount.z = 0.70;
|
||||
|
||||
// Draw the particle as a texture billboard. Use the scattered light amount as the color to
|
||||
// simulate forward scattering of light by this particle.
|
||||
glBegin(GL_QUADS);
|
||||
DrawQuad(vecParticlePos, cam.X * (*iter)->GetRadius(), cam.Y * (*iter)->GetRadius(), vecScatteredAmount);
|
||||
glEnd();
|
||||
|
||||
//glutSwapBuffers(); // Uncomment this swap buffers to visualize cloud illumination computation.
|
||||
}
|
||||
|
||||
// Note: here we could optionally store the current back buffer as a shadow image
|
||||
// to be projected from the light position onto the scene. This way we can have clouds shadow
|
||||
// the environment.
|
||||
|
||||
// restore matrix stack and viewport.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]);
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::CopyBoundingVolume
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::CopyBoundingVolume() const
|
||||
* @brief Returns a new copy of the SkyMinMaxBox for this cloud.
|
||||
*/
|
||||
SkyMinMaxBox* SkyCloud::CopyBoundingVolume() const
|
||||
{
|
||||
SkyMinMaxBox *pBox = new SkyMinMaxBox();
|
||||
pBox->SetMax(_boundingBox.GetMax());
|
||||
pBox->SetMin(_boundingBox.GetMin());
|
||||
return pBox;
|
||||
}
|
||||
|
||||
SKYRESULT SkyCloud::Load(const SkyArchive &archive,
|
||||
float rScale, /* = 1.0f */
|
||||
double latitude, double longitude )
|
||||
{
|
||||
unsigned int iNumParticles;
|
||||
Vec3f vecCenter = Vec3f::ZERO;
|
||||
//Vec3f vecCenter;
|
||||
//float rRadius;
|
||||
//archive.FindVec3f("CldCenter", &vecCenter);
|
||||
//archive.FindFloat32("CldRadius", &rRadius);
|
||||
|
||||
//_boundingBox.SetMin(vecCenter - Vec3f(rRadius, rRadius, rRadius));
|
||||
//_boundingBox.SetMax(vecCenter + Vec3f(rRadius, rRadius, rRadius));
|
||||
|
||||
archive.FindUInt32("CldNumParticles", &iNumParticles);
|
||||
//if (!bLocal)
|
||||
archive.FindVec3f("CldCenter", &vecCenter);
|
||||
|
||||
Vec3f *pParticlePositions = new Vec3f[iNumParticles];
|
||||
float *pParticleRadii = new float[iNumParticles];
|
||||
Vec4f *pParticleColors = new Vec4f[iNumParticles];
|
||||
|
||||
unsigned int iNumBytes;
|
||||
archive.FindData("CldParticlePositions", ANY_TYPE, (void**const)&pParticlePositions, &iNumBytes);
|
||||
archive.FindData("CldParticleRadii", ANY_TYPE, (void**const)&pParticleRadii, &iNumBytes);
|
||||
archive.FindData("CldParticleColors", ANY_TYPE, (void**const)&pParticleColors, &iNumBytes);
|
||||
|
||||
for (unsigned int i = 0; i < iNumParticles; ++i)
|
||||
{
|
||||
SkyCloudParticle *pParticle = new SkyCloudParticle((pParticlePositions[i] + vecCenter) * rScale,
|
||||
pParticleRadii[i] * rScale,
|
||||
pParticleColors[i]);
|
||||
_boundingBox.AddPoint(pParticle->GetPosition());
|
||||
|
||||
_particles.push_back(pParticle);
|
||||
}
|
||||
// this is just a bad hack to align cloud field from skyworks with local horizon at KSFO
|
||||
// this "almost" works not quite the right solution okay to get some up and running
|
||||
// we need to develop our own scheme for loading and positioning clouds
|
||||
Mat33f R;
|
||||
Vec3f moveit;
|
||||
|
||||
R.Set( 0, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 0, 1);
|
||||
// clouds sit in the y-z plane and x-axis is the vertical cloud height
|
||||
Rotate( R );
|
||||
|
||||
// rotate the cloud field about the fgfs z-axis based on initial longitude
|
||||
float ex = 0.0;
|
||||
float ey = 0.0;
|
||||
float ez = 1.0;
|
||||
float phi = longitude / 57.29578;
|
||||
float one_min_cos = 1 - cos(phi);
|
||||
|
||||
R.Set(
|
||||
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
|
||||
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
|
||||
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
|
||||
|
||||
Rotate( R );
|
||||
|
||||
// okay now that let's rotate about a vector for latitude where longitude forms the
|
||||
// components of a unit vector in the x-y plane
|
||||
ex = sin( longitude / 57.29578 );
|
||||
ey = -cos( longitude / 57.29578 );
|
||||
ez = 0.0;
|
||||
phi = latitude / 57.29578;
|
||||
one_min_cos = 1 - cos(phi);
|
||||
|
||||
R.Set(
|
||||
cos(phi) + one_min_cos*ex*ex, one_min_cos*ex*ey - ez*sin(phi), one_min_cos*ex*ez + ey*sin(phi),
|
||||
one_min_cos*ex*ey + ez*sin(phi), cos(phi) + one_min_cos*ey*ey, one_min_cos*ey*ez - ex*sin(phi),
|
||||
one_min_cos*ex*ez - ey*sin(phi), one_min_cos*ey*ez + ex*sin(phi), cos(phi) + one_min_cos*ez*ez );
|
||||
|
||||
Rotate( R );
|
||||
// need to calculate an offset to place the clouds at ~3000 feet MSL ATM this is an approximation
|
||||
// to move the clouds to some altitude above sea level. At some locations this could be underground
|
||||
// will need a better scheme to position clouds per user preferences
|
||||
float cloud_level_msl = 3000.0f;
|
||||
|
||||
float x_offset = ex * cloud_level_msl;
|
||||
float y_offset = ey * cloud_level_msl;
|
||||
float z_offset = cloud_level_msl * 0.5;
|
||||
moveit.Set( x_offset, y_offset, z_offset );
|
||||
|
||||
Translate( moveit );
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Save
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Save(SkyArchive &archive) const
|
||||
* @brief Saves the cloud data to @a archive.
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyCloud::Save FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SKYRESULT SkyCloud::Save(SkyArchive &archive) const
|
||||
{
|
||||
SkyArchive myArchive("Cloud");
|
||||
//myArchive.AddVec3f("CldCenter", _center);
|
||||
//myArchive.AddFloat32("CldRadius", _boundingBox.GetRadius());
|
||||
myArchive.AddUInt32("CldNumParticles", _particles.size());
|
||||
|
||||
// make temp arrays
|
||||
Vec3f *pParticlePositions = new Vec3f[_particles.size()];
|
||||
float *pParticleRadii = new float[_particles.size()];
|
||||
Vec4f *pParticleColors = new Vec4f[_particles.size()];
|
||||
|
||||
unsigned int i = 0;
|
||||
|
||||
for (ParticleConstIterator iter = _particles.begin(); iter != _particles.end(); ++iter, ++i)
|
||||
{
|
||||
pParticlePositions[i] = (*iter)->GetPosition(); // position around origin
|
||||
pParticleRadii[i] = (*iter)->GetRadius();
|
||||
pParticleColors[i] = (*iter)->GetBaseColor();
|
||||
}
|
||||
|
||||
myArchive.AddData("CldParticlePositions",
|
||||
ANY_TYPE,
|
||||
pParticlePositions,
|
||||
sizeof(Vec3f),
|
||||
_particles.size());
|
||||
|
||||
myArchive.AddData("CldParticleRadii",
|
||||
ANY_TYPE,
|
||||
pParticleRadii,
|
||||
sizeof(float),
|
||||
_particles.size());
|
||||
|
||||
myArchive.AddData("CldParticleColors",
|
||||
ANY_TYPE,
|
||||
pParticleColors,
|
||||
sizeof(Vec3f),
|
||||
_particles.size());
|
||||
|
||||
archive.AddArchive(myArchive);
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Rotate
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Rotate(const Mat33f& rot)
|
||||
* @brief @todo <WRITE BRIEF SkyCloud::Rotate DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyCloud::Rotate FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyCloud::Rotate(const Mat33f& rot)
|
||||
{
|
||||
_boundingBox.Clear();
|
||||
for (int i = 0; i < _particles.size(); ++i)
|
||||
{
|
||||
_particles[i]->SetPosition(rot * _particles[i]->GetPosition());
|
||||
_boundingBox.AddPoint(_particles[i]->GetPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Translate
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Translate(const Vec3f& trans)
|
||||
* @brief @todo <WRITE BRIEF SkyCloud::Translate DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyCloud::Translate FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyCloud::Translate(const Vec3f& trans)
|
||||
{
|
||||
for (int i = 0; i < _particles.size(); ++i)
|
||||
{
|
||||
_particles[i]->SetPosition(_particles[i]->GetPosition() + trans);
|
||||
}
|
||||
_boundingBox.SetMax(_boundingBox.GetMax() + trans);
|
||||
_boundingBox.SetMin(_boundingBox.GetMin() + trans);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::Scale
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::Scale(const float scale)
|
||||
* @brief @todo <WRITE BRIEF SkyCloud::Scale DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyCloud::Scale FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyCloud::Scale(const float scale)
|
||||
{
|
||||
_boundingBox.Clear();
|
||||
for (int i = 0; i < _particles.size(); ++i)
|
||||
{
|
||||
_particles[i]->SetPosition(_particles[i]->GetPosition() * scale);
|
||||
_boundingBox.AddPoint(_particles[i]->GetPosition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::_SortParticles
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::_SortParticles(const Vec3f& vecViewDir, const Vec3f& sortPoint, SortDirection dir)
|
||||
* @brief Sorts the cloud particles in the direction specified by @a dir.
|
||||
*
|
||||
* @vecSortPoint is assumed to already be transformed into the basis space of the cloud.
|
||||
*/
|
||||
void SkyCloud::_SortParticles(const Vec3f& vecViewDir,
|
||||
const Vec3f& vecSortPoint,
|
||||
SortDirection dir)
|
||||
{
|
||||
Vec3f partPos;
|
||||
for (int i = 0; i < _particles.size(); ++i)
|
||||
{
|
||||
partPos = _particles[i]->GetPosition();
|
||||
partPos -= vecSortPoint;
|
||||
_particles[i]->SetSquareSortDistance(partPos * vecViewDir);//partPos.LengthSqr());
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case SKY_CLOUD_SORT_TOWARD:
|
||||
std::sort(_particles.begin(), _particles.end(), _towardComparator);
|
||||
break;
|
||||
case SKY_CLOUD_SORT_AWAY:
|
||||
std::sort(_particles.begin(), _particles.end(), _awayComparator);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : EvalHermite
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* EvalHermite(float pA, float pB, float vA, float vB, float u)
|
||||
* @brief Evaluates Hermite basis functions for the specified coefficients.
|
||||
*/
|
||||
inline float EvalHermite(float pA, float pB, float vA, float vB, float u)
|
||||
{
|
||||
float u2=(u*u), u3=u2*u;
|
||||
float B0 = 2*u3 - 3*u2 + 1;
|
||||
float B1 = -2*u3 + 3*u2;
|
||||
float B2 = u3 - 2*u2 + u;
|
||||
float B3 = u3 - u;
|
||||
return( B0*pA + B1*pB + B2*vA + B3*vB );
|
||||
}
|
||||
|
||||
// NORMALIZED GAUSSIAN INTENSITY MAP (N must be a power of 2)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : CreateGaussianMap
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* CreateGaussianMap(int N)
|
||||
*
|
||||
* Creates a 2D gaussian image using a hermite surface.
|
||||
*/
|
||||
unsigned char* CreateGaussianMap(int N)
|
||||
{
|
||||
float *M = new float[2*N*N];
|
||||
unsigned char *B = new unsigned char[4*N*N];
|
||||
float X,Y,Y2,Dist;
|
||||
float Incr = 2.0f/N;
|
||||
int i=0;
|
||||
int j = 0;
|
||||
Y = -1.0f;
|
||||
for (int y=0; y<N; y++, Y+=Incr)
|
||||
{
|
||||
Y2=Y*Y;
|
||||
X = -1.0f;
|
||||
for (int x=0; x<N; x++, X+=Incr, i+=2, j+=4)
|
||||
{
|
||||
Dist = (float)sqrt(X*X+Y2);
|
||||
if (Dist>1) Dist=1;
|
||||
M[i+1] = M[i] = EvalHermite(0.4f,0,0,0,Dist);// * (1 - noise);
|
||||
B[j+3] = B[j+2] = B[j+1] = B[j] = (unsigned char)(M[i] * 255);
|
||||
}
|
||||
}
|
||||
SAFE_DELETE_ARRAY(M);
|
||||
return(B);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::_CreateSplatTexture
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::_CreateSplatTexture(unsigned int iResolution)
|
||||
* @brief Creates the texture map used for cloud particles.
|
||||
*/
|
||||
void SkyCloud::_CreateSplatTexture(unsigned int iResolution)
|
||||
{
|
||||
unsigned char *splatTexture = CreateGaussianMap(iResolution);
|
||||
SkyTexture texture;
|
||||
TextureManager::InstancePtr()->Create2DTextureObject(texture, iResolution, iResolution,
|
||||
GL_RGBA, splatTexture);
|
||||
|
||||
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
s_pShadeMaterial->SetTexture(0, GL_TEXTURE_2D, texture);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
s_pShadeMaterial->SetTextureParameter(0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
s_pShadeMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
s_pShadeMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
s_pMaterial->EnableTexture(0, true);
|
||||
s_pShadeMaterial->EnableTexture(0, true);
|
||||
|
||||
SAFE_DELETE_ARRAY(splatTexture);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloud::_PhaseFunction
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloud::_PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir)
|
||||
* @brief Computes the phase (scattering) function of the given light and view directions.
|
||||
*
|
||||
* A phase function is a transfer function that determines, for any angle between incident
|
||||
* and outgoing directions, how much of the incident light intensity will be
|
||||
* scattered in the outgoing direction. For example, scattering by very small
|
||||
* particles such as those found in clear air, can be approximated using <i>Rayleigh
|
||||
* scattering</i>. The phase function for Rayleigh scattering is
|
||||
* p(q) = 0.75*(1 + cos<sup>2</sup>(q)), where q is the angle between incident
|
||||
* and scattered directions. Scattering by larger particles is more complicated.
|
||||
* It is described by Mie scattering theory. Cloud particles are more in the regime
|
||||
* of Mie scattering than Rayleigh scattering. However, we obtain good visual
|
||||
* results by using the simpler Rayleigh scattering phase function as an approximation.
|
||||
*/
|
||||
float SkyCloud::_PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir)
|
||||
{
|
||||
float rCosAlpha = vecLightDir * vecViewDir;
|
||||
return .75f * (1 + rCosAlpha * rCosAlpha); // rayleigh scattering = (3/4) * (1+cos^2(alpha))
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyCloud.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyCloud.hpp
|
||||
*
|
||||
* Interface definition for class SkyCloud.
|
||||
*/
|
||||
#ifndef __SKYCLOUD_HPP__
|
||||
#define __SKYCLOUD_HPP__
|
||||
|
||||
// warning for truncation of template name for browse info
|
||||
#pragma warning( disable : 4786)
|
||||
|
||||
#include "SkyCloudParticle.hpp"
|
||||
#include "SkyRenderable.hpp"
|
||||
#include "SkyMinMaxBox.hpp"
|
||||
#include "camera.hpp"
|
||||
#include "SkyArchive.hpp"
|
||||
#include "mat33.hpp"
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
class SkyMaterial;
|
||||
class SkyLight;
|
||||
class SkyRenderableInstance;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyCloud
|
||||
* @brief A renderable that represents a volumetric cloud.
|
||||
*
|
||||
* A SkyCloud is made up of particles, and is rendered using particle splatting.
|
||||
* SkyCloud is intended to represent realisticly illuminated volumetric clouds
|
||||
* through which the viewer and / or other objects can realistically pass.
|
||||
*
|
||||
* Realistic illumination is performed by the Illuminate() method, which uses a
|
||||
* graphics hardware algorithm to precompute and store multiple forward scattering
|
||||
* of light by each particle in the cloud. Clouds may be illuminated by multiple
|
||||
* light sources. The light from each source is precomputed and stored at each
|
||||
* particle. Each light's contribution is stored separately so that we can
|
||||
* compute view-dependent (anisotropic) scattering at run-time. This gives realistic
|
||||
* effects such as the "silver lining" that you see on a thick cloud when it crosses
|
||||
* in front of the sun.
|
||||
*
|
||||
* At run-time, the cloud is rendered by drawing each particle as a view-oriented
|
||||
* textured billboard (splat), with lighting computed from the precomputed illumination
|
||||
* as follows: for each light source <i>l</i>, compute the scattering function (See _PhaseFunction())
|
||||
* based on the view direction and the direction from the particle to the viewer. This
|
||||
* scattering function modulates the lighting contribution of <i>l</i>. The modulated
|
||||
* contributions are then added and used to modulate the color of the particle. The result
|
||||
* is view-dependent scattering.
|
||||
*
|
||||
* If the phase (scattering) function is not enabled (see IsPhaseFunctionEnabled()), then the
|
||||
* contributions of the light sources are simply added.
|
||||
*
|
||||
* @see SkyRenderableInstanceCloud, SkyCloudParticle, SkySceneManager
|
||||
*/
|
||||
class SkyCloud : public SkyRenderable
|
||||
{
|
||||
public:
|
||||
SkyCloud();
|
||||
virtual ~SkyCloud();
|
||||
|
||||
virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance* pInstance = NULL);
|
||||
|
||||
virtual SKYRESULT Display(const Camera &camera, SkyRenderableInstance *pInstance = NULL);
|
||||
|
||||
SKYRESULT DisplaySplit(const Camera &camera,
|
||||
const Vec3f &vecSplitPoint,
|
||||
bool bBackHalf,
|
||||
SkyRenderableInstance *pInstance = NULL);
|
||||
|
||||
SKYRESULT Illuminate( SkyLight *pLight,
|
||||
SkyRenderableInstance* pInstance,
|
||||
bool bReset = false);
|
||||
|
||||
virtual SkyMinMaxBox* CopyBoundingVolume() const;
|
||||
|
||||
//! Enables the use of a scattering function for anisotropic light scattering.
|
||||
void EnablePhaseFunction(bool bEnable) { _bUsePhaseFunction = bEnable; }
|
||||
//! Returns true if the use of a scattering function is enabled.
|
||||
bool IsPhaseFunctionEnabled() const { return _bUsePhaseFunction; }
|
||||
|
||||
SKYRESULT Save(SkyArchive &archive) const;
|
||||
SKYRESULT Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
|
||||
|
||||
void Rotate(const Mat33f& rot);
|
||||
void Translate(const Vec3f& trans);
|
||||
void Scale(const float scale);
|
||||
|
||||
protected: // methods
|
||||
enum SortDirection
|
||||
{
|
||||
SKY_CLOUD_SORT_TOWARD,
|
||||
SKY_CLOUD_SORT_AWAY
|
||||
};
|
||||
|
||||
void _SortParticles( const Vec3f& vecViewDir,
|
||||
const Vec3f& vecSortPoint,
|
||||
SortDirection dir);
|
||||
|
||||
void _CreateSplatTexture( unsigned int iResolution);
|
||||
|
||||
float _PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir);
|
||||
|
||||
protected: // datatypes
|
||||
typedef std::vector<SkyCloudParticle*> ParticleArray;
|
||||
typedef ParticleArray::iterator ParticleIterator;
|
||||
typedef ParticleArray::const_iterator ParticleConstIterator;
|
||||
|
||||
typedef std::vector<Vec3f> DirectionArray;
|
||||
typedef DirectionArray::iterator DirectionIterator;
|
||||
|
||||
class ParticleAwayComparator
|
||||
{
|
||||
public:
|
||||
bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
|
||||
{
|
||||
return ((*pA) < (*pB));
|
||||
}
|
||||
};
|
||||
|
||||
class ParticleTowardComparator
|
||||
{
|
||||
public:
|
||||
bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
|
||||
{
|
||||
return ((*pA) > (*pB));
|
||||
}
|
||||
};
|
||||
|
||||
protected: // data
|
||||
ParticleArray _particles; // cloud particles
|
||||
// particle sorting functors for STL sort.
|
||||
ParticleTowardComparator _towardComparator;
|
||||
ParticleAwayComparator _awayComparator;
|
||||
|
||||
DirectionArray _lightDirections; // light directions in cloud space (cached)
|
||||
|
||||
SkyMinMaxBox _boundingBox; // bounds
|
||||
|
||||
bool _bUsePhaseFunction;
|
||||
|
||||
Vec3f _vecLastSortViewDir;
|
||||
Vec3f _vecLastSortCamPos;
|
||||
Vec3f _vecSortPos;
|
||||
|
||||
float _rSplitDistance;
|
||||
|
||||
static SkyMaterial *s_pMaterial; // shared material for clouds.
|
||||
static SkyMaterial *s_pShadeMaterial;// shared material for illumination pass.
|
||||
static unsigned int s_iShadeResolution; // the resolution of the viewport used for shading
|
||||
static float s_rAlbedo; // the cloud albedo
|
||||
static float s_rExtinction; // the extinction of the clouds
|
||||
static float s_rTransparency; // the transparency of the clouds
|
||||
static float s_rScatterFactor; // How much the clouds scatter
|
||||
static float s_rSortAngleErrorTolerance; // how far the view must turn to cause a resort.
|
||||
static float s_rSortSquareDistanceTolerance; // how far the view must move to cause a resort.
|
||||
};
|
||||
|
||||
#endif //__SKYCLOUD_HPP__
|
||||
@@ -0,0 +1,175 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyCloudParticle.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyCloudParticle.hpp
|
||||
*
|
||||
* Definition of a simple cloud particle class.
|
||||
*/
|
||||
#ifndef __SKYCLOUDPARTICLE_HPP__
|
||||
#define __SKYCLOUDPARTICLE_HPP__
|
||||
|
||||
#include "vec3f.hpp"
|
||||
#include "vec4f.hpp"
|
||||
#include <vector>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyCloudParticle
|
||||
* @brief A class for particles that make up a cloud.
|
||||
*
|
||||
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
|
||||
*/
|
||||
class SkyCloudParticle
|
||||
{
|
||||
public:
|
||||
inline SkyCloudParticle();
|
||||
inline SkyCloudParticle(const Vec3f& pos,
|
||||
float rRadius,
|
||||
const Vec4f& baseColor,
|
||||
float rTransparency = 0);
|
||||
inline ~SkyCloudParticle();
|
||||
|
||||
//! Returns the radius of the particle.
|
||||
float GetRadius() const { return _rRadius; }
|
||||
//! Returns the transparency of the particle.
|
||||
float GetTransparency() const { return _rTransparency; }
|
||||
//! Returns the position of the particle.
|
||||
const Vec3f& GetPosition() const { return _vecPosition; }
|
||||
//! Returns the base color of the particle. This is often used for ambient color.
|
||||
const Vec4f& GetBaseColor() const { return _vecBaseColor; }
|
||||
//! Returns the number of light contributions to this particle's color.
|
||||
unsigned int GetNumLitColors() const { return _vecLitColors.size(); }
|
||||
//! Returns the light contribution to the color of this particle from light @a index.
|
||||
inline const Vec4f& GetLitColor(unsigned int index) const;
|
||||
//! Returns the square distance from the sort position used for the operator< in sorts / splits.
|
||||
float GetSquareSortDistance() const { return _rSquareSortDistance; }
|
||||
|
||||
//! Sets the radius of the particle.
|
||||
void SetRadius(float rad) { _rRadius = rad; }
|
||||
//! Returns the transparency of the particle.
|
||||
void SetTransparency(float trans) { _rTransparency = trans; }
|
||||
//! Sets the position of the particle.
|
||||
void SetPosition(const Vec3f& pos) { _vecPosition = pos; }
|
||||
//! Sets the base color of the particle. This is often used for ambient color.
|
||||
void SetBaseColor(const Vec4f& col) { _vecBaseColor = col; }
|
||||
//! Sets the light contribution to the color of this particle from light @a index.
|
||||
void AddLitColor(const Vec4f& col) { _vecLitColors.push_back(col); }
|
||||
//! Clears the list of light contributions.
|
||||
void ClearLitColors() { _vecLitColors.clear(); }
|
||||
//! Sets the square distance from the sort position used for the operator< in sorts.
|
||||
void SetSquareSortDistance(float rSquareDistance) { _rSquareSortDistance = rSquareDistance; }
|
||||
|
||||
//! This operator is used to sort particle arrays from nearest to farthes.
|
||||
bool operator<(const SkyCloudParticle& p) const
|
||||
{
|
||||
return (_rSquareSortDistance < p._rSquareSortDistance);
|
||||
}
|
||||
|
||||
//! This operator is used to sort particle arrays from farthest to nearest.
|
||||
bool operator>(const SkyCloudParticle& p) const
|
||||
{
|
||||
return (_rSquareSortDistance > p._rSquareSortDistance);
|
||||
}
|
||||
|
||||
protected:
|
||||
float _rRadius;
|
||||
float _rTransparency;
|
||||
Vec3f _vecPosition;
|
||||
Vec4f _vecBaseColor;
|
||||
std::vector<Vec4f> _vecLitColors;
|
||||
Vec3f _vecEye;
|
||||
|
||||
// for sorting particles during shading
|
||||
float _rSquareSortDistance;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloudParticle::SkyCloudParticle
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloudParticle::SkyCloudParticle()
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
inline SkyCloudParticle::SkyCloudParticle()
|
||||
: _rRadius(0),
|
||||
_rTransparency(0),
|
||||
_vecPosition(0, 0, 0),
|
||||
_vecBaseColor(0, 0, 0, 1),
|
||||
_vecEye(0, 0, 0),
|
||||
_rSquareSortDistance(0)
|
||||
{
|
||||
_vecLitColors.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloudParticle::SkyCloudParticle
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloudParticle::SkyCloudParticle(const Vec3f& pos, float rRadius, const Vec4f& baseColor, float rTransparency)
|
||||
* @brief Constructor.
|
||||
*/
|
||||
inline SkyCloudParticle::SkyCloudParticle(const Vec3f& pos,
|
||||
float rRadius,
|
||||
const Vec4f& baseColor,
|
||||
float rTransparency /* = 0 */)
|
||||
: _rRadius(rRadius),
|
||||
_rTransparency(rTransparency),
|
||||
_vecPosition(pos),
|
||||
_vecBaseColor(baseColor),
|
||||
_vecEye(0, 0, 0),
|
||||
_rSquareSortDistance(0)
|
||||
{
|
||||
_vecLitColors.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyCloudParticle::~SkyCloudParticle
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyCloudParticle::~SkyCloudParticle()
|
||||
* @brief Destructor.
|
||||
*/
|
||||
inline SkyCloudParticle::~SkyCloudParticle()
|
||||
{
|
||||
_vecLitColors.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Vec4f& SkyCloudParticle::GetLitColor
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn Vec4f& SkyCloudParticle::GetLitColor(unsigned int index) const
|
||||
* @brief Returns the lit color specified by index.
|
||||
*
|
||||
* If the index is out of range, returns a zero vector.
|
||||
*/
|
||||
inline const Vec4f& SkyCloudParticle::GetLitColor(unsigned int index) const
|
||||
{
|
||||
if (index <= _vecLitColors.size())
|
||||
return _vecLitColors[index];
|
||||
else
|
||||
return Vec4f::ZERO;
|
||||
}
|
||||
|
||||
#endif //__SKYCLOUDPARTICLE_HPP__
|
||||
@@ -0,0 +1,305 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyContext.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyContext.cpp
|
||||
*
|
||||
* Graphics Context Interface. Initializes GL extensions, etc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <GL/glut.h>
|
||||
#ifndef WIN32
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
//#include "extgl.h"
|
||||
|
||||
#include "SkyContext.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
#include "SkyMaterial.hpp"
|
||||
#include "SkyTextureState.hpp"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::SkyContext
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::SkyContext()
|
||||
* @brief Constructor.
|
||||
*
|
||||
*/
|
||||
SkyContext::SkyContext()
|
||||
{
|
||||
_iWidth = glutGet(GLUT_WINDOW_WIDTH);
|
||||
_iHeight = glutGet(GLUT_WINDOW_HEIGHT);
|
||||
|
||||
// materials and structure classes
|
||||
AddCurrentGLContext();
|
||||
// Initialize all the extensions and load the functions - JW (file is extgl.c)
|
||||
#ifdef WIN32
|
||||
glInitialize();
|
||||
InitializeExtension("GL_ARB_multitexture");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::~SkyContext
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::~SkyContext()
|
||||
* @brief Destructor.
|
||||
*/
|
||||
SkyContext::~SkyContext()
|
||||
{
|
||||
// delete map of materials
|
||||
for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
|
||||
{
|
||||
SAFE_DELETE(cmi->second);
|
||||
}
|
||||
_currentMaterials.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::ProcessReshapeEvent
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
|
||||
* @brief Handles window resize events, and notifies all context listeners of the event.
|
||||
*/
|
||||
SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
|
||||
{
|
||||
_iWidth = iWidth;
|
||||
_iHeight = iHeight;
|
||||
return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::InitializeExtensions
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
|
||||
* @brief Initializes GL extension specified by @a pExtensionNames.
|
||||
*/
|
||||
SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
|
||||
{ /***
|
||||
if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
|
||||
{
|
||||
SkyTrace(
|
||||
"ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n",
|
||||
pExtensionName);
|
||||
return SKYRESULT_FAIL;
|
||||
} **/
|
||||
//set this false to catch all the extensions until we come up with a linux version
|
||||
return SKYRESULT_FAIL;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::GetCurrentMaterial
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::GetCurrentMaterial()
|
||||
* @brief Returns the current cached material state that is active in this OpenGL context.
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SkyMaterial* SkyContext::GetCurrentMaterial()
|
||||
{
|
||||
#ifdef WIN32
|
||||
ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
|
||||
#else
|
||||
ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
|
||||
#endif
|
||||
if (_currentMaterials.end() != cmi)
|
||||
return cmi->second;
|
||||
else
|
||||
{
|
||||
SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::GetCurrentTextureState
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::GetCurrentTextureState()
|
||||
* @brief Returns the current cached texture state that is active in this OpenGL context.
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SkyTextureState* SkyContext::GetCurrentTextureState()
|
||||
{
|
||||
#ifdef WIN32
|
||||
ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
|
||||
#else
|
||||
ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
|
||||
#endif
|
||||
if (_currentTextureState.end() != ctsi)
|
||||
return ctsi->second;
|
||||
else
|
||||
{
|
||||
SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::AddCurrentGLContext
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::AddCurrentGLContext()
|
||||
* @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SKYRESULT SkyContext::AddCurrentGLContext()
|
||||
{
|
||||
SkyMaterial *pCurrentMaterial = new SkyMaterial;
|
||||
#ifdef WIN32
|
||||
_currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
|
||||
#else
|
||||
_currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
|
||||
#endif
|
||||
|
||||
SkyTextureState *pCurrentTS = new SkyTextureState;
|
||||
#ifdef WIN32
|
||||
_currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
|
||||
#else
|
||||
_currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
|
||||
#endif
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::Register
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::Register(Listener* pListener, int priority)
|
||||
* @brief Register with the messaging system to handle notification of mode changes
|
||||
*/
|
||||
SKYRESULT SkyContext::Register(Listener* pListener, int priority)
|
||||
{
|
||||
std::list<ListenerPair>::iterator iter =
|
||||
std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
|
||||
if (iter == _listeners.end())
|
||||
{
|
||||
// insert the listener, sorted by priority
|
||||
for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
|
||||
{
|
||||
if (priority <= iter->first)
|
||||
{
|
||||
_listeners.insert(iter, ListenerPair(priority, pListener));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iter == _listeners.end())
|
||||
{
|
||||
_listeners.push_back(ListenerPair(priority, pListener));
|
||||
}
|
||||
// Send a message to the pListener if we are already active so it
|
||||
// can intialize itself
|
||||
//FAIL_RETURN(pListener->GraphicsReshapeEvent());
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
|
||||
}
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyContext::UnRegister
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyContext::UnRegister(Listener *pListener)
|
||||
* @brief UnRegister with the messaging system.
|
||||
*/
|
||||
SKYRESULT SkyContext::UnRegister(Listener *pListener)
|
||||
{
|
||||
std::list<ListenerPair>::iterator iter =
|
||||
std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
|
||||
if (iter == _listeners.end())
|
||||
{
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
|
||||
}
|
||||
else
|
||||
{
|
||||
_listeners.erase(iter);
|
||||
}
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn SkyContext::_SendMessage(SkyMessageType msg)
|
||||
* @brief Messaging system to handle notification of mode changes
|
||||
*/
|
||||
SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
|
||||
{
|
||||
if (_listeners.size() == 0) return SKYRESULT_OK;
|
||||
|
||||
bool failure = false;
|
||||
SKYRESULT res, failureCode = SKYRESULT_OK;
|
||||
std::list<ListenerPair>::iterator iter;
|
||||
SKYRESULT (Listener::*fnPtr)() = NULL;
|
||||
|
||||
// Make a pointer to the appropriate method
|
||||
switch (msg)
|
||||
{
|
||||
case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
|
||||
}
|
||||
|
||||
// Notify all listeners of the messag. catch failures, but still call everyone else.
|
||||
// !!! WRH HORRIBLE HACK must cache the current "end" because these functions could register new listeners
|
||||
std::list<ListenerPair>::iterator endIter = _listeners.end();
|
||||
endIter--;
|
||||
|
||||
iter = _listeners.begin();
|
||||
do
|
||||
{
|
||||
if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
|
||||
{
|
||||
failureCode = res;
|
||||
SkyTrace("SkyContext: SendMessage failed");
|
||||
}
|
||||
if (iter == endIter) break;
|
||||
iter++;
|
||||
} while (true);
|
||||
|
||||
FAIL_RETURN(failureCode);
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyContext.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyContext.hpp
|
||||
*
|
||||
* Graphics Context Interface. Initializes GL extensions, etc.
|
||||
*/
|
||||
#ifndef __SKYCONTEXT_HPP__
|
||||
#define __SKYCONTEXT_HPP__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
// warning for truncation of template name for browse info
|
||||
// #pragma warning( disable : 4786)
|
||||
#include "SkySingleton.hpp"
|
||||
#include <simgear/compiler.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#ifdef WIN32
|
||||
# include "extgl.h"
|
||||
#else
|
||||
typedef void *HANDLE;
|
||||
typedef HANDLE *PHANDLE;
|
||||
#define DECLARE_HANDLE(n) typedef HANDLE n
|
||||
DECLARE_HANDLE(HGLRC);
|
||||
#endif
|
||||
|
||||
class SkyContext;
|
||||
class SkyMaterial;
|
||||
class SkyTextureState;
|
||||
|
||||
//! Graphics Context Singleton declaration.
|
||||
/*! The Context must be created by calling GraphicsContext::Instantiate(). */
|
||||
typedef SkySingleton<SkyContext> GraphicsContext;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyContext
|
||||
* @brief A manager / proxy for the state of OpenGL contexts.
|
||||
*
|
||||
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
|
||||
*/
|
||||
class SkyContext
|
||||
{
|
||||
public: // datatypes
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class Listener
|
||||
* @brief Inherit this class and overide its methods to be notified of context events.
|
||||
*/
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
|
||||
//! Handle a change in the dimensions of the graphics window.
|
||||
virtual SKYRESULT GraphicsReshapeEvent() { return SKYRESULT_OK; }
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum SkyMessageType messages that the context can generate for it's listeners.
|
||||
*/
|
||||
enum SkyMessageType
|
||||
{
|
||||
SKYCONTEXT_MESSAGE_RESHAPE,
|
||||
SKYCONTEXT_MESSAGE_COUNT
|
||||
};
|
||||
|
||||
public: // methods
|
||||
|
||||
SKYRESULT ProcessReshapeEvent(int iWidth, int iHeight);
|
||||
SKYRESULT InitializeExtension(const char *pExtensionName);
|
||||
|
||||
//! Returns the current dimensions of the window.
|
||||
void GetWindowSize(int &iWidth, int &iHeight) { iWidth = _iWidth; iHeight = _iHeight; }
|
||||
|
||||
SkyMaterial* GetCurrentMaterial();
|
||||
SkyTextureState* GetCurrentTextureState();
|
||||
|
||||
SKYRESULT AddCurrentGLContext();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Register with the messaging system to handle notification of mode changes
|
||||
//------------------------------------------------------------------------------
|
||||
SKYRESULT Register(Listener *pListener, int priority = 0);
|
||||
SKYRESULT UnRegister(Listener *pLlistener);
|
||||
|
||||
protected: // methods
|
||||
SkyContext();
|
||||
~SkyContext();
|
||||
|
||||
protected: // data
|
||||
int _iWidth;
|
||||
int _iHeight;
|
||||
|
||||
typedef std::map<HGLRC, SkyMaterial*> ContextMaterialMap;
|
||||
typedef ContextMaterialMap::iterator ContextMaterialIterator;
|
||||
typedef std::map<HGLRC, SkyTextureState*> ContextTextureStateMap;
|
||||
typedef ContextTextureStateMap::iterator ContextTextureStateIterator;
|
||||
|
||||
ContextMaterialMap _currentMaterials;
|
||||
ContextTextureStateMap _currentTextureState;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Messaging system to handle notification of mode changes
|
||||
//------------------------------------------------------------------------------
|
||||
typedef std::pair<int, Listener*> ListenerPair;
|
||||
class _ListenerPred
|
||||
{
|
||||
public:
|
||||
_ListenerPred(const Listener* l) { _l = l; }
|
||||
bool operator()(const ListenerPair& pair) { return pair.second == _l; }
|
||||
protected:
|
||||
const Listener *_l;
|
||||
};
|
||||
|
||||
SKYRESULT _SendMessage(SkyMessageType msg);
|
||||
std::list<ListenerPair> _listeners;
|
||||
|
||||
};
|
||||
|
||||
#endif //__SKYCONTEXT_HPP__
|
||||
@@ -0,0 +1,65 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyControlled.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyControlled.hpp
|
||||
*
|
||||
* Interface definition for controlled objects.
|
||||
*/
|
||||
#ifndef __SKYCONTROLLED_HPP__
|
||||
#define __SKYCONTROLLED_HPP__
|
||||
|
||||
//#include "BHXController.hpp"
|
||||
|
||||
template<typename ControlStateType> class SkyController;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyControlled
|
||||
* @brief A base class defining an interface for controlled objects.
|
||||
*
|
||||
* This class abstracts the control of objects into a simple interface that a
|
||||
* class may inherit that allows it to be controlled by SkyController objects.
|
||||
* A class simply inherits from SkyControlled, which forces the class to implement
|
||||
* the method UpdateStateFromControls(). This method usually uses the SkyController
|
||||
* object passed to SetController() to query the input state via
|
||||
* SkyController::GetControlState().
|
||||
*
|
||||
* @see SkyController
|
||||
*/
|
||||
template<typename ControlStateType>
|
||||
class SkyControlled
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SkyControlled() { _pController = NULL; }
|
||||
//! Destructor
|
||||
virtual ~SkyControlled() { _pController = NULL; }
|
||||
|
||||
//! Sets the controller which will control this controlled object.
|
||||
void SetController(SkyController<ControlStateType> *pController) { _pController = pController; }
|
||||
|
||||
//! Updates the state of the controlled object based on the controls (received from the controller).
|
||||
virtual SKYRESULT UpdateStateFromControls(SKYTIME timeStep) = 0;
|
||||
|
||||
protected:
|
||||
SkyController<ControlStateType> *_pController;
|
||||
ControlStateType _controlState;
|
||||
};
|
||||
|
||||
#endif //__SKYCONTROLLED_HPP__
|
||||
@@ -0,0 +1,56 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyController.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyController.hpp
|
||||
*
|
||||
* Abstract base class for game object controllers.
|
||||
*/
|
||||
#ifndef __SKYCONTROLLER_HPP__
|
||||
#define __SKYCONTROLLER_HPP__
|
||||
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyController
|
||||
* @brief A class that defines an interface for translating general control input into game object control.
|
||||
*
|
||||
* This class abstracts game object control from specific control input, such
|
||||
* as via user interface devices or via artificial intelligence. Subclasses of
|
||||
* this class implement the method GetControlState() so that objects controlled
|
||||
* by an instance of a SkyController can query the control state that determines
|
||||
* their actions. The object need not know whether it is controlled by a human
|
||||
* or the computer since either controller provides it the same interface.
|
||||
*
|
||||
* @see SkyControlled
|
||||
*/
|
||||
template <typename ControlStateType>
|
||||
class SkyController
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SkyController() {}
|
||||
//! Destructor.
|
||||
virtual ~SkyController() {}
|
||||
|
||||
//! Fills out the control state structure passed in with the current state of controls.
|
||||
virtual SKYRESULT GetControlState(ControlStateType &controlState) = 0;
|
||||
};
|
||||
|
||||
#endif //__SKYCONTROLLER_HPP__
|
||||
@@ -0,0 +1,278 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyDynamicTextureManager.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyDynamicTextureManager.cpp
|
||||
*
|
||||
* Implementation of a repository for check out and check in of dynamic textures.
|
||||
*/
|
||||
|
||||
#pragma warning( disable : 4786 )
|
||||
|
||||
#include "SkyDynamicTextureManager.hpp"
|
||||
#include "SkyTexture.hpp"
|
||||
#include "SkyContext.hpp"
|
||||
|
||||
#pragma warning( disable : 4786 )
|
||||
|
||||
//! Set this to 1 to print lots of dynamic texture usage messages.
|
||||
#define SKYDYNTEXTURE_VERBOSE 0
|
||||
//! The maximum number of textures of each resolution to allow in the checked in pool.
|
||||
#define SKYDYNTEXTURE_TEXCACHE_LIMIT 32
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyDynamicTextureManager::SkyDynamicTextureManager
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyDynamicTextureManager::SkyDynamicTextureManager()
|
||||
* @brief Constructor.
|
||||
*/
|
||||
SkyDynamicTextureManager::SkyDynamicTextureManager()
|
||||
#ifdef SKYDYNTEXTURE_VERBOSE
|
||||
: _iNumTextureBytesUsed(0),
|
||||
_iNumTextureBytesCheckedIn(0),
|
||||
_iNumTextureBytesCheckedOut(0)
|
||||
#endif
|
||||
{
|
||||
for (int i = 0; i < 11; ++i)
|
||||
for (int j = 0; j < 11; ++j)
|
||||
_iAvailableSizeCounts[i][j] = 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyDynamicTextureManager::~SkyDynamicTextureManager
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyDynamicTextureManager::~SkyDynamicTextureManager()
|
||||
* @brief Destructor.
|
||||
*/
|
||||
SkyDynamicTextureManager::~SkyDynamicTextureManager()
|
||||
{
|
||||
for ( TextureSet::iterator subset = _availableTexturePool.begin();
|
||||
subset != _availableTexturePool.end();
|
||||
++subset )
|
||||
{ // iterate over texture subsets.
|
||||
for ( TextureSubset::iterator texture = (*subset).second->begin();
|
||||
texture != (*subset).second->end();
|
||||
++texture )
|
||||
{
|
||||
texture->second->Destroy();
|
||||
delete texture->second;
|
||||
}
|
||||
subset->second->clear();
|
||||
}
|
||||
_availableTexturePool.clear();
|
||||
|
||||
for ( TextureSubset::iterator texture = _checkedOutTexturePool.begin();
|
||||
texture != _checkedOutTexturePool.end();
|
||||
++texture )
|
||||
{
|
||||
texture->second->Destroy();
|
||||
delete texture->second;
|
||||
}
|
||||
_checkedOutTexturePool.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyDynamicTextureManager::CheckOutTexture
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyDynamicTextureManager::CheckOutTexture(unsigned int iWidth, unsigned int iHeight)
|
||||
* @brief Returns a texture from the available pool, creating a new one if necessary.
|
||||
*
|
||||
* Thi texture returned by this method is checked out: it will be maintained in a
|
||||
* checked out pool until it is checked in with CheckInTexture(). The texture is owned
|
||||
* by the SkyDynamicTextureManager -- it should not be deleted by another object. Checked out
|
||||
* textures can be modified (copied, or rendered to, etc.), but should not be reallocated
|
||||
* or resized. All checked out textures will be deleted when the SkyDynamicTextureManager
|
||||
* is destroyed, so this manager should be destroyed only after rendering ceases.
|
||||
*/
|
||||
SkyTexture* SkyDynamicTextureManager::CheckOutTexture(unsigned int iWidth,
|
||||
unsigned int iHeight)
|
||||
{
|
||||
int iWidthLog, iHeightLog;
|
||||
iWidthLog = SkyGetLogBaseTwo(iWidth);
|
||||
iHeightLog = SkyGetLogBaseTwo(iHeight);
|
||||
|
||||
// first see if a texture of this resolution is available:
|
||||
// find the subset of textures with width = iWidth, if it exists.
|
||||
TextureSet::iterator subset = _availableTexturePool.find(iWidth);
|
||||
if (subset != _availableTexturePool.end())
|
||||
{ // found the iWidth subset
|
||||
// now find a texture with height = iHeight:
|
||||
TextureSubset::iterator texture = (*subset).second->find(iHeight);
|
||||
if (texture != (*subset).second->end())
|
||||
{ // found one!
|
||||
// extract the texture
|
||||
SkyTexture *pTexture = (*texture).second;
|
||||
(*texture).second = NULL;
|
||||
// first remove it from this set.
|
||||
(*subset).second->erase(texture);
|
||||
// now add it to the checked out texture set.
|
||||
_checkedOutTexturePool.insert(TextureSubset::value_type(pTexture->GetID(), pTexture));
|
||||
|
||||
// update checked out/in amount.
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
_iNumTextureBytesCheckedIn -= iWidth * iHeight * 4;
|
||||
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
|
||||
printf("CHECKOUT: %d x %d\n", iWidth, iHeight);
|
||||
#endif
|
||||
_iAvailableSizeCounts[iWidthLog][iHeightLog]--;
|
||||
// we're now free to give this texture to the user
|
||||
return pTexture;
|
||||
}
|
||||
else
|
||||
{ // we didn't find an iWidth x iHeight texture, although the iWidth subset exists
|
||||
// create a new texture of the appropriate dimensions and return it.
|
||||
SkyTexture *pNewTexture = CreateDynamicTexture(iWidth, iHeight);
|
||||
_checkedOutTexturePool.insert(TextureSubset::value_type(pNewTexture->GetID(),
|
||||
pNewTexture));
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
|
||||
#endif
|
||||
|
||||
return pNewTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // we don't yet have a subset for iWidth textures. Create one.
|
||||
TextureSubset *pSubset = new TextureSubset;
|
||||
_availableTexturePool.insert(TextureSet::value_type(iWidth, pSubset));
|
||||
// now create a new texture of the appropriate dimensions and return it.
|
||||
SkyTexture *pNewTexture = CreateDynamicTexture(iWidth, iHeight);
|
||||
_checkedOutTexturePool.insert(TextureSubset::value_type(pNewTexture->GetID(), pNewTexture));
|
||||
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
_iNumTextureBytesCheckedOut += iWidth * iHeight * 4;
|
||||
#endif
|
||||
return pNewTexture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyDynamicTextureManager::CheckInTexture
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyDynamicTextureManager::CheckInTexture(SkyTexture *pTexture)
|
||||
* @brief Returns a checked-out texture to the available pool.
|
||||
*
|
||||
* This method removes the checked out texture from the checked out pool if it is
|
||||
* checked out, and then checks it in to the available pool.
|
||||
*/
|
||||
void SkyDynamicTextureManager::CheckInTexture(SkyTexture *pTexture)
|
||||
{
|
||||
// first see if the texture is in the checked out pool.
|
||||
TextureSubset::iterator coTexture = _checkedOutTexturePool.find(pTexture->GetID());
|
||||
if (coTexture != _checkedOutTexturePool.end())
|
||||
{ // if it is there, remove it.
|
||||
_checkedOutTexturePool.erase(coTexture);
|
||||
_iNumTextureBytesCheckedOut -= pTexture->GetWidth() * pTexture->GetHeight() * 4;
|
||||
}
|
||||
|
||||
// Don't cache too many unused textures.
|
||||
int iWidthLog, iHeightLog;
|
||||
iWidthLog = SkyGetLogBaseTwo(pTexture->GetWidth());
|
||||
iHeightLog = SkyGetLogBaseTwo(pTexture->GetHeight());
|
||||
if (_iAvailableSizeCounts[iWidthLog][iHeightLog] >= SKYDYNTEXTURE_TEXCACHE_LIMIT)
|
||||
{
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
_iNumTextureBytesUsed -= pTexture->GetWidth() * pTexture->GetHeight() * 4;
|
||||
printf("%dx%d texture DESTROYED.\n\t Total memory used: %d bytes.\n",
|
||||
pTexture->GetWidth(), pTexture->GetHeight(), _iNumTextureBytesUsed);
|
||||
#endif
|
||||
|
||||
pTexture->Destroy();
|
||||
SAFE_DELETE(pTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
// now check the texture into the available pool.
|
||||
// find the width subset:
|
||||
TextureSet::iterator subset = _availableTexturePool.find(pTexture->GetWidth());
|
||||
if (subset != _availableTexturePool.end())
|
||||
{ // the subset exists. Add the texture to it
|
||||
(*subset).second->insert(TextureSubset::value_type(pTexture->GetHeight(), pTexture));
|
||||
_iNumTextureBytesCheckedIn += pTexture->GetWidth() * pTexture->GetHeight() * 4;
|
||||
|
||||
_iAvailableSizeCounts[iWidthLog][iHeightLog]++;
|
||||
}
|
||||
else
|
||||
{ // subset not found. Create it.
|
||||
TextureSubset *pSubset = new TextureSubset;
|
||||
// insert the texture.
|
||||
pSubset->insert(TextureSubset::value_type(pTexture->GetHeight(), pTexture));
|
||||
// insert the subset into the available pool
|
||||
_availableTexturePool.insert(TextureSet::value_type(pTexture->GetWidth(), pSubset));
|
||||
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
_iNumTextureBytesCheckedIn += pTexture->GetWidth() * pTexture->GetHeight() * 4;
|
||||
_iAvailableSizeCounts[iWidthLog][iHeightLog]++;
|
||||
#endif
|
||||
}
|
||||
|
||||
pTexture = NULL;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyDynamicTextureManager::CreateDynamicTexture
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyDynamicTextureManager::CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight)
|
||||
* @brief Allocate a new dynamic texture object of the given resolution.
|
||||
*
|
||||
* This method is used by CheckOutTexture() when it can't find an available texture of
|
||||
* the requested resolution. It can also be called externally, but will result in an
|
||||
* unmanaged texture unless the new texture is subsequently checked in using CheckInTexture().
|
||||
*/
|
||||
SkyTexture* SkyDynamicTextureManager::CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight)
|
||||
{
|
||||
unsigned int iID;
|
||||
glGenTextures(1, &iID);
|
||||
SkyTexture *pNewTexture = new SkyTexture(iWidth, iHeight, iID);
|
||||
glBindTexture(GL_TEXTURE_2D, pNewTexture->GetID());
|
||||
// set default filtering.
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// create an empty buffer
|
||||
unsigned char *pData = new unsigned char[iWidth * iHeight * 4];
|
||||
|
||||
// allocate the texture
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData );
|
||||
|
||||
delete [] pData;
|
||||
|
||||
// update the used texture bytes...
|
||||
_iNumTextureBytesUsed += iWidth * iHeight * 4;
|
||||
#if SKYDYNTEXTURE_VERBOSE
|
||||
printf("New %dx%d texture created.\n\t Total memory used: %d bytes\n", iWidth, iHeight, _iNumTextureBytesUsed);
|
||||
printf("\tTotal memory checked in: %d\n", _iNumTextureBytesCheckedIn);
|
||||
printf("\tTotal memory checked out: %d\n", _iNumTextureBytesCheckedOut);
|
||||
#endif
|
||||
|
||||
return pNewTexture;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyDynamicTextureManager.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyDynamicTextureManager.hpp
|
||||
*
|
||||
* Interface definition of a repository for check out and check in of dynamic textures.
|
||||
*/
|
||||
#ifndef __SKYDYNAMICTEXTUREMANAGER_HPP__
|
||||
#define __SKYDYNAMICTEXTUREMANAGER_HPP__
|
||||
|
||||
// warning for truncation of template name for browse info
|
||||
#pragma warning( disable : 4786)
|
||||
|
||||
#include <map>
|
||||
#include <GL/glut.h>
|
||||
#include "SkyUtil.hpp"
|
||||
#include "SkySingleton.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SkyTexture;
|
||||
class SkyDynamicTextureManager;
|
||||
|
||||
//! Dynamic Texture Manager Singleton declaration.
|
||||
/*! The DynamicTextureManager must be created by calling DynamicTextureManager::Instantiate(). */
|
||||
typedef SkySingleton<SkyDynamicTextureManager> DynamicTextureManager;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyDynamicTextureManager
|
||||
* @brief A repository that allows check-out and check-in from a pool of dynamic textures.
|
||||
*
|
||||
* When an object needs a dynamic texture, it checks it out using CheckOutTexture(), passing
|
||||
* the resolution of the texture it needs. When the object is done with the texture, it
|
||||
* calls CheckInTexture(). New dynamic textures can be allocated by calling CreateDynamicTexture,
|
||||
* but these textures will be unmanaged.
|
||||
*/
|
||||
class SkyDynamicTextureManager
|
||||
{
|
||||
public:
|
||||
SkyTexture* CheckOutTexture(unsigned int iWidth, unsigned int iHeight);
|
||||
void CheckInTexture(SkyTexture* pTexture);
|
||||
|
||||
SkyTexture* CreateDynamicTexture(unsigned int iWidth, unsigned int iHeight);
|
||||
|
||||
protected: // methods
|
||||
SkyDynamicTextureManager(); // these are protected because it is a singleton.
|
||||
~SkyDynamicTextureManager();
|
||||
|
||||
protected: // datatypes
|
||||
typedef multimap<unsigned int, SkyTexture*> TextureSubset;
|
||||
typedef multimap<unsigned int, TextureSubset*> TextureSet;
|
||||
|
||||
protected: // data
|
||||
TextureSet _availableTexturePool;
|
||||
TextureSubset _checkedOutTexturePool;
|
||||
|
||||
unsigned int _iAvailableSizeCounts[11][11];
|
||||
|
||||
unsigned int _iNumTextureBytesUsed;
|
||||
unsigned int _iNumTextureBytesCheckedOut;
|
||||
unsigned int _iNumTextureBytesCheckedIn;
|
||||
};
|
||||
|
||||
#endif //__SKYDYNAMICTEXTUREMANAGER_HPP__
|
||||
@@ -0,0 +1,231 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyLight.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyLight.cpp
|
||||
*
|
||||
* Implementation of a class that maintains the state and operation of a light.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning( disable : 4786)
|
||||
# endif
|
||||
# include "extgl.h"
|
||||
#endif
|
||||
|
||||
#include "SkyLight.hpp"
|
||||
#include "SkyMaterial.hpp"
|
||||
#include "mat44.hpp"
|
||||
#include <GL/glut.h>
|
||||
|
||||
SkyMaterial* SkyLight::s_pMaterial = NULL;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyLight::SkyLight
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyLight::SkyLight(SkyLightType eType)
|
||||
* @brief @todo <WRITE BRIEF SkyLight::SkyLight DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyLight::SkyLight FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SkyLight::SkyLight(SkyLightType eType)
|
||||
: _bEnabled(true),
|
||||
_bDirty(true),
|
||||
_iLastGLID(-1),
|
||||
_eType(eType),
|
||||
_vecPosition(0, 0, 1, 1),
|
||||
_vecDirection(0, 0, -1, 0),
|
||||
_vecDiffuse(1, 1, 1, 1),
|
||||
_vecAmbient(0, 0, 0, 0),
|
||||
_vecSpecular(1, 1, 1, 1),
|
||||
_vecAttenuation(1, 0, 0),
|
||||
_rSpotExponent(0),
|
||||
_rSpotCutoff(180)
|
||||
{
|
||||
if (!s_pMaterial)
|
||||
{
|
||||
s_pMaterial = new SkyMaterial;
|
||||
s_pMaterial->SetColorMaterialMode(GL_DIFFUSE);
|
||||
s_pMaterial->EnableColorMaterial(true);
|
||||
s_pMaterial->EnableLighting(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyLight::~SkyLight
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyLight::~SkyLight()
|
||||
* @brief @todo <WRITE BRIEF SkyLight::~SkyLight DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyLight::~SkyLight FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SkyLight::~SkyLight()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyLight::Display
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyLight::Display() const
|
||||
* @brief Displays a wireframe representation of the light.
|
||||
*
|
||||
* This is useful for debugging.
|
||||
*/
|
||||
void SkyLight::Display() const
|
||||
{
|
||||
s_pMaterial->Activate();
|
||||
//if (_bEnabled)
|
||||
//glColor3fv(&(_vecDiffuse.x));
|
||||
//else
|
||||
glColor3f(0, 0, 0);
|
||||
|
||||
switch(_eType)
|
||||
{
|
||||
case SKY_LIGHT_POINT:
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
{
|
||||
glTranslatef(_vecPosition.x, _vecPosition.y, _vecPosition.z);
|
||||
glutWireSphere(4, 8, 8);
|
||||
}
|
||||
glPopMatrix();
|
||||
break;
|
||||
case SKY_LIGHT_DIRECTIONAL:
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
{
|
||||
Mat44f mat;
|
||||
Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
|
||||
Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
|
||||
Vec3f vecUp(0, 1, 0);
|
||||
if (fabs(vecDir * vecUp) - 1 < 1e-6) // check that the view and up directions are not parallel.
|
||||
vecUp.Set(1, 0, 0);
|
||||
|
||||
mat.invLookAt(vecPos, vecPos + 10 * vecDir, vecUp);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
glTranslatef(-50 * vecDir.x, -50 * vecDir.y, -50 * vecDir.z);
|
||||
glMultMatrixf(mat);
|
||||
glutWireCone(10, 10, 4, 1);
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
glMultMatrixf(mat);
|
||||
GLUquadric *pQuadric = gluNewQuadric();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
gluCylinder(pQuadric, 4, 4, 50, 4, 4);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
case SKY_LIGHT_SPOT:
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
{
|
||||
Mat44f mat;
|
||||
Vec3f vecUp = Vec3f(0, 1, 0);
|
||||
Vec3f vecPos(_vecPosition.x, _vecPosition.y, _vecPosition.z);
|
||||
Vec3f vecDir(_vecDirection.x, _vecDirection.y, _vecDirection.z);
|
||||
if (_vecDirection == vecUp)
|
||||
vecUp.Set(1, 0, 0);
|
||||
mat.invLookAt(vecPos + 50 * vecDir, vecPos + 51 * vecDir, vecUp);
|
||||
|
||||
glMultMatrixf(mat);
|
||||
float rAlpha= acos(pow(10, (-12 / _rSpotExponent)));
|
||||
//glutWireCone(50 * tan(SKYDEGREESTORADS * rAlpha), 50, 16, 8);
|
||||
glutWireCone(50 * tan(SKYDEGREESTORADS * _rSpotCutoff), 50, 16, 8);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyLight::Activate
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyLight::Activate(int iLightID)
|
||||
* @brief @todo <WRITE BRIEF SkyLight::Activate DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyLight::Activate FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SKYRESULT SkyLight::Activate(int iLightID)
|
||||
{
|
||||
glPushMatrix();
|
||||
// set the position every frame
|
||||
if (SKY_LIGHT_DIRECTIONAL != _eType)
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_POSITION, &(_vecPosition.x));
|
||||
else
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_POSITION, &(_vecDirection.x));
|
||||
|
||||
if (SKY_LIGHT_SPOT == _eType)
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_SPOT_DIRECTION, &(_vecDirection.x));
|
||||
|
||||
// set other light properties only when they change.
|
||||
if (_bDirty || iLightID != _iLastGLID)
|
||||
{
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_DIFFUSE, &(_vecDiffuse.x));
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_AMBIENT, &(_vecAmbient.x));
|
||||
glLightfv(GL_LIGHT0 + iLightID, GL_SPECULAR, &(_vecSpecular.x));
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_CONSTANT_ATTENUATION, _vecAttenuation.x);
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_LINEAR_ATTENUATION, _vecAttenuation.y);
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_QUADRATIC_ATTENUATION, _vecAttenuation.z);
|
||||
|
||||
if (SKY_LIGHT_SPOT == _eType)
|
||||
{
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_CUTOFF, _rSpotCutoff);
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_EXPONENT, _rSpotExponent);
|
||||
}
|
||||
else
|
||||
{
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_CUTOFF, 180);
|
||||
glLightf(GL_LIGHT0 + iLightID, GL_SPOT_EXPONENT, 0);
|
||||
}
|
||||
|
||||
if (_bEnabled)
|
||||
glEnable(GL_LIGHT0 + iLightID);
|
||||
else
|
||||
{
|
||||
glDisable(GL_LIGHT0 + iLightID);
|
||||
}
|
||||
|
||||
_iLastGLID = iLightID;
|
||||
_bDirty = false;
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyLight.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyLight.hpp
|
||||
*
|
||||
* Definition of a class that maintains the state and operation of a light.
|
||||
*/
|
||||
#ifndef __SKYLIGHT_HPP__
|
||||
#define __SKYLIGHT_HPP__
|
||||
|
||||
#include "vec3f.hpp"
|
||||
#include "vec4f.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
class SkyMaterial;
|
||||
|
||||
class SkyLight
|
||||
{
|
||||
public: // types
|
||||
enum SkyLightType
|
||||
{
|
||||
SKY_LIGHT_POINT,
|
||||
SKY_LIGHT_DIRECTIONAL,
|
||||
SKY_LIGHT_SPOT,
|
||||
SKY_LIGHT_NUM_TYPES
|
||||
};
|
||||
|
||||
public: // methods
|
||||
SkyLight(SkyLightType eType);
|
||||
virtual ~SkyLight();
|
||||
|
||||
// for visualization of light positions / directions.
|
||||
void Display() const;
|
||||
|
||||
bool GetEnabled() const { return _bEnabled; }
|
||||
SkyLightType GetType() const { return _eType; }
|
||||
const float* GetPosition() const { return _vecPosition; }
|
||||
const float* GetDirection() const { return _vecDirection; }
|
||||
const float* GetDiffuse() const { return _vecDiffuse; }
|
||||
const float* GetAmbient() const { return _vecAmbient; }
|
||||
const float* GetSpecular() const { return _vecSpecular; }
|
||||
const float* GetAttenuation() const { return _vecAttenuation; }
|
||||
float GetSpotExponent() const { return _rSpotExponent; }
|
||||
float GetSpotCutoff() const { return _rSpotCutoff; }
|
||||
|
||||
void Enable(bool bEnable) { _bEnabled = bEnable; _bDirty = true; }
|
||||
void SetType(const SkyLightType& t) { _eType = t; _bDirty = true; }
|
||||
void SetPosition(const float pos[3])
|
||||
{ _vecPosition.Set(pos[0], pos[1], pos[2], (_eType != SKY_LIGHT_DIRECTIONAL)); _bDirty = true; }
|
||||
|
||||
void SetDirection(const float dir[3]) { _vecDirection.Set(dir[0], dir[1], dir[2], 0); _bDirty = true; }
|
||||
void SetDiffuse(const float color[4]) { _vecDiffuse.Set(color); _bDirty = true; }
|
||||
void SetAmbient(const float color[4]) { _vecAmbient.Set(color); _bDirty = true; }
|
||||
void SetSpecular(const float color[4]){ _vecSpecular.Set(color); _bDirty = true; }
|
||||
void SetAttenuation(float rConstant, float rLinear, float rQuadratic)
|
||||
{ _vecAttenuation.Set(rConstant, rLinear, rQuadratic); _bDirty = true; }
|
||||
|
||||
void SetSpotExponent(float rExp) { _rSpotExponent = rExp; _bDirty = true; }
|
||||
void SetSpotCutoff(float rCutoff) { _rSpotCutoff = rCutoff; _bDirty = true; }
|
||||
|
||||
SKYRESULT Activate(int iLightID);
|
||||
|
||||
protected: // data
|
||||
bool _bEnabled;
|
||||
bool _bDirty;
|
||||
|
||||
int _iLastGLID;
|
||||
|
||||
SkyLightType _eType;
|
||||
|
||||
Vec4f _vecPosition;
|
||||
Vec4f _vecDirection;
|
||||
Vec4f _vecDiffuse;
|
||||
Vec4f _vecAmbient;
|
||||
Vec4f _vecSpecular;
|
||||
Vec3f _vecAttenuation; // constant, linear, and quadratic attenuation factors.
|
||||
float _rSpotExponent;
|
||||
float _rSpotCutoff;
|
||||
|
||||
static SkyMaterial *s_pMaterial; // used for rendering the lights during debugging
|
||||
};
|
||||
|
||||
#endif //__SKYLIGHT_HPP__
|
||||
@@ -0,0 +1,445 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyMaterial.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyMaterial.cpp
|
||||
*
|
||||
* Implementation of class SkyMaterial, a meterial property object.
|
||||
*/
|
||||
#include "SkyMaterial.hpp"
|
||||
#include "SkyContext.hpp"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::SkyMaterial
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::SkyMaterial()
|
||||
* @brief Constructor.
|
||||
*/
|
||||
SkyMaterial::SkyMaterial()
|
||||
: _iMaterialID(-1),
|
||||
_vecDiffuse(Vec4f::ZERO),
|
||||
_vecSpecular(Vec4f::ZERO),
|
||||
_vecAmbient(Vec4f::ZERO),
|
||||
_vecEmissive(Vec4f::ZERO),
|
||||
_rSpecularPower(0),
|
||||
_bLighting(true),
|
||||
_eColorMaterialFace(GL_FRONT_AND_BACK),
|
||||
_eColorMaterialMode(GL_AMBIENT_AND_DIFFUSE),
|
||||
_bColorMaterial(false),
|
||||
_vecFogColor(Vec4f::ZERO),
|
||||
_eFogMode(GL_EXP),
|
||||
_bFog(false),
|
||||
_eDepthFunc(GL_LESS),
|
||||
_bDepthMask(true),
|
||||
_bDepthTest(true),
|
||||
_eAlphaFunc(GL_ALWAYS),
|
||||
_rAlphaRef(0),
|
||||
_bAlphaTest(false),
|
||||
_eBlendSrcFactor(GL_ONE),
|
||||
_eBlendDstFactor(GL_ZERO),
|
||||
_bBlending(false),
|
||||
_bFaceCulling(false),
|
||||
_eFaceCullingMode(GL_BACK),
|
||||
_eTextureEnvMode(GL_MODULATE)
|
||||
{
|
||||
_rFogParams[SKY_FOG_DENSITY] = 1;
|
||||
_rFogParams[SKY_FOG_START] = 0;
|
||||
_rFogParams[SKY_FOG_END] = 1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::~SkyMaterial
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::~SkyMaterial()
|
||||
* @brief Destructor.
|
||||
*/
|
||||
SkyMaterial::~SkyMaterial()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::SetFogParameter
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
|
||||
*/
|
||||
SKYRESULT SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
|
||||
{
|
||||
switch (eParameter)
|
||||
{
|
||||
case GL_FOG_DENSITY:
|
||||
_rFogParams[SKY_FOG_DENSITY] = rValue;
|
||||
break;
|
||||
case GL_FOG_START:
|
||||
_rFogParams[SKY_FOG_START] = rValue;
|
||||
break;
|
||||
case GL_FOG_END:
|
||||
_rFogParams[SKY_FOG_END] = rValue;
|
||||
break;
|
||||
default:
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::SetFogParameter(): Invalid parameter.");
|
||||
break;
|
||||
}
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::GetFogParameter
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::GetFogParameter(GLenum eParameter) const
|
||||
*/
|
||||
float SkyMaterial::GetFogParameter(GLenum eParameter) const
|
||||
{
|
||||
switch (eParameter)
|
||||
{
|
||||
case GL_FOG_DENSITY:
|
||||
return _rFogParams[SKY_FOG_DENSITY];
|
||||
break;
|
||||
case GL_FOG_START:
|
||||
return _rFogParams[SKY_FOG_START];
|
||||
break;
|
||||
case GL_FOG_END:
|
||||
return _rFogParams[SKY_FOG_END];
|
||||
break;
|
||||
default:
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::GetFogParameter(): Invalid parameter.");
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::Activate
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::Activate()
|
||||
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SKYRESULT SkyMaterial::Activate()
|
||||
{
|
||||
// Update the cached current material, and only pass values that have changed to the GL.
|
||||
|
||||
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
|
||||
assert(NULL != pCurrentMaterial);
|
||||
|
||||
// basic material properties
|
||||
if (pCurrentMaterial->GetDiffuse() != GetDiffuse())
|
||||
{
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
|
||||
pCurrentMaterial->SetDiffuse(GetDiffuse());
|
||||
}
|
||||
if (pCurrentMaterial->GetSpecular() != GetSpecular())
|
||||
{
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
|
||||
pCurrentMaterial->SetSpecular(GetSpecular());
|
||||
}
|
||||
if (pCurrentMaterial->GetAmbient() != GetAmbient())
|
||||
{
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
|
||||
pCurrentMaterial->SetAmbient(GetAmbient());
|
||||
}
|
||||
if (pCurrentMaterial->GetEmissive() != GetEmissive())
|
||||
{
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
|
||||
pCurrentMaterial->SetEmissive(GetEmissive());
|
||||
}
|
||||
if (pCurrentMaterial->GetSpecularPower() != GetSpecularPower())
|
||||
{
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
|
||||
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
|
||||
}
|
||||
|
||||
// lighting
|
||||
if (pCurrentMaterial->IsLightingEnabled() != IsLightingEnabled())
|
||||
{
|
||||
if (IsLightingEnabled())
|
||||
glEnable(GL_LIGHTING);
|
||||
else
|
||||
glDisable(GL_LIGHTING);
|
||||
pCurrentMaterial->EnableLighting(IsLightingEnabled());
|
||||
}
|
||||
|
||||
// color material (which material property tracks color calls)
|
||||
if (pCurrentMaterial->GetColorMaterialFace() != GetColorMaterialFace() ||
|
||||
pCurrentMaterial->GetColorMaterialMode() != GetColorMaterialMode())
|
||||
{
|
||||
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
|
||||
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
|
||||
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
|
||||
}
|
||||
if (pCurrentMaterial->IsColorMaterialEnabled() != IsColorMaterialEnabled())
|
||||
{
|
||||
if (IsColorMaterialEnabled())
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
else
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
|
||||
}
|
||||
|
||||
// fog
|
||||
if (pCurrentMaterial->GetFogMode() != GetFogMode())
|
||||
{
|
||||
glFogf(GL_FOG_MODE, GetFogMode());
|
||||
pCurrentMaterial->SetFogMode(GetFogMode());
|
||||
}
|
||||
if (pCurrentMaterial->GetFogColor() != GetFogColor())
|
||||
{
|
||||
glFogfv(GL_FOG_COLOR, GetFogColor());
|
||||
pCurrentMaterial->SetFogColor(GetFogColor());
|
||||
}
|
||||
if (pCurrentMaterial->GetFogParameter(GL_FOG_DENSITY) != GetFogParameter(GL_FOG_DENSITY))
|
||||
{
|
||||
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
|
||||
}
|
||||
if (pCurrentMaterial->GetFogParameter(GL_FOG_START) != GetFogParameter(GL_FOG_START))
|
||||
{
|
||||
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
|
||||
}
|
||||
if (pCurrentMaterial->GetFogParameter(GL_FOG_END) != GetFogParameter(GL_FOG_END))
|
||||
{
|
||||
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
|
||||
}
|
||||
if (pCurrentMaterial->IsFogEnabled() != IsFogEnabled())
|
||||
{
|
||||
if (IsFogEnabled())
|
||||
glEnable(GL_FOG);
|
||||
else
|
||||
glDisable(GL_FOG);
|
||||
pCurrentMaterial->EnableFog(IsFogEnabled());
|
||||
}
|
||||
|
||||
// depth test
|
||||
if (pCurrentMaterial->GetDepthFunc() != GetDepthFunc())
|
||||
{
|
||||
glDepthFunc(GetDepthFunc());
|
||||
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
|
||||
}
|
||||
if (pCurrentMaterial->GetDepthMask() != GetDepthMask())
|
||||
{
|
||||
glDepthMask(GetDepthMask());
|
||||
pCurrentMaterial->SetDepthMask(GetDepthMask());
|
||||
}
|
||||
if (pCurrentMaterial->IsDepthTestEnabled() != IsDepthTestEnabled())
|
||||
{
|
||||
if (IsDepthTestEnabled())
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
|
||||
}
|
||||
|
||||
// alpha test
|
||||
if (pCurrentMaterial->GetAlphaFunc() != GetAlphaFunc() ||
|
||||
pCurrentMaterial->GetAlphaRef() != GetAlphaRef())
|
||||
{
|
||||
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
|
||||
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
|
||||
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
|
||||
}
|
||||
if (pCurrentMaterial->IsAlphaTestEnabled() != IsAlphaTestEnabled())
|
||||
{
|
||||
if (IsAlphaTestEnabled())
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
else
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
pCurrentMaterial->EnableAlphaTest(IsAlphaTestEnabled());
|
||||
}
|
||||
|
||||
// blending
|
||||
if (pCurrentMaterial->GetBlendingSourceFactor() != GetBlendingSourceFactor() ||
|
||||
pCurrentMaterial->GetBlendingDestFactor() != GetBlendingDestFactor())
|
||||
{
|
||||
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
|
||||
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
|
||||
}
|
||||
if (pCurrentMaterial->IsBlendingEnabled() != IsBlendingEnabled())
|
||||
{
|
||||
if (IsBlendingEnabled())
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
|
||||
}
|
||||
|
||||
if (pCurrentMaterial->GetFaceCullingMode() != GetFaceCullingMode())
|
||||
{
|
||||
glCullFace(GetFaceCullingMode());
|
||||
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
|
||||
}
|
||||
if (pCurrentMaterial->IsFaceCullingEnabled() != IsFaceCullingEnabled())
|
||||
{
|
||||
if (IsFaceCullingEnabled())
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
|
||||
}
|
||||
|
||||
// texturing
|
||||
FAIL_RETURN(_textureState.Activate());
|
||||
if (pCurrentMaterial->GetTextureApplicationMode() != GetTextureApplicationMode())
|
||||
{
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
|
||||
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
|
||||
}
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMaterial::Force
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMaterial::Force()
|
||||
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
SKYRESULT SkyMaterial::Force()
|
||||
{
|
||||
// Update the cached current material, and only pass values that have changed to the GL.
|
||||
|
||||
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
|
||||
assert(NULL != pCurrentMaterial);
|
||||
|
||||
// basic material properties
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
|
||||
pCurrentMaterial->SetDiffuse(GetDiffuse());
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
|
||||
pCurrentMaterial->SetSpecular(GetSpecular());
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
|
||||
pCurrentMaterial->SetAmbient(GetAmbient());
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
|
||||
pCurrentMaterial->SetEmissive(GetEmissive());
|
||||
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
|
||||
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
|
||||
|
||||
// lighting
|
||||
if (IsLightingEnabled())
|
||||
glEnable(GL_LIGHTING);
|
||||
else
|
||||
glDisable(GL_LIGHTING);
|
||||
pCurrentMaterial->EnableLighting(IsLightingEnabled());
|
||||
|
||||
// color material (which material property tracks color calls)
|
||||
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
|
||||
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
|
||||
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
|
||||
|
||||
if (IsColorMaterialEnabled())
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
else
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
|
||||
|
||||
// fog
|
||||
glFogf(GL_FOG_MODE, GetFogMode());
|
||||
pCurrentMaterial->SetFogMode(GetFogMode());
|
||||
|
||||
glFogfv(GL_FOG_COLOR, GetFogColor());
|
||||
pCurrentMaterial->SetFogColor(GetFogColor());
|
||||
|
||||
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
|
||||
|
||||
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
|
||||
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
|
||||
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
|
||||
|
||||
if (IsFogEnabled())
|
||||
glEnable(GL_FOG);
|
||||
else
|
||||
glDisable(GL_FOG);
|
||||
pCurrentMaterial->EnableFog(IsFogEnabled());
|
||||
|
||||
// depth test
|
||||
glDepthFunc(GetDepthFunc());
|
||||
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
|
||||
|
||||
glDepthMask(GetDepthMask());
|
||||
pCurrentMaterial->SetDepthMask(GetDepthMask());
|
||||
|
||||
if (IsDepthTestEnabled())
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
|
||||
|
||||
// alpha test
|
||||
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
|
||||
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
|
||||
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
|
||||
|
||||
if (IsAlphaTestEnabled())
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
else
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// blending
|
||||
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
|
||||
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
|
||||
|
||||
if (IsBlendingEnabled())
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
|
||||
|
||||
glCullFace(GetFaceCullingMode());
|
||||
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
|
||||
|
||||
if (IsFaceCullingEnabled())
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
|
||||
|
||||
// texturing
|
||||
FAIL_RETURN(_textureState.Force());
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
|
||||
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyMaterial.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyMaterial.hpp
|
||||
*
|
||||
* Interface definition for class SkyMaterial, a meterial property object.
|
||||
*/
|
||||
#ifndef __SKYMATERIAL_HPP__
|
||||
#define __SKYMATERIAL_HPP__
|
||||
|
||||
// #pragma warning( disable : 4786)
|
||||
|
||||
#include "vec4f.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
#include "SkyTextureManager.hpp"
|
||||
#include "SkyTextureState.hpp"
|
||||
#include <GL/glut.h>
|
||||
|
||||
// forward
|
||||
class SkyRenderable;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyMaterial
|
||||
* @brief A class for organizing and caching material state.
|
||||
*
|
||||
* This class handles setting and querying material state. By calling the Activate()
|
||||
* method, the material's state can be made current in OpenGL. The material will not
|
||||
* set states that are currently active in the current OpenGL context.
|
||||
*/
|
||||
class SkyMaterial
|
||||
{
|
||||
public:
|
||||
SkyMaterial();
|
||||
~SkyMaterial();
|
||||
|
||||
SKYRESULT Activate();
|
||||
SKYRESULT Force();
|
||||
|
||||
// Getters for basic material properties
|
||||
|
||||
//! Returns the material identifier.
|
||||
int GetMaterialID() const { return _iMaterialID; }
|
||||
//! Returns the material diffuse color.
|
||||
const Vec4f& GetDiffuse() const { return _vecDiffuse; }
|
||||
//! Returns the material specular color.
|
||||
const Vec4f& GetSpecular() const { return _vecSpecular; }
|
||||
//! Returns the material ambient color.
|
||||
const Vec4f& GetAmbient() const { return _vecAmbient; }
|
||||
//! Returns the material emissive color.
|
||||
const Vec4f& GetEmissive() const { return _vecEmissive; }
|
||||
//! Returns the material specular power (shininess).
|
||||
const float GetSpecularPower() const { return _rSpecularPower; }
|
||||
|
||||
// lighting
|
||||
//! Returns true if lighting is enabled for this material.
|
||||
bool IsLightingEnabled() const { return _bLighting; }
|
||||
|
||||
// color material (which material property tracks color calls)
|
||||
//! Returns the face for which color material tracking is enabled.
|
||||
GLenum GetColorMaterialFace() const { return _eColorMaterialFace; }
|
||||
//! Returns the color material tracking mode.
|
||||
GLenum GetColorMaterialMode() const { return _eColorMaterialMode; }
|
||||
//! Returns true if color material tracking is enabled.
|
||||
bool IsColorMaterialEnabled() const { return _bColorMaterial; }
|
||||
|
||||
//! Returns the fog density or start / end distance.
|
||||
float GetFogParameter(GLenum eParameter) const;
|
||||
//! Returns the fog mode (exponential, linear, etc.)
|
||||
GLenum GetFogMode() const { return _eFogMode; }
|
||||
//! Returns the fog color.
|
||||
const Vec4f& GetFogColor() const { return _vecFogColor; }
|
||||
//! Returns true if fog is enabled for this material.
|
||||
bool IsFogEnabled() const { return _bFog; }
|
||||
|
||||
// texturing
|
||||
//! Returns the active texture target for texture unit @a iTextureUnit.
|
||||
GLenum GetActiveTarget(unsigned int iTextureUnit) const
|
||||
{ return _textureState.GetActiveTarget(iTextureUnit); }
|
||||
//! Returns the bound texture ID for texture unit @a iTextureUnit.
|
||||
unsigned int GetTextureID(unsigned int iTextureUnit) const
|
||||
{ return _textureState.GetTextureID(iTextureUnit); }
|
||||
//! Returns true if texturing is enabled for texture unit @a iTextureUnit.
|
||||
bool IsTextureEnabled(unsigned int iTextureUnit) const
|
||||
{ return _textureState.IsTextureEnabled(iTextureUnit); }
|
||||
//! Returns the value of the texture parameter @a eParameter for texture unit @a iTextureUnit.
|
||||
GLenum GetTextureParameter(unsigned int iTextureUnit, GLenum eParameter) const
|
||||
{ return _textureState.GetTextureParameter(iTextureUnit, eParameter); }
|
||||
//! Returns the texture application mode of the texture environment.
|
||||
GLenum GetTextureApplicationMode() const { return _eTextureEnvMode; }
|
||||
|
||||
//! Returns a reference to the texture state object owned by this materal.
|
||||
SkyTextureState& GetTextureState() { return _textureState; }
|
||||
|
||||
// depth test
|
||||
//! Returns true if depth testing is enabled for this material.
|
||||
bool IsDepthTestEnabled() const { return _bDepthTest; }
|
||||
//! Returns the depth test function for this material.
|
||||
GLenum GetDepthFunc() const { return _eDepthFunc; }
|
||||
//! Returns true if depth writes are enabled for this material, false if not.
|
||||
bool GetDepthMask() const { return _bDepthMask; }
|
||||
|
||||
// alpha test
|
||||
//! Returns true if alpha testing is enabled for this material.
|
||||
bool IsAlphaTestEnabled() const { return _bAlphaTest; }
|
||||
//! Returns the alpha test function for this material.
|
||||
GLenum GetAlphaFunc() const { return _eAlphaFunc; }
|
||||
//! Returns the reference value for alpha comparison.
|
||||
float GetAlphaRef() const { return _rAlphaRef; }
|
||||
|
||||
// blending
|
||||
//! Returns true if blending is enabled for this material.
|
||||
bool IsBlendingEnabled() const { return _bBlending; }
|
||||
//! Returns the source blending factor for this material.
|
||||
GLenum GetBlendingSourceFactor() const { return _eBlendSrcFactor; }
|
||||
//! Returns the destination blending factor for this material.
|
||||
GLenum GetBlendingDestFactor() const { return _eBlendDstFactor; }
|
||||
|
||||
//! Returns true if face culling enabled for this material.
|
||||
bool IsFaceCullingEnabled() const { return _bFaceCulling; }
|
||||
//! Returns which faces are culled -- front-facing or back-facing.
|
||||
GLenum GetFaceCullingMode() const { return _eFaceCullingMode; }
|
||||
|
||||
// Setters for basic material properties
|
||||
|
||||
//! Sets the material identifier.
|
||||
void SetMaterialID(int ID) { _iMaterialID = ID; }
|
||||
//! Sets the diffuse material color.
|
||||
void SetDiffuse( const Vec4f& d) { _vecDiffuse = d; }
|
||||
//! Sets the specular material color.
|
||||
void SetSpecular(const Vec4f& d) { _vecSpecular = d; }
|
||||
//! Sets the ambient material color.
|
||||
void SetAmbient( const Vec4f& d) { _vecAmbient = d; }
|
||||
//! Sets the emissive material color.
|
||||
void SetEmissive(const Vec4f& d) { _vecEmissive = d; }
|
||||
//! Sets the material specular power (shininess).
|
||||
void SetSpecularPower(float power) { _rSpecularPower = power; }
|
||||
|
||||
// lighting
|
||||
//! Enables / Disables lighting for this material.
|
||||
void EnableLighting(bool bEnable) { _bLighting = bEnable; }
|
||||
|
||||
// color material (which material property tracks color calls)
|
||||
//! Sets which faces (front or back) track color calls.
|
||||
void SetColorMaterialFace(GLenum eFace) { _eColorMaterialFace = eFace; }
|
||||
//! Sets which material property tracks color calls.
|
||||
void SetColorMaterialMode(GLenum eMode) { _eColorMaterialMode = eMode; }
|
||||
//! Enables / Disables material color tracking for this material.
|
||||
void EnableColorMaterial(bool bEnable) { _bColorMaterial = bEnable; }
|
||||
|
||||
//! Sets the fog density or start / end distance.
|
||||
SKYRESULT SetFogParameter(GLenum eParameter, float rValue);
|
||||
//! Sets the fog mode (exponential, linear, etc.)
|
||||
void SetFogMode(GLenum eMode) { _eFogMode = eMode; }
|
||||
//! Sets the fog color.
|
||||
void SetFogColor(const Vec4f& color) { _vecFogColor = color; }
|
||||
//! Enables / Disables fog for this material.
|
||||
void EnableFog(bool bEnable) { _bFog = bEnable; }
|
||||
|
||||
// texturing
|
||||
//! Sets the bound texture and texture target for texture unit @a iTextureUnit.
|
||||
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, SkyTexture& texture)
|
||||
{ return _textureState.SetTexture(iTextureUnit, eTarget, texture); }
|
||||
//! Sets the bound texture and texture target for texture unit @a iTextureUnit.
|
||||
SKYRESULT SetTexture(unsigned int iTextureUnit, GLenum eTarget, unsigned int iTextureID)
|
||||
{ return _textureState.SetTexture(iTextureUnit, eTarget, iTextureID); }
|
||||
//! Enables / Disables texture unit @a iTextureUnit for this material.
|
||||
SKYRESULT EnableTexture(unsigned int iTextureUnit, bool bEnable)
|
||||
{ return _textureState.EnableTexture(iTextureUnit, bEnable); }
|
||||
//! Sets the value of the texture parameter @a eParameter for texture unit @a iTextureUnit.
|
||||
SKYRESULT SetTextureParameter(unsigned int iTextureUnit, GLenum eParameter, GLenum eMode)
|
||||
{ return _textureState.SetTextureParameter(iTextureUnit, eParameter, eMode); }
|
||||
|
||||
//! Sets the texture application mode of the texture environment.
|
||||
void SetTextureApplicationMode(GLenum eMode){ _eTextureEnvMode = eMode;}
|
||||
|
||||
// depth test
|
||||
//! Enables / Disables depth test for this material.
|
||||
void EnableDepthTest(bool bEnable) { _bDepthTest = bEnable; }
|
||||
//! Sets the depth test function (greater, less than, equal, etc.).
|
||||
void SetDepthFunc(GLenum eDepthFunc) { _eDepthFunc = eDepthFunc;}
|
||||
//! If @a bDepthMask is true, then depth writes are enabled, otherwise they are not.
|
||||
void SetDepthMask(bool bDepthMask) { _bDepthMask = bDepthMask;}
|
||||
|
||||
// alpha test
|
||||
//! Enables / Disables alpha test for this material.
|
||||
void EnableAlphaTest(bool bEnable) { _bAlphaTest = bEnable; }
|
||||
//! Sets the alpha test function (greater, less than, equal, etc.).
|
||||
void SetAlphaFunc(GLenum eAlphaFunc) { _eAlphaFunc = eAlphaFunc;}
|
||||
//! Sets the reference value against which fragment alpha values are compared.
|
||||
void SetAlphaRef(float rAlphaRef) { _rAlphaRef = rAlphaRef; }
|
||||
|
||||
// blending
|
||||
//! Enables / Disables blending for this material.
|
||||
void EnableBlending(bool bEnable) { _bBlending = bEnable; }
|
||||
//! Sets the source and destination blending factors for this material.
|
||||
void SetBlendFunc(GLenum eSrcFactor, GLenum eDstFactor)
|
||||
{ _eBlendSrcFactor = eSrcFactor; _eBlendDstFactor = eDstFactor; }
|
||||
|
||||
//! Enables / Disables face culling for this material.
|
||||
void EnableFaceCulling(bool bEnable) { _bFaceCulling = bEnable; }
|
||||
//! Sets which faces will be culled -- front facing or back facing.
|
||||
void SetFaceCullingMode(GLenum eMode) { _eFaceCullingMode = eMode; }
|
||||
|
||||
protected:
|
||||
int _iMaterialID;
|
||||
|
||||
Vec4f _vecDiffuse;
|
||||
Vec4f _vecSpecular;
|
||||
Vec4f _vecAmbient;
|
||||
Vec4f _vecEmissive;
|
||||
|
||||
float _rSpecularPower;
|
||||
|
||||
bool _bLighting;
|
||||
|
||||
GLenum _eColorMaterialFace;
|
||||
GLenum _eColorMaterialMode;
|
||||
bool _bColorMaterial;
|
||||
|
||||
enum SkyFogParams
|
||||
{
|
||||
SKY_FOG_DENSITY,
|
||||
SKY_FOG_START,
|
||||
SKY_FOG_END,
|
||||
SKY_FOG_NUM_PARAMS
|
||||
};
|
||||
|
||||
Vec4f _vecFogColor;
|
||||
GLenum _eFogMode;
|
||||
float _rFogParams[SKY_FOG_NUM_PARAMS];
|
||||
bool _bFog;
|
||||
|
||||
GLenum _eDepthFunc;
|
||||
bool _bDepthMask;
|
||||
bool _bDepthTest;
|
||||
|
||||
GLenum _eAlphaFunc;
|
||||
float _rAlphaRef;
|
||||
bool _bAlphaTest;
|
||||
|
||||
GLenum _eBlendSrcFactor;
|
||||
GLenum _eBlendDstFactor;
|
||||
bool _bBlending;
|
||||
|
||||
bool _bFaceCulling;
|
||||
GLenum _eFaceCullingMode;
|
||||
|
||||
SkyTextureState _textureState;
|
||||
GLenum _eTextureEnvMode;
|
||||
};
|
||||
|
||||
#endif //__SKYMATERIAL_HPP__
|
||||
@@ -0,0 +1,322 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyMinMaxBox.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyMinMaxBox.cpp
|
||||
*
|
||||
* Implementation of a bounding box class. Modified from Wes Hunt's BoundingBox.
|
||||
*/
|
||||
#include "SkyMinMaxBox.hpp"
|
||||
#include "camutils.hpp"
|
||||
#include <GL/glut.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::SkyMinMaxBox
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::SkyMinMaxBox()
|
||||
* @brief Constructor
|
||||
*/
|
||||
SkyMinMaxBox::SkyMinMaxBox()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::Clear
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::Clear()
|
||||
* @brief Reset the min and max to floating point extremes.
|
||||
*
|
||||
*/
|
||||
void SkyMinMaxBox::Clear()
|
||||
{
|
||||
_min.x = FLT_MAX;
|
||||
_min.y = FLT_MAX;
|
||||
_min.z = FLT_MAX;
|
||||
_max.x = -FLT_MAX;
|
||||
_max.y = -FLT_MAX;
|
||||
_max.z = -FLT_MAX;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::PointInBBox
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
|
||||
* @brief Queries pt to see if it is inside the SkyMinMaxBox.
|
||||
*
|
||||
*/
|
||||
bool SkyMinMaxBox::PointInBBox( const Vec3f &pt ) const
|
||||
{
|
||||
if( (pt.x >= _min.x) && ( pt.x <= _max.x ) )
|
||||
{
|
||||
if( (pt.y >= _min.y) && ( pt.y <= _max.y ) )
|
||||
{
|
||||
if( (pt.z >= _min.z) && ( pt.z <= _max.z ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::AddPoint
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::AddPoint( float x , float y , float z )
|
||||
* @brief Adds a point and adjusts bounds if necessary.
|
||||
*/
|
||||
void SkyMinMaxBox::AddPoint( float x , float y , float z )
|
||||
{
|
||||
if( x > _max.x )
|
||||
_max.x = x;
|
||||
if( x < _min.x )
|
||||
_min.x = x;
|
||||
|
||||
if( y > _max.y )
|
||||
_max.y = y;
|
||||
if( y < _min.y )
|
||||
_min.y = y;
|
||||
|
||||
if( z > _max.z )
|
||||
_max.z = z;
|
||||
if( z < _min.z )
|
||||
_min.z = z;
|
||||
|
||||
// update the center and radius
|
||||
_UpdateSphere();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::AddPoint
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::AddPoint( const Vec3f &pt )
|
||||
* @brief Adds a point and adjusts bounds if necessary.
|
||||
*/
|
||||
void SkyMinMaxBox::AddPoint( const Vec3f &pt )
|
||||
{
|
||||
if( pt.x > _max.x )
|
||||
_max.x = pt.x;
|
||||
if( pt.x < _min.x )
|
||||
_min.x = pt.x;
|
||||
|
||||
if( pt.y > _max.y )
|
||||
_max.y = pt.y;
|
||||
if( pt.y < _min.y )
|
||||
_min.y = pt.y;
|
||||
|
||||
if( pt.z > _max.z )
|
||||
_max.z = pt.z;
|
||||
if( pt.z < _min.z )
|
||||
_min.z = pt.z;
|
||||
|
||||
// update the center and radius
|
||||
_UpdateSphere();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::ViewFrustumCull
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
|
||||
* @brief Returns true if bounding volume culled against cam.
|
||||
*
|
||||
* This function must transform the object space min and max then adjust the new
|
||||
* min and max box by expanding it. Each of the 8 points must be tested. This
|
||||
* is faster then doing an xform of all the geometry points and finding a tight
|
||||
* fitting min max box, however this will be enlarged.
|
||||
*/
|
||||
bool SkyMinMaxBox::ViewFrustumCull( const Camera &cam, const Mat44f &mat )
|
||||
{
|
||||
SkyMinMaxBox xBV; // Xformed Bounding Volume
|
||||
Vec3f xMin = mat * _min; // Xformed _min
|
||||
Vec3f xMax = mat * _max; // Xformed _max
|
||||
Vec3f offset = _max - _min; // Offset for sides of MinMaxBox
|
||||
Vec3f tmp;
|
||||
|
||||
xBV.Clear(); // Clear the values first
|
||||
|
||||
// First find the new minimum x,y,z
|
||||
// Find min + x
|
||||
tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
|
||||
tmp *= offset.x;
|
||||
tmp += xMin;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Find min + y
|
||||
tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
|
||||
tmp *= offset.y;
|
||||
tmp += xMin;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Find min + z
|
||||
tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
|
||||
tmp *= offset.z;
|
||||
tmp += xMin;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Second find the new maximum x,y,z
|
||||
// Find max - x
|
||||
tmp.Set(mat.M[0], mat.M[4], mat.M[8]);
|
||||
tmp *= -offset.x;
|
||||
tmp += xMax;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Find max - y
|
||||
tmp.Set(mat.M[1], mat.M[5], mat.M[9]);
|
||||
tmp *= -offset.y;
|
||||
tmp += xMax;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Find max - z
|
||||
tmp.Set(mat.M[3], mat.M[6], mat.M[10]);
|
||||
tmp *= -offset.z;
|
||||
tmp += xMax;
|
||||
xBV.AddPoint(tmp);
|
||||
|
||||
// Use the camera utility function that already exists for minmax boxes
|
||||
return VFC(&cam, xBV.GetMin(), xBV.GetMax());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::Transform
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::Transform(const Mat44f& mat)
|
||||
* @brief @todo <WRITE BRIEF SkyMinMaxBox::Transform DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyMinMaxBox::Transform FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyMinMaxBox::Transform(const Mat44f& mat)
|
||||
{
|
||||
Vec3f verts[8];
|
||||
_CalcVerts(verts);
|
||||
Clear();
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
AddPoint(mat * verts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::_UpdateSphere
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::_UpdateSphere()
|
||||
* @brief Updates the bounding sphere based on min and max.
|
||||
*/
|
||||
void SkyMinMaxBox::_UpdateSphere()
|
||||
{
|
||||
_vecCenter = _min;
|
||||
_vecCenter += _max;
|
||||
_vecCenter *= 0.5f;
|
||||
|
||||
Vec3f rad = _max;
|
||||
rad -= _vecCenter;
|
||||
_rRadius = rad.Length();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::Display
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::Display() const
|
||||
* @brief @todo <WRITE BRIEF SkyMinMaxBox::Display DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyMinMaxBox::Display FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyMinMaxBox::Display() const
|
||||
{
|
||||
Vec3f V[8];
|
||||
_CalcVerts(V);
|
||||
|
||||
glPushAttrib(GL_LINE_BIT);
|
||||
glLineWidth(1.0);
|
||||
|
||||
glBegin(GL_LINE_LOOP); // TOP FACE
|
||||
glVertex3fv(V[4]); glVertex3fv(V[5]); glVertex3fv(V[1]); glVertex3fv(V[0]);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP); // BOTTOM FACE
|
||||
glVertex3fv(V[3]); glVertex3fv(V[2]); glVertex3fv(V[6]); glVertex3fv(V[7]);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP); // LEFT FACE
|
||||
glVertex3fv(V[1]); glVertex3fv(V[5]); glVertex3fv(V[6]); glVertex3fv(V[2]);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP); // RIGHT FACE
|
||||
glVertex3fv(V[0]); glVertex3fv(V[3]); glVertex3fv(V[7]); glVertex3fv(V[4]);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP); // NEAR FACE
|
||||
glVertex3fv(V[1]); glVertex3fv(V[2]); glVertex3fv(V[3]); glVertex3fv(V[0]);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_LOOP); // FAR FACE
|
||||
glVertex3fv(V[4]); glVertex3fv(V[7]); glVertex3fv(V[6]); glVertex3fv(V[5]);
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Calculates the eight corner vertices of the MinMaxBox.
|
||||
// V must be prealloced.
|
||||
// 5---4
|
||||
// / /|
|
||||
// 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
|
||||
// | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
|
||||
// | |/
|
||||
// 2---3
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyMinMaxBox::_CalcVerts
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
|
||||
* @brief @todo <WRITE BRIEF SkyMinMaxBox::_CalcVerts DOCUMENTATION>
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyMinMaxBox::_CalcVerts FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyMinMaxBox::_CalcVerts(Vec3f pVerts[8]) const
|
||||
{
|
||||
pVerts[0].Set(_max); pVerts[4].Set(_max.x, _max.y, _min.z);
|
||||
pVerts[1].Set(_min.x, _max.y, _max.z); pVerts[5].Set(_min.x, _max.y, _min.z);
|
||||
pVerts[2].Set(_min.x, _min.y, _max.z); pVerts[6].Set(_min);
|
||||
pVerts[3].Set(_max.x, _min.y, _max.z); pVerts[7].Set(_max.x, _min.y, _min.z);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyMinMaxBox.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyMinMaxBox.hpp
|
||||
*
|
||||
* Interface definition for a min-max bounding box class for bounding volume hierarchies.
|
||||
*/
|
||||
#ifndef __SKYMINMAXBOX_HPP__
|
||||
#define __SKYMINMAXBOX_HPP__
|
||||
|
||||
#include "SkyBoundingVolume.hpp"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyMinMaxBox
|
||||
* @brief An AABB class that can be used in bounding volume hierarchies.
|
||||
*
|
||||
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
|
||||
*/
|
||||
class SkyMinMaxBox : public SkyBoundingVolume
|
||||
{
|
||||
public:
|
||||
SkyMinMaxBox();
|
||||
//! Destructor
|
||||
virtual ~SkyMinMaxBox() {}
|
||||
|
||||
void AddPoint( const Vec3f &pt );
|
||||
void AddPoint( float x , float y , float z );
|
||||
|
||||
//! Expand this box to contain @a box.
|
||||
void Union(const SkyMinMaxBox& box) { AddPoint(box.GetMin()); AddPoint(box.GetMax()); }
|
||||
|
||||
//! Returns the minimum corner of the bounding box.
|
||||
const Vec3f &GetMin() const { return _min; }
|
||||
//! Returns the maximum corner of the bounding box.
|
||||
const Vec3f &GetMax() const { return _max; }
|
||||
|
||||
//! Sets the minimum corner of the bounding box.
|
||||
void SetMin(const Vec3f &min) { _min = min; _UpdateSphere(); }
|
||||
//! Sets the maximum corner of the bounding box.
|
||||
void SetMax(const Vec3f &max) { _max = max; _UpdateSphere(); }
|
||||
|
||||
//! Returns the X width of the bounding box.
|
||||
float GetWidthInX() const { return _max.x - _min.x;}
|
||||
//! Returns the Y width of the bounding box.
|
||||
float GetWidthInY() const { return _max.y - _min.y;}
|
||||
//! Returns the Z width of the bounding box.
|
||||
float GetWidthInZ() const { return _max.z - _min.z;}
|
||||
|
||||
bool PointInBBox( const Vec3f &pt ) const;
|
||||
|
||||
bool ViewFrustumCull( const Camera &cam, const Mat44f &mat );
|
||||
|
||||
void Transform(const Mat44f& mat);
|
||||
|
||||
// Reset the bounding box
|
||||
void Clear();
|
||||
|
||||
void Display() const;
|
||||
|
||||
protected:
|
||||
void _UpdateSphere();
|
||||
void _CalcVerts(Vec3f pVerts[8]) const;
|
||||
|
||||
private:
|
||||
Vec3f _min; // Original object space BV
|
||||
Vec3f _max;
|
||||
};
|
||||
|
||||
#endif //__SKYMINMAXBOX_HPP__
|
||||
@@ -0,0 +1,116 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderable.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderable.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// Sky : Copyright 2002 Mark J. Harris and Andrew Zaferakis
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @file SkyRenderable.hpp
|
||||
*
|
||||
* Abstract base class definition for SkyRenderable, a renderable object class.
|
||||
*/
|
||||
#ifndef __SKYRENDERABLE_HPP__
|
||||
#define __SKYRENDERABLE_HPP__
|
||||
|
||||
#pragma warning( disable : 4786)
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
// forward to reduce unnecessary dependencies
|
||||
class SkyMinMaxBox;
|
||||
class SkyRenderableInstance;
|
||||
class Camera;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyRenderable
|
||||
* @brief An base class for renderable objects.
|
||||
*
|
||||
* Each SkyRenderable object should know how to Display itself, however some
|
||||
* objects may not have a bounding volume that is useful (skybox, etc.)
|
||||
*/
|
||||
class SkyRenderable
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
SkyRenderable() {}
|
||||
//! Destructor
|
||||
virtual ~SkyRenderable() { }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SetName
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SetName(const std::string &name)
|
||||
* @brief Set a name for this renderable.
|
||||
*/
|
||||
void SetName(const std::string &name) { _name = name; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : GetName
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn GetName() const
|
||||
* @brief Get the name of this renderable.
|
||||
*/
|
||||
const std::string& GetName() const { return _name; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Update
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn Update(const Camera &cam, SkyRenderableInstance *pInstance)
|
||||
* @brief Update the state of the renderable.
|
||||
*
|
||||
* This method is optional, as some renderables will need periodic updates
|
||||
* (i.e. for animation) and others will not.
|
||||
*/
|
||||
virtual SKYRESULT Update(const Camera &cam, SkyRenderableInstance *pInstance = NULL)
|
||||
{ return SKYRESULT_OK; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Display
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn Display(const Camera &cam, SkyRenderableInstance *pInstance)
|
||||
* @brief Display the object.
|
||||
*/
|
||||
virtual SKYRESULT Display(const Camera &cam, SkyRenderableInstance *pInstance = NULL) = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : CopyBoundingVolume
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn CopyBoundingVolume() const
|
||||
* @brief Create a copy of the object's bounding volume, useful for collision, VFC, etc.
|
||||
*/
|
||||
virtual SkyMinMaxBox* CopyBoundingVolume() const = 0;// { return 0; }
|
||||
|
||||
protected:
|
||||
std::string _name; // the name of this renderable.
|
||||
};
|
||||
|
||||
#endif //__SKYRENDERABLE_HPP__
|
||||
@@ -0,0 +1,202 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderableInstance.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyRenderableInstance.hpp
|
||||
*
|
||||
* Interface definition for SkyRenderableInstance, an instance of a renderable object.
|
||||
*/
|
||||
#ifndef __SKYRENDERABLEINSTANCE_HPP__
|
||||
#define __SKYRENDERABLEINSTANCE_HPP__
|
||||
|
||||
#include <vector>
|
||||
#include "mat33.hpp"
|
||||
#include "mat44.hpp"
|
||||
#include "SkyUtil.hpp"
|
||||
|
||||
// forward to reduce unnecessary dependencies
|
||||
class Camera;
|
||||
class SkyMinMaxBox;
|
||||
|
||||
// forward so we can make the following typedefs easily visible in the header.
|
||||
// rather than buried under the class definition.
|
||||
class SkyRenderableInstance;
|
||||
|
||||
//! A dynamic array of SkyRenderableInstance pointers.
|
||||
typedef std::vector<SkyRenderableInstance*> InstanceArray;
|
||||
//! An instance array iterator.
|
||||
typedef InstanceArray::iterator InstanceIterator;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyRenderableInstance
|
||||
* @brief An instance of a SkyRenderable object.
|
||||
*
|
||||
* An instance contains a pointer to a SkyRenderable object. The
|
||||
* instance contains attributes such as position, orientation,
|
||||
* scale, etc. that vary between instances.
|
||||
*/
|
||||
class SkyRenderableInstance
|
||||
{
|
||||
public:
|
||||
//! Constructor.
|
||||
SkyRenderableInstance()
|
||||
: _bCulled(false), _bAlive(true), _vecPosition(0, 0, 0), _rScale(1), _rSquareSortDistance(0)
|
||||
{
|
||||
_matRotation.Identity(); _matInvRotation.Identity();
|
||||
}
|
||||
|
||||
//! Constructor.
|
||||
SkyRenderableInstance(const Vec3f &position,
|
||||
const Mat33f &rotation,
|
||||
const float scale)
|
||||
: _bCulled(false), _bAlive(true), _vecPosition(position),
|
||||
_matRotation(rotation), _rScale(scale), _rSquareSortDistance(0)
|
||||
{
|
||||
_matInvRotation = _matRotation;
|
||||
_matInvRotation.Transpose();
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
virtual ~SkyRenderableInstance() {}
|
||||
|
||||
// Setters / Getters
|
||||
//! Set the world space position of the instance.
|
||||
virtual void SetPosition(const Vec3f &position) { _vecPosition = position; }
|
||||
//! Set the world space rotation of the instance.
|
||||
virtual void SetRotation(const Mat33f &rotation) { _matRotation = rotation;
|
||||
_matInvRotation = rotation;
|
||||
_matInvRotation.Transpose(); }
|
||||
//! Set the world space scale of the instance.
|
||||
virtual void SetScale( const float &scale) { _rScale = scale; }
|
||||
|
||||
//! Returns the world space position of the instance.
|
||||
virtual const Vec3f& GetPosition() const { return _vecPosition; }
|
||||
//! Returns the world space rotation matrix of the instance.
|
||||
virtual const Mat33f& GetRotation() const { return _matRotation; }
|
||||
//! Returns the inverse of the world space rotation matrix of the instance.
|
||||
virtual const Mat33f& GetInverseRotation() const { return _matInvRotation; }
|
||||
//! Returns the world space scale of the instance.
|
||||
virtual float GetScale() const { return _rScale; }
|
||||
|
||||
//! Update the instance based on the given camera, @a cam.
|
||||
virtual SKYRESULT Update(const Camera &cam) { return SKYRESULT_OK; }
|
||||
//! Render the instance.
|
||||
virtual SKYRESULT Display() { return SKYRESULT_OK; }
|
||||
|
||||
//! Returns the transform matrix from model space to world space.
|
||||
inline virtual void GetModelToWorldTransform(Mat44f &mat) const;
|
||||
|
||||
//! Returns the transform matrix from world space to model space.
|
||||
|
||||
inline virtual void GetWorldToModelTransform(Mat44f &mat) const;
|
||||
|
||||
//! Returns the object-space bounding volume for this instance, or NULL if none is available.
|
||||
virtual SkyMinMaxBox* GetBoundingVolume() const { return NULL; }
|
||||
|
||||
//! Returns true if and only if the bounding volume of this instance lies entirely outside @a cam.
|
||||
virtual bool ViewFrustumCull(const Camera &cam) { return false; }
|
||||
//! Returns true if the instance was culled.
|
||||
virtual bool IsCulled() { return _bCulled; }
|
||||
//! Sets the culled state of the instance.
|
||||
virtual void SetCulled(bool bCulled) { _bCulled = bCulled; }
|
||||
|
||||
//! Returns true if the instance is currently active.
|
||||
virtual bool IsAlive() { return _bAlive; }
|
||||
//! Activates or deactivates the instance.
|
||||
virtual void SetIsAlive(bool bAlive) { _bAlive = bAlive; }
|
||||
|
||||
//! Sets the distance of this object from the sort position. Used to sort instances.
|
||||
virtual void SetSquareSortDistance(float rSqrDist) { _rSquareSortDistance = rSqrDist; }
|
||||
//! Returns the distance of this object from the sort position. (Set with SetSquareSortDistance())
|
||||
virtual float GetSquareSortDistace() const { return _rSquareSortDistance; }
|
||||
|
||||
//! This operator is used to sort instance arrays.
|
||||
bool operator<(const SkyRenderableInstance& instance) const
|
||||
{
|
||||
return (_rSquareSortDistance > instance._rSquareSortDistance);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _bCulled; // Culled flag
|
||||
bool _bAlive; // Alive object flag
|
||||
|
||||
Vec3f _vecPosition; // Position
|
||||
Mat33f _matRotation; // Rotation
|
||||
Mat33f _matInvRotation; // inverse rotation
|
||||
float _rScale; // Scale
|
||||
|
||||
// for sorting particles during shading
|
||||
float _rSquareSortDistance;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstance::GetModelToWorldTransform
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstance::GetModelToWorldTransform(Mat44f &mat) const
|
||||
* @brief Returns the 4x4 transformation matrix from world to model space.
|
||||
*/
|
||||
inline void SkyRenderableInstance::GetModelToWorldTransform(Mat44f &mat) const
|
||||
{
|
||||
mat[0] = _matRotation.M[0]; mat[4] = _matRotation.M[3];
|
||||
mat[8] = _matRotation.M[6]; mat[12] = 0;
|
||||
mat[1] = _matRotation.M[1]; mat[5] = _matRotation.M[4];
|
||||
mat[9] = _matRotation.M[7]; mat[13] = 0;
|
||||
mat[2] = _matRotation.M[2]; mat[6] = _matRotation.M[5];
|
||||
mat[10] = _matRotation.M[8]; mat[14] = 0;
|
||||
mat[3] = 0; mat[7] = 0; mat[11] = 0; mat[15] = 0;
|
||||
|
||||
// Scale the matrix (we don't want to scale translation or mat[15] which is 1)
|
||||
if (_rScale != 1)
|
||||
mat *= _rScale;
|
||||
|
||||
// Set the translation and w coordinate after the potential scaling
|
||||
mat[12] = _vecPosition.x; mat[13] = _vecPosition.y; mat[14] = _vecPosition.z;
|
||||
mat[15] = 1;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Mat44f& SkyRenderableInstance::GetWorldToModelTransform
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstance::GetWorldToModelTransform(Mat44f &mat) const
|
||||
* @brief Returns the 4x4 transformation matrix from world to model space.
|
||||
*/
|
||||
inline void SkyRenderableInstance::GetWorldToModelTransform(Mat44f &mat) const
|
||||
{
|
||||
mat[0] = _matRotation.M[0]; mat[4] = _matRotation.M[1];
|
||||
mat[8] = _matRotation.M[2]; mat[12] = 0;
|
||||
mat[1] = _matRotation.M[3]; mat[5] = _matRotation.M[4];
|
||||
mat[9] = _matRotation.M[5]; mat[13] = 0;
|
||||
mat[2] = _matRotation.M[6]; mat[6] = _matRotation.M[7];
|
||||
mat[10] = _matRotation.M[8]; mat[14] = 0;
|
||||
mat[3] = 0; mat[7] = 0; mat[11] = 0; mat[15] = 0;
|
||||
|
||||
// Scale the matrix (we don't want to scale translation or mat[15] which is 1)
|
||||
if (_rScale != 1)
|
||||
mat *= (1 / _rScale);
|
||||
|
||||
// Set the translation and w coordinate after the potential scaling
|
||||
mat[12] = -_vecPosition.x; mat[13] = -_vecPosition.y; mat[14] = -_vecPosition.z;
|
||||
mat[15] = 1;
|
||||
}
|
||||
|
||||
#endif //__SKYRENDERABLEINSTANCE_HPP__
|
||||
@@ -0,0 +1,708 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderableInstanceCloud.cpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyRenderableInstanceCloud.cpp
|
||||
*
|
||||
* Implementation of class SkyRenderableInstanceCloud.
|
||||
*/
|
||||
#include "SkyUtil.hpp"
|
||||
#include "SkyCloud.hpp"
|
||||
#include "SkyMaterial.hpp"
|
||||
#include "SkyBoundingVolume.hpp"
|
||||
#include "SkyRenderableInstanceCloud.hpp"
|
||||
#include "SkyDynamicTextureManager.hpp"
|
||||
|
||||
//! Set this to 1 to see verbose messages about impostor updates.
|
||||
#define SKYCLOUD_VERBOSE 0
|
||||
|
||||
//! Set this to control the number of frames a cloud has to be culled before its textures are released.
|
||||
#define SKYCLOUD_CULL_RELEASE_COUNT 100
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Static declarations.
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int SkyRenderableInstanceCloud::s_iCount = 0;
|
||||
float SkyRenderableInstanceCloud::s_rErrorToleranceAngle = SKYDEGREESTORADS * 0.125f;
|
||||
SkyMaterial* SkyRenderableInstanceCloud::s_pMaterial = NULL;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::SkyRenderableInstanceCloud
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud, bool bUseOffScreenBuffer)
|
||||
* @brief Constructor.
|
||||
*/
|
||||
SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud,
|
||||
bool bUseOffScreenBuffer /* = true */)
|
||||
: SkyRenderableInstance(),
|
||||
_iCloudID(-1),
|
||||
_pCloud(pCloud),
|
||||
_pWorldSpaceBV(NULL),
|
||||
_rRadius(0),
|
||||
_bScreenImpostor(false),
|
||||
_bImageExists(false),
|
||||
_bEnabled(true),
|
||||
_bUseOffScreenBuffer(bUseOffScreenBuffer),
|
||||
_bSplit(false),
|
||||
_vecSplit(0, 0, 0),
|
||||
_vecNearPoint(0, 0, 0),
|
||||
_vecFarPoint(0, 0, 0),
|
||||
_iLogResolution(0),
|
||||
_pBackTexture(NULL),
|
||||
_pFrontTexture(NULL),
|
||||
_iCulledCount(0)
|
||||
{
|
||||
_Initialize();
|
||||
// cout << "Cloud Instance created" << endl;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::SkyRenderableInstanceCloud
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud, const Vec3f &position, const Mat33f &rotation, const float scale, bool bUseOffScreenBuffer)
|
||||
* @brief Constructor.
|
||||
*/
|
||||
SkyRenderableInstanceCloud::SkyRenderableInstanceCloud(SkyCloud *pCloud,
|
||||
const Vec3f &position,
|
||||
const Mat33f &rotation,
|
||||
const float scale,
|
||||
bool bUseOffScreenBuffer /* = true */)
|
||||
: SkyRenderableInstance(position, rotation, scale),
|
||||
_iCloudID(-1),
|
||||
_pCloud(pCloud),
|
||||
_pWorldSpaceBV(NULL),
|
||||
_rRadius(0),
|
||||
_bScreenImpostor(false),
|
||||
_bImageExists(false),
|
||||
_bEnabled(true),
|
||||
_bUseOffScreenBuffer(false),
|
||||
_bSplit(false),
|
||||
_vecSplit(0, 0, 0),
|
||||
_vecNearPoint(0, 0, 0),
|
||||
_vecFarPoint(0, 0, 0),
|
||||
_iLogResolution(0),
|
||||
_pBackTexture(NULL),
|
||||
_pFrontTexture(NULL)
|
||||
{
|
||||
_Initialize();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud()
|
||||
* @brief Destructor
|
||||
*/
|
||||
SkyRenderableInstanceCloud::~SkyRenderableInstanceCloud()
|
||||
{
|
||||
_pCloud = NULL;
|
||||
SAFE_DELETE(_pWorldSpaceBV);
|
||||
|
||||
s_iCount--;
|
||||
// delete the offscreen buffer when no one else is using it.
|
||||
if (0 == s_iCount)
|
||||
{
|
||||
//JW?? SAFE_DELETE(s_pRenderBuffer);
|
||||
SAFE_DELETE(s_pMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::SetPosition
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SetPosition(const Vec3f &position)
|
||||
* @brief Set the world space position of the instance.
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyRenderableInstanceCloud::SetPosition FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::SetPosition(const Vec3f &position)
|
||||
{
|
||||
if (_pCloud)
|
||||
{
|
||||
_pCloud->Translate(position - _vecPosition);
|
||||
}
|
||||
_vecPosition = position;
|
||||
|
||||
_UpdateWorldSpaceBounds();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::SetRotation
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SetRotation(const Mat33f &rotation)
|
||||
* @brief Set the world space rotation of the instance.
|
||||
*
|
||||
* @todo <WRITE EXTENDED SkyRenderableInstanceCloud::SetRotation FUNCTION DOCUMENTATION>
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::SetRotation(const Mat33f &rotation)
|
||||
{
|
||||
if (_pCloud)
|
||||
{
|
||||
_pCloud->Translate(-_vecPosition);
|
||||
_pCloud->Rotate(_matInvRotation * rotation);
|
||||
_pCloud->Translate(_vecPosition);
|
||||
}
|
||||
_matRotation = rotation;
|
||||
_matInvRotation = rotation;
|
||||
_matInvRotation.Transpose();
|
||||
_UpdateWorldSpaceBounds();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::SetScale
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SetScale(const float &scale)
|
||||
* @brief Set the world space scale of the instance.
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::SetScale(const float &scale)
|
||||
{
|
||||
if (_pCloud)
|
||||
{
|
||||
_pCloud->Translate(-_vecPosition);
|
||||
_pCloud->Scale(scale);
|
||||
_pCloud->Translate(_vecPosition);
|
||||
}
|
||||
_rScale = scale;
|
||||
_UpdateWorldSpaceBounds();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : DrawQuad
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
|
||||
* @brief Simply draws an OpenGL quad at @a pos.
|
||||
*
|
||||
* The quad's size and orientation are determined by the (non-unit) vectors @a x
|
||||
* and @a y. Its color is given by @a color.
|
||||
*/
|
||||
inline void DrawQuad(Vec3f pos, Vec3f x, Vec3f y, Vec4f color)
|
||||
{
|
||||
glColor4fv(&(color.x));
|
||||
Vec3f left = pos; left -= y;
|
||||
Vec3f right = left; right += x;
|
||||
left -= x;
|
||||
glTexCoord2f(0, 0); glVertex3fv(&(left.x));
|
||||
glTexCoord2f(1, 0); glVertex3fv(&(right.x));
|
||||
left += y; left += y;
|
||||
right += y; right += y;
|
||||
glTexCoord2f(1, 1); glVertex3fv(&(right.x));
|
||||
glTexCoord2f(0, 1); glVertex3fv(&(left.x));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::Display
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::Display(bool bDisplayFrontOfSplit)
|
||||
* @brief Display the instance of the cloud using the impostor image.
|
||||
*/
|
||||
SKYRESULT SkyRenderableInstanceCloud::Display(bool bDisplayFrontOfSplit /* = false */)
|
||||
{
|
||||
|
||||
if (!_bImageExists || !_bEnabled)
|
||||
{
|
||||
//FAIL_RETURN(DisplayWithoutImpostor(*(GLVU::GetCurrent()->GetCurrentCam())));
|
||||
FAIL_RETURN(DisplayWithoutImpostor(Camera()));
|
||||
}
|
||||
else
|
||||
{//cout << "Using impostor image\n";
|
||||
if (!_pBackTexture || (bDisplayFrontOfSplit && !_pFrontTexture)) {
|
||||
// cout << "texture id failure" << endl;
|
||||
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyRenderableInstanceCloud::Display(): missing texture!");
|
||||
}
|
||||
|
||||
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, bDisplayFrontOfSplit ? *_pFrontTexture : *_pBackTexture);
|
||||
if (_bScreenImpostor)
|
||||
{
|
||||
s_pMaterial->EnableDepthTest(false);
|
||||
}
|
||||
else if (_bSplit)
|
||||
{
|
||||
if (!bDisplayFrontOfSplit)
|
||||
{
|
||||
s_pMaterial->EnableDepthTest(true);
|
||||
s_pMaterial->SetDepthMask(false);
|
||||
}
|
||||
else
|
||||
s_pMaterial->EnableDepthTest(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_pMaterial->EnableDepthTest(true);
|
||||
s_pMaterial->SetDepthMask(true);
|
||||
}
|
||||
|
||||
s_pMaterial->Activate();
|
||||
// s_pMaterial->Force();
|
||||
|
||||
Vec3f x, y, z;
|
||||
|
||||
if (!_bScreenImpostor)
|
||||
{//cout << "Outside the cloud\n";
|
||||
z = _vecPosition;
|
||||
z -= _impostorCam.Orig;
|
||||
z.Normalize();
|
||||
x = (z ^ _impostorCam.Y);
|
||||
x.Normalize();
|
||||
x *= _rRadius;
|
||||
y = (x ^ z);
|
||||
y.Normalize();
|
||||
y *= _rRadius;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
DrawQuad(_vecPosition, x, y, Vec4f(1, 1, 1, 1));
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{ //cout << "Drawing a polygon - must be inside a cloud\n";
|
||||
x = _impostorCam.X;
|
||||
x *= 0.5f * (_impostorCam.wR - _impostorCam.wL);
|
||||
y = _impostorCam.Y;
|
||||
y *= 0.5f * (_impostorCam.wT - _impostorCam.wB);
|
||||
z = -_impostorCam.Z;
|
||||
z *= _impostorCam.Near;
|
||||
|
||||
// draw a polygon with this texture...
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(-1, 1, -1, 1);
|
||||
|
||||
glColor4f(1, 1, 1, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0); glVertex2f(-1, -1);
|
||||
glTexCoord2f(1, 0); glVertex2f(1, -1);
|
||||
glTexCoord2f(1, 1); glVertex2f(1, 1);
|
||||
glTexCoord2f(0, 1); glVertex2f(-1, 1);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::DisplayWithoutImpostor
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::DisplayWithoutImpostor(const Camera &cam)
|
||||
* @brief Displays the cloud directly -- without an impotor.
|
||||
*
|
||||
* This is used both when the impostor is disabled and to create the impostor image
|
||||
* when it needs to be updated.
|
||||
*/
|
||||
SKYRESULT SkyRenderableInstanceCloud::DisplayWithoutImpostor(const Camera &cam)
|
||||
{
|
||||
// Get and set the world space transformation
|
||||
/*Mat44f mat;
|
||||
GetModelToWorldTransform(mat);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glMultMatrixf(mat.M);*/
|
||||
|
||||
FAIL_RETURN_MSG(_pCloud->Display(cam, this), "SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
|
||||
|
||||
//glMatrixMode(GL_MODELVIEW);
|
||||
//glPopMatrix();
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::ViewFrustumCull
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::ViewFrustumCull(const Camera &cam)
|
||||
* @brief View frustum cull the object given its world position
|
||||
*/
|
||||
bool SkyRenderableInstanceCloud::ViewFrustumCull(const Camera &cam)
|
||||
{
|
||||
Mat44f xform;
|
||||
//GetModelToWorldTransform(xform);
|
||||
xform.Identity();
|
||||
_bCulled = (_pWorldSpaceBV == NULL) ? false : _pWorldSpaceBV->ViewFrustumCull(cam, xform);
|
||||
return _bCulled;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::ReleaseImpostorTextures
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::ReleaseImpostorTextures()
|
||||
* @brief Causes the instance to release its impostor textures for use by other impostors.
|
||||
*
|
||||
* This method is called when the cloud is view frustum culled.
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::ReleaseImpostorTextures()
|
||||
{
|
||||
_iCulledCount++;
|
||||
|
||||
if (_iCulledCount > SKYCLOUD_CULL_RELEASE_COUNT)
|
||||
{
|
||||
_iCulledCount = 0;
|
||||
|
||||
if (_pBackTexture)
|
||||
{
|
||||
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
|
||||
_pBackTexture = NULL;
|
||||
}
|
||||
|
||||
if (_pFrontTexture)
|
||||
{
|
||||
DynamicTextureManager::InstancePtr()->CheckInTexture(_pFrontTexture);
|
||||
_pFrontTexture = NULL;
|
||||
}
|
||||
_bImageExists = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::Update
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::Update(const Camera &cam)
|
||||
* @brief Updates the impostor image to be valid for the current viewpoint.
|
||||
*
|
||||
* If the image is already valid, exits early.
|
||||
*
|
||||
* @see SetErrorToleranceAngle, IsValid
|
||||
*/
|
||||
SKYRESULT SkyRenderableInstanceCloud::Update(const Camera &cam)
|
||||
{
|
||||
if (!_bEnabled || IsImpostorValid(cam))
|
||||
return SKYRESULT_OK;
|
||||
|
||||
// since we are going to update it anyway, let's make sure we don't try to use it if something
|
||||
// goes wrong. This will be set to true on the successful completion of this Update() method.
|
||||
_bImageExists = false;
|
||||
//cout << "updating impostor\n";
|
||||
Mat44f M;
|
||||
|
||||
_impostorCam = cam;
|
||||
float rDistance = (_vecPosition - cam.Orig).Length();
|
||||
|
||||
float rRadius = _pWorldSpaceBV->GetRadius();
|
||||
float rCamRadius = sqrt(cam.wR*cam.wR + cam.Near*cam.Near);
|
||||
|
||||
float rWidth = cam.wR - cam.wL;
|
||||
float rHeight = cam.wT - cam.wB;
|
||||
float rMaxdim = (rWidth > rHeight) ? rWidth : rHeight;
|
||||
|
||||
if (rRadius * cam.Near / rDistance < 0.5 * rMaxdim && (rDistance - rRadius > rCamRadius))
|
||||
{ // outside cloud
|
||||
_impostorCam.TightlyFitToSphere(cam.Orig, cam.Y, _vecPosition, rRadius);
|
||||
_rRadius = 0.5f * (_impostorCam.wR - _impostorCam.wL) * rDistance / _impostorCam.Near;
|
||||
_rRadius *= GetScale();
|
||||
_bScreenImpostor = false;
|
||||
// store points used in later error estimation
|
||||
_vecNearPoint = -_impostorCam.Z;
|
||||
_vecNearPoint *= _impostorCam.Near;
|
||||
_vecNearPoint += _impostorCam.Orig;
|
||||
_vecFarPoint = -_impostorCam.Z;
|
||||
_vecFarPoint *= _impostorCam.Far;
|
||||
_vecFarPoint += _impostorCam.Orig;
|
||||
}
|
||||
else // inside cloud
|
||||
{
|
||||
_impostorCam.Far = _impostorCam.Near + 3 * rRadius;
|
||||
_bScreenImpostor = true;
|
||||
}
|
||||
|
||||
// resolution based on screensize, distance, and object size.
|
||||
// Cam radius is used to heuristically reduce resolution for clouds very close to the camera.
|
||||
_iLogResolution = _GetRequiredLogResolution(rDistance, rRadius, rCamRadius);
|
||||
|
||||
int iRes = 1 << _iLogResolution;
|
||||
|
||||
int iOldVP[4];
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, iOldVP);
|
||||
|
||||
_impostorCam.GetProjectionMatrix(M);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(M);
|
||||
|
||||
_impostorCam.GetModelviewMatrix(M);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(M);
|
||||
|
||||
glViewport(0, 0, iRes, iRes);
|
||||
|
||||
s_pMaterial->SetDepthMask(true); // so that the depth buffer gets cleared!
|
||||
s_pMaterial->Activate();
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (!_bSplit)
|
||||
{
|
||||
FAIL_RETURN(DisplayWithoutImpostor(_impostorCam));
|
||||
|
||||
if (_pBackTexture && _pBackTexture->GetWidth() != iRes)
|
||||
{
|
||||
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
|
||||
_pBackTexture = NULL;
|
||||
}
|
||||
|
||||
if (!_pBackTexture)
|
||||
{
|
||||
_pBackTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
|
||||
}
|
||||
|
||||
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, *_pBackTexture); // shared material for clouds.
|
||||
s_pMaterial->Activate();
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_RETURN_MSG(_pCloud->DisplaySplit(cam, _vecSplit, true, this),
|
||||
"SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
|
||||
|
||||
if (_pBackTexture && _pBackTexture->GetWidth() != iRes)
|
||||
{
|
||||
DynamicTextureManager::InstancePtr()->CheckInTexture(_pBackTexture);
|
||||
_pBackTexture = NULL;
|
||||
}
|
||||
if (_pFrontTexture && _pFrontTexture->GetWidth() != iRes)
|
||||
{
|
||||
DynamicTextureManager::InstancePtr()->CheckInTexture(_pFrontTexture);
|
||||
_pFrontTexture = NULL;
|
||||
}
|
||||
|
||||
if (!_pBackTexture)
|
||||
{
|
||||
_pBackTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
|
||||
}
|
||||
|
||||
s_pMaterial->SetTexture(0, GL_TEXTURE_2D, *_pBackTexture); // shared material for clouds.
|
||||
FAIL_RETURN(s_pMaterial->Activate());
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
|
||||
|
||||
// now clear and draw the front.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
FAIL_RETURN_MSG(_pCloud->DisplaySplit(cam, _vecSplit, false, this),
|
||||
"SkyRenderableInstanceCloud:Display(): Cloud's display failed.");
|
||||
|
||||
if (!_pFrontTexture)
|
||||
{
|
||||
_pFrontTexture = DynamicTextureManager::InstancePtr()->CheckOutTexture(iRes, iRes);
|
||||
}
|
||||
|
||||
s_pMaterial->GetTextureState().SetTexture(0, GL_TEXTURE_2D, *_pFrontTexture);
|
||||
FAIL_RETURN(s_pMaterial->GetTextureState().Activate());
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, iRes, iRes);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
//GLVU::CheckForGLError("Cloud Impostor Update");
|
||||
|
||||
glViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]);
|
||||
|
||||
_bImageExists = true;
|
||||
|
||||
// the textures should now exist.
|
||||
assert(_pBackTexture);
|
||||
assert(!_bSplit || (_bSplit && _pFrontTexture));
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::IsImpostorValid
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::IsImpostorValid(const Camera& cam)
|
||||
* @brief Returns true if the impostor image is valid for the given camera.
|
||||
*
|
||||
* Will return false if this is a screen impostor, or if there is error in either
|
||||
* the translation of the camera from the capture point or the impostor image resolution.
|
||||
*
|
||||
* @see SetErrorToleranceAngle
|
||||
*/
|
||||
bool SkyRenderableInstanceCloud::IsImpostorValid(const Camera& cam)
|
||||
{
|
||||
// first make sure there is a current image.
|
||||
if (!_bImageExists)
|
||||
return false;
|
||||
|
||||
// screen impostors should always be updated
|
||||
if (_bScreenImpostor)
|
||||
{
|
||||
_vecFarPoint = Vec3f::ZERO;
|
||||
_vecNearPoint = Vec3f::ZERO;
|
||||
#if SKYCLOUD_VERBOSE
|
||||
SkyTrace("Screen Impostor Update");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
// impostors are valid from the viewpoint from which they were captured
|
||||
if (cam.Orig == _impostorCam.Orig)
|
||||
return true;
|
||||
|
||||
if (_bSplit)
|
||||
{
|
||||
#if SKYCLOUD_VERBOSE
|
||||
SkyTrace("Split Impostor Update");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
Vec3f vecX = _vecNearPoint - cam.Orig;
|
||||
Vec3f vecY = _vecFarPoint - cam.Orig;
|
||||
float rXLength = vecX.Length();
|
||||
float rYLength = vecY.Length();
|
||||
if (rXLength > rYLength)
|
||||
{
|
||||
#if SKYCLOUD_VERBOSE
|
||||
SkyTrace("Backwards Impostor Update");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
vecX /= rXLength;
|
||||
vecY /= rYLength;
|
||||
float rCosAlpha = vecX * vecY; // dot product of normalized vectors = cosine
|
||||
|
||||
if (fabs(rCosAlpha) < 1.0)
|
||||
{
|
||||
float rAlpha = acos(rCosAlpha);
|
||||
if (rAlpha >= s_rErrorToleranceAngle)
|
||||
{
|
||||
#if SKYCLOUD_VERBOSE
|
||||
SkyTrace("Angle Error Update %f", SKYRADSTODEGREES * rAlpha);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float rDistance = (_vecPosition - cam.Orig).Length();
|
||||
float rCamRadius = sqrt(cam.wR*cam.wR + cam.Near*cam.Near);
|
||||
|
||||
int iRes = _GetRequiredLogResolution(rDistance, _pWorldSpaceBV->GetRadius(), rCamRadius);
|
||||
|
||||
if (iRes > _iLogResolution)
|
||||
{
|
||||
#if SKYCLOUD_VERBOSE
|
||||
SkyTrace("Resolution Error Update: Required: %d Actual: %d", iRes, _iLogResolution);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SetErrorToleranceAngle
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::SetErrorToleranceAngle(float rDegrees)
|
||||
* @brief Set the global error tolerance angle for all impostors.
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::SetErrorToleranceAngle(float rDegrees)
|
||||
{
|
||||
s_rErrorToleranceAngle = SKYDEGREESTORADS * rDegrees;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::_Initialize
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::_Initialize()
|
||||
* @brief Initializer used by the constructors.
|
||||
*/
|
||||
void SkyRenderableInstanceCloud::_Initialize()
|
||||
{
|
||||
_UpdateWorldSpaceBounds();
|
||||
|
||||
// if (!s_pRenderBuffer && _bUseOffScreenBuffer)
|
||||
// {
|
||||
//JW?? s_pRenderBuffer = new SkyOffScreenBuffer(GLUT_SINGLE | GLUT_DEPTH | GLUT_STENCIL);
|
||||
//JW?? s_pRenderBuffer->Initialize(true);
|
||||
|
||||
//JW?? s_pRenderBuffer->MakeCurrent();
|
||||
// set some GL state:
|
||||
// glClearColor(0, 0, 0, 0);
|
||||
//JW?? GLVU::GetCurrent()->MakeCurrent();
|
||||
// }
|
||||
if (!s_pMaterial)
|
||||
{
|
||||
s_pMaterial = new SkyMaterial;
|
||||
s_pMaterial->EnableBlending(true);
|
||||
s_pMaterial->SetBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
s_pMaterial->SetAlphaFunc(GL_GREATER);
|
||||
s_pMaterial->EnableDepthTest(false);
|
||||
s_pMaterial->SetDepthMask(true);
|
||||
s_pMaterial->EnableAlphaTest(true);
|
||||
s_pMaterial->EnableLighting(false);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
s_pMaterial->SetTextureParameter(0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
s_pMaterial->EnableTexture(0, true);
|
||||
}
|
||||
s_iCount++;
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderableInstanceCloud.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or implied warranty.
|
||||
/**
|
||||
* @file SkyRenderableInstanceCloud.hpp
|
||||
*
|
||||
* Interface for class SkyRenderableInstanceCloud, an instance of a SkyCloud object.
|
||||
*/
|
||||
#ifndef __SKYRENDERABLEINSTANCECLOUD_HPP__
|
||||
#define __SKYRENDERABLEINSTANCECLOUD_HPP__
|
||||
|
||||
class SkyCloud;
|
||||
class SkyTexture;
|
||||
//class SkyOffScreenBuffer;
|
||||
|
||||
#include <vector>
|
||||
#include "camera.hpp"
|
||||
#include "SkyContext.hpp"
|
||||
#include "SkyRenderableInstance.hpp"
|
||||
#include "SkyRenderableInstanceGeneric.hpp"
|
||||
#include "SkyCloud.hpp"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyRenderableInstanceCloud
|
||||
* @brief An instance of a cloud. Renders using an impostor.
|
||||
*
|
||||
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
|
||||
*/
|
||||
class SkyRenderableInstanceCloud : public SkyRenderableInstance
|
||||
{
|
||||
public:
|
||||
SkyRenderableInstanceCloud( SkyCloud *pCloud, bool bUseOffScreenBuffer = false);
|
||||
SkyRenderableInstanceCloud( SkyCloud *pCloud,
|
||||
const Vec3f &position,
|
||||
const Mat33f &rotation,
|
||||
const float scale,
|
||||
bool bUseOffScreenBuffer = false);
|
||||
virtual ~SkyRenderableInstanceCloud();
|
||||
|
||||
// Setters / Getters
|
||||
//! Sets the identifier for this cloud (used by SkySceneManager.)
|
||||
void SetID(int id) { _iCloudID = id; }
|
||||
|
||||
virtual void SetPosition(const Vec3f &position);
|
||||
|
||||
virtual void SetRotation(const Mat33f &rotation);
|
||||
|
||||
virtual void SetScale(const float &scale);
|
||||
|
||||
//! Returns SkySceneManager's id for this cloud.
|
||||
int GetID() const { return _iCloudID; }
|
||||
//! Returns a pointer to the renderable that this instance represents.
|
||||
virtual SkyCloud* GetCloud() const { return _pCloud; }
|
||||
|
||||
//! Returns the world space bounding box of the cloud instance.
|
||||
const SkyMinMaxBox& GetWorldSpaceBounds() { return *_pWorldSpaceBV; }
|
||||
|
||||
//! Make this into a split impostor. Will be rendered as two halves, around the split point.
|
||||
void SetSplit(bool bSplit) { _bSplit = bSplit; }
|
||||
|
||||
//! Set the distance at which the cloud will be split (from the camera position).
|
||||
void SetSplitPoint(const Vec3f& vecSplit) { _vecSplit = vecSplit; }
|
||||
|
||||
//! Returns true if this is a split impostor (cloud contains objects)
|
||||
bool IsSplit() const { return _bSplit; }
|
||||
|
||||
//! Returns true if the camera is inside this clouds bounding volume.
|
||||
bool IsScreenImpostor() const { return _bScreenImpostor; }
|
||||
|
||||
virtual SKYRESULT Update(const Camera& cam);
|
||||
virtual SKYRESULT Display(bool bDisplayFrontOfSplit = false);
|
||||
SKYRESULT DisplayWithoutImpostor(const Camera& cam);
|
||||
|
||||
virtual bool ViewFrustumCull( const Camera &cam );
|
||||
|
||||
void ReleaseImpostorTextures();
|
||||
|
||||
|
||||
virtual SkyMinMaxBox* GetBoundingVolume() const { return _pWorldSpaceBV; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Determine if the current impostor image is valid for the given viewpoint
|
||||
//----------------------------------------------------------------------------
|
||||
bool IsImpostorValid(const Camera &cam);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : Enable
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn Enable(bool bEnable)
|
||||
* @brief Enable / Disable the use of impostor images (if disabled, displays geometry).
|
||||
*/
|
||||
void Enable(bool bEnable) { _bEnabled = bEnable; }
|
||||
|
||||
static void SetErrorToleranceAngle(float rDegrees);
|
||||
|
||||
protected: // methods
|
||||
void _Initialize();
|
||||
inline int _GetRequiredLogResolution(float rObjectDistance, float rObjectRadius, float rCamRadius);
|
||||
|
||||
inline void _UpdateWorldSpaceBounds();
|
||||
|
||||
protected: // data
|
||||
int _iCloudID; // used by the scene manager to identify clouds.
|
||||
|
||||
SkyCloud *_pCloud; // Pointer to the cloud object
|
||||
SkyMinMaxBox *_pWorldSpaceBV; // Pointer to bounding volume in object space
|
||||
|
||||
float _rRadius; // Radius of the impostor.
|
||||
bool _bScreenImpostor; // Is this a screen space or world space impostor?
|
||||
bool _bImageExists; // The impostor image exists and is ready to use.
|
||||
bool _bEnabled; // if disabled, draw geometry -- otherwise, draw impostor.
|
||||
bool _bUseOffScreenBuffer; // if enabled, uses off-screen rendering to create impostor images.
|
||||
|
||||
bool _bSplit; // true if the cloud contains other object instances.
|
||||
Vec3f _vecSplit; // the point about which this cloud is split.
|
||||
|
||||
Vec3f _vecNearPoint; // Nearest point on bounding sphere to viewpoint.
|
||||
Vec3f _vecFarPoint; // Farthest point on bounding sphere from viewpoint.
|
||||
|
||||
Camera _impostorCam; // camera used to generate this impostor
|
||||
|
||||
unsigned int _iLogResolution; // Log base 2 of current impostor image resolution.
|
||||
|
||||
SkyTexture *_pBackTexture; // Back texture for split clouds or main texture for unsplit.
|
||||
SkyTexture *_pFrontTexture; // Front texture for split clouds.
|
||||
|
||||
unsigned int _iCulledCount; // used to determine when to release textures
|
||||
|
||||
static unsigned int s_iCount; // keep track of number of impostors using the render buffer.
|
||||
//JW?? static SkyOffScreenBuffer* s_pRenderBuffer;
|
||||
static float s_rErrorToleranceAngle;
|
||||
static SkyMaterial *s_pMaterial; // shared material for cloud impostors.
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyContainerCloud
|
||||
* @brief A class used to organize the rendering order of cloud impostors and the objects in the clouds
|
||||
*
|
||||
* @todo <WRITE EXTENDED CLASS DESCRIPTION>
|
||||
*/
|
||||
class SkyContainerCloud : public SkyRenderableInstance
|
||||
{
|
||||
public: // methods
|
||||
//! Constructor.
|
||||
SkyContainerCloud(SkyRenderableInstanceCloud *cloud) : SkyRenderableInstance(), pCloud(cloud) {}
|
||||
//! Destructor.
|
||||
~SkyContainerCloud()
|
||||
{ pCloud = NULL; containedOpaqueInstances.clear(); containedTransparentInstances.clear(); }
|
||||
|
||||
virtual SKYRESULT Display()
|
||||
{
|
||||
// display the back half of the split impostor.
|
||||
FAIL_RETURN_MSG(pCloud->Display(false),
|
||||
"SkySceneManager::Display(): cloud instance display failed.");
|
||||
|
||||
if (pCloud->IsSplit())
|
||||
{
|
||||
// display contained instances -- first opaque, then transparent.
|
||||
InstanceIterator ii;
|
||||
for (ii = containedOpaqueInstances.begin(); ii != containedOpaqueInstances.end(); ++ii)
|
||||
FAIL_RETURN((*ii)->Display());
|
||||
for (ii = containedTransparentInstances.begin(); ii != containedTransparentInstances.end(); ++ii)
|
||||
FAIL_RETURN((*ii)->Display());
|
||||
|
||||
// now display the front half of the split impostor.
|
||||
FAIL_RETURN_MSG(pCloud->Display(true),
|
||||
"SkySceneManager::Display(): cloud instance display failed.");
|
||||
}
|
||||
|
||||
return SKYRESULT_OK;
|
||||
}
|
||||
|
||||
virtual const Vec3f& GetPosition() const { return pCloud->GetPosition(); }
|
||||
|
||||
public: //data -- here the data are public because the interface is minimal.
|
||||
SkyRenderableInstanceCloud *pCloud;
|
||||
|
||||
InstanceArray containedOpaqueInstances;
|
||||
InstanceArray containedTransparentInstances;
|
||||
|
||||
// This operator is used to sort ContainerCloud arrays.
|
||||
bool operator<(const SkyContainerCloud& container) const
|
||||
{
|
||||
return (*((SkyRenderableInstance*)pCloud) < *((SkyRenderableInstance*)container.pCloud));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : _GetRequiredLogResolution
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::_GetRequiredLogResolution(float rObjectDistance, float rObjectRadius, float rCamRadius)
|
||||
* @brief Returns the integer logarithm base two of the expected impostor resolution.
|
||||
*
|
||||
* Impostor resolution is based on object size, distance, and the FOV of the camera (stored as the
|
||||
* radius of a sphere centered at the camera position and passing through the corners of the
|
||||
* projection plane.
|
||||
*/
|
||||
inline int SkyRenderableInstanceCloud::_GetRequiredLogResolution(float rObjectDistance,
|
||||
float rObjectRadius,
|
||||
float rCamRadius)
|
||||
{
|
||||
int iScreenWidth, iScreenHeight;
|
||||
GraphicsContext::InstancePtr()->GetWindowSize(iScreenWidth, iScreenHeight);
|
||||
//cout << "SkyRes: w=" << iScreenWidth << "h=" << iScreenHeight << endl; char ff; cin >> ff;
|
||||
int iScreenResolution = (iScreenWidth > iScreenHeight) ? iScreenWidth : iScreenHeight;
|
||||
int iLogMinScreenResolution = (iScreenWidth > iScreenHeight) ? iScreenHeight : iScreenWidth;
|
||||
iLogMinScreenResolution = SkyGetLogBaseTwo(iLogMinScreenResolution) - 1;
|
||||
|
||||
int iRes = 2 * iScreenResolution * _pWorldSpaceBV->GetRadius() / rObjectDistance;
|
||||
int iLogResolution;
|
||||
|
||||
if (rObjectDistance - (0.5f * rObjectRadius) < rCamRadius)
|
||||
{
|
||||
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 8);
|
||||
}
|
||||
else if (rObjectDistance - rObjectRadius < rCamRadius)
|
||||
{
|
||||
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 4);
|
||||
}
|
||||
else if (iRes > iScreenResolution)
|
||||
{
|
||||
iLogResolution = SkyGetLogBaseTwo(iScreenResolution / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
iLogResolution = SkyGetLogBaseTwo(iRes);
|
||||
}
|
||||
|
||||
// if not rendering to an off screen buffer, make sure the resolution fits in the window!
|
||||
if (!_bUseOffScreenBuffer && (iLogMinScreenResolution < iLogResolution))
|
||||
iLogResolution = iLogMinScreenResolution;
|
||||
|
||||
return iLogResolution;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function : SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds
|
||||
// Description :
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @fn SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds()
|
||||
* @brief Updates the world space bounding box of the cloud.
|
||||
*/
|
||||
inline void SkyRenderableInstanceCloud::_UpdateWorldSpaceBounds()
|
||||
{
|
||||
SAFE_DELETE(_pWorldSpaceBV);
|
||||
_pWorldSpaceBV = _pCloud->CopyBoundingVolume();
|
||||
_vecPosition = _pCloud->CopyBoundingVolume()->GetCenter();
|
||||
}
|
||||
|
||||
#endif //__SKYRENDERABLEINSTANCECLOUD_HPP__
|
||||
@@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File : SkyRenderableInstanceGeneric.hpp
|
||||
//------------------------------------------------------------------------------
|
||||
// SkyWorks : Copyright 2002 Mark J. Harris and
|
||||
// The University of North Carolina at Chapel Hill
|
||||
//------------------------------------------------------------------------------
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appear in all copies and that both that copyright
|
||||
// notice and this permission notice appear in supporting documentation.
|
||||
// Binaries may be compiled with this software without any royalties or
|
||||
// restrictions.
|
||||
//
|
||||
// The author(s) and The University of North Carolina at Chapel Hill make no
|
||||
// representations about the suitability of this software for any purpose.
|
||||
// It is provided "as is" without express or
|
||||
// implied warranty.
|
||||
/**
|
||||
* @file SkyRenderableInstanceGeneric.hpp
|
||||
*
|
||||
* Interface for a basic implementation of SkyRenderableInstance
|
||||
*/
|
||||
#ifndef __SKYRENDERABLEINSTANCEGENERIC_HPP__
|
||||
#define __SKYRENDERABLEINSTANCEGENERIC_HPP__
|
||||
|
||||
#include "SkyRenderableInstance.hpp"
|
||||
|
||||
// forward to reduce unnecessary dependencies
|
||||
class SkyRenderable;
|
||||
class SkyMinMaxBox;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @class SkyRenderableInstanceGeneric
|
||||
* @brief A generic renderable instance
|
||||
*
|
||||
* The SkyRenderableInstanceGeneric is a basic implementation of the base class.
|
||||
* For view frustum culling, the function ViewFrustumCull should be called once
|
||||
* per frame, at which point a flag is set if the object is culled or not. It
|
||||
* is possible that the object is then queried multiple times if it is culled or
|
||||
* not by various other objects before being displayed, that is why the flag is
|
||||
* stored.
|
||||
*/
|
||||
class SkyRenderableInstanceGeneric : public SkyRenderableInstance
|
||||
{
|
||||
public:
|
||||
SkyRenderableInstanceGeneric(SkyRenderable *pObject);
|
||||
SkyRenderableInstanceGeneric(SkyRenderable *pObject,
|
||||
const Vec3f &position,
|
||||
const Mat33f &rotation,
|
||||
const float scale);
|
||||
virtual ~SkyRenderableInstanceGeneric();
|
||||
|
||||
// Setters / Getters
|
||||
|
||||
virtual void SetRenderable(SkyRenderable *pRenderable );
|
||||
|
||||
//! Returns a pointer to the renderable that this instance represents.
|
||||
virtual SkyRenderable* GetRenderable() const { return _pObj; }
|
||||
|
||||
virtual SKYRESULT Display();
|
||||
|
||||
// Test / Set / Get
|
||||
virtual bool ViewFrustumCull( const Camera &cam );
|
||||
|
||||
|
||||
virtual SkyMinMaxBox* GetBoundingVolume() const { return _pBV; }
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
SkyRenderable *_pObj; // Pointer to the renderable object
|
||||
SkyMinMaxBox *_pBV; // Pointer to bounding volume
|
||||
};
|
||||
|
||||
#endif //__SKYRENDERABLEINSTANCEGENERIC_HPP__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user