Compare commits
69
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c410d36e3 | ||
|
|
98a603a570 | ||
|
|
5876052170 | ||
|
|
f8303b4623 | ||
|
|
20005a7a22 | ||
|
|
4f0bfbab21 | ||
|
|
811442832e | ||
|
|
40811311d7 | ||
|
|
198de211f8 | ||
|
|
9f5412fa9d | ||
|
|
0dc9de81ae | ||
|
|
5b8f42ce5e | ||
|
|
5314274ed6 | ||
|
|
c831856711 | ||
|
|
1bade6d796 | ||
|
|
629a4a950e | ||
|
|
aebb1f6ec8 | ||
|
|
6e42bc55e0 | ||
|
|
1235fba7ee | ||
|
|
7a459db022 | ||
|
|
607987def5 | ||
|
|
397ec62180 | ||
|
|
9315210fbe | ||
|
|
5127990a43 | ||
|
|
40ad2b155a | ||
|
|
a0412d026c | ||
|
|
7d2134c488 | ||
|
|
d894f52b97 | ||
|
|
735f475c24 | ||
|
|
353dd73e24 | ||
|
|
49fe06498a | ||
|
|
bc95ec8084 | ||
|
|
f79906bf16 | ||
|
|
b3262fcb80 | ||
|
|
52b8f924aa | ||
|
|
52f57160aa | ||
|
|
6d4f23919c | ||
|
|
899623f71b | ||
|
|
c5d677ac7b | ||
|
|
c75270a9fc | ||
|
|
1588a379eb | ||
|
|
72d2075828 | ||
|
|
e99c682637 | ||
|
|
c815f70831 | ||
|
|
0da50eaa79 | ||
|
|
b0af84a549 | ||
|
|
b9631e8521 | ||
|
|
f664f7a201 | ||
|
|
f72b3882c3 | ||
|
|
ea47a2973c | ||
|
|
04be9ca670 | ||
|
|
6f0baf6ca9 | ||
|
|
1f5ec6b8d5 | ||
|
|
a2a91520aa | ||
|
|
fd7b5d3de7 | ||
|
|
30ea844c43 | ||
|
|
efac53b121 | ||
|
|
73c0ef59c1 | ||
|
|
7e65ab2d3b | ||
|
|
fec769f632 | ||
|
|
90e42642b6 | ||
|
|
9d9610a882 | ||
|
|
1fc81f4b66 | ||
|
|
4f0b1e847c | ||
|
|
9567ac32f2 | ||
|
|
8dd9cfa2a6 | ||
|
|
dbda8ef893 | ||
|
|
cd143c15d5 | ||
|
|
509a388ccc |
@@ -2,6 +2,7 @@ EXTRA_DIST = \
|
||||
acinclude.m4 \
|
||||
autogen.sh \
|
||||
DoxygenMain.cxx \
|
||||
project/VC8 \
|
||||
README.MSVC \
|
||||
README.zlib \
|
||||
projects \
|
||||
|
||||
+3
-3
@@ -261,10 +261,10 @@ OPENAL_OK="no"
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
INCLUDES="$INCLUDES -I/usr/local/include"
|
||||
INCLUDES="$INCLUDES -I/usr/local/include/"
|
||||
LIBS="$LIBS -L/usr/local/lib"
|
||||
AC_SEARCH_LIBS(alGenBuffers, openal32)
|
||||
AC_SEARCH_LIBS(alutInit, [ openal32 ALut ] )
|
||||
AC_SEARCH_LIBS(alGenBuffers, [ openal32 openal ] )
|
||||
AC_SEARCH_LIBS(alutInit, [ openal32 ALut alut ] )
|
||||
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
|
||||
openal_LIBS="$LIBS"
|
||||
OPENAL_OK="$ac_cv_search_alGenBuffers"
|
||||
|
||||
+14
-10
@@ -41,7 +41,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../AL/include;"../../../zlib-1.2.3";"../../../Pre-built.2/include""
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../devel/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -103,7 +103,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../AL/include;"../../../zlib-1.2.3";"../../../Pre-built.2/include""
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../devel/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
@@ -247,10 +247,6 @@
|
||||
RelativePath="..\..\simgear\screen\extensions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\fastmath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\timing\geocoord.h"
|
||||
>
|
||||
@@ -511,6 +507,10 @@
|
||||
RelativePath="..\..\simgear\math\sg_types.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGCMath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGGeoc.hxx"
|
||||
>
|
||||
@@ -535,6 +535,10 @@
|
||||
RelativePath="..\..\simgear\math\SGMath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGMathFwd.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGMatrix.hxx"
|
||||
>
|
||||
@@ -821,10 +825,6 @@
|
||||
RelativePath="..\..\simgear\screen\extensions.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\fastmath.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\gc.c"
|
||||
>
|
||||
@@ -973,6 +973,10 @@
|
||||
RelativePath="..\..\simgear\scene\model\personality.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\persparam.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\placement.cxx"
|
||||
>
|
||||
|
||||
@@ -128,6 +128,12 @@
|
||||
/** Knots to Miles per second */
|
||||
#define SG_KT_TO_MPS 0.5144444444444444444
|
||||
|
||||
/** Feet per second to Knots */
|
||||
#define SG_FPS_TO_KT 0.5924838012958962841
|
||||
|
||||
/** Knots to Feet per second */
|
||||
#define SG_KT_TO_FPS 1.6878098571011956874
|
||||
|
||||
/** Miles per second to Miles per hour */
|
||||
#define SG_MPS_TO_MPH 2.2369362920544020312
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
logstream *global_logstream = NULL;
|
||||
|
||||
bool logbuf::logging_enabled = true;
|
||||
#ifdef _MSC_VER
|
||||
bool logbuf::has_console = true;
|
||||
#endif
|
||||
sgDebugClass logbuf::logClass = SG_NONE;
|
||||
sgDebugPriority logbuf::logPriority = SG_INFO;
|
||||
streambuf* logbuf::sbuf = NULL;
|
||||
|
||||
@@ -139,6 +139,10 @@ public:
|
||||
*/
|
||||
void set_sb( streambuf* sb );
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static void has_no_console() { has_console = false; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
/** sync/flush */
|
||||
@@ -154,6 +158,9 @@ private:
|
||||
static streambuf* sbuf;
|
||||
|
||||
static bool logging_enabled;
|
||||
#ifdef _MSC_VER
|
||||
static bool has_console;
|
||||
#endif
|
||||
static sgDebugClass logClass;
|
||||
static sgDebugPriority logPriority;
|
||||
|
||||
@@ -184,7 +191,6 @@ inline logbuf::int_type
|
||||
logbuf::overflow( int c )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static bool has_console = false;
|
||||
if ( logging_enabled ) {
|
||||
if ( !has_console ) {
|
||||
AllocConsole();
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
* @file metar.cxx
|
||||
* Interface for encoded Meteorological Aerodrome Reports (METAR).
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef _VISUAL_ENVIRO_HXX
|
||||
#define _VISUAL_ENVIRO_HXX
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
+73
-61
@@ -23,6 +23,19 @@
|
||||
//
|
||||
// Put in some bullet-proofing to handle magnetic and geographic poles.
|
||||
// 3/28/2000 EAW
|
||||
//
|
||||
// Updated coefficient arrays to use the current WMM2005 model,
|
||||
// (valid between 2005.0 and 2010.0)
|
||||
// Also removed unused variables and corrected earth radii constants
|
||||
// to the values for WGS84 and WMM2005.
|
||||
// Reference:
|
||||
// McLean, S., S. Macmillan, S. Maus, V. Lesur, A.
|
||||
// Thomson, and D. Dater, December 2004, The
|
||||
// US/UK World Magnetic Model for 2005-2010,
|
||||
// NOAA Technical Report NESDIS/NGDC-1.
|
||||
//
|
||||
// 25/10/2006 Wim Van Hoydonck -- wim.van.hoydonck@gmail.com
|
||||
//
|
||||
|
||||
// The routine uses a spherical harmonic expansion of the magnetic
|
||||
// potential up to twelfth order, together with its time variation, as
|
||||
@@ -75,74 +88,72 @@
|
||||
|
||||
|
||||
static const double pi = 3.14159265358979;
|
||||
static const double a = 6378.16; /* major radius (km) IAU66 ellipsoid */
|
||||
static const double f = 1.0 / 298.25; /* inverse flattening IAU66 ellipsoid */
|
||||
static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
|
||||
/* minor radius b=a*(1-f) */
|
||||
static const double r_0 = 6371.2; /* "mean radius" for spherical harmonic expansion */
|
||||
static const double a = 6378.137; /* semi-major axis (equatorial radius) of WGS84 ellipsoid */
|
||||
static const double b = 6356.7523142; /* semi-minor axis referenced to the WGS84 ellipsoid */
|
||||
static const double r_0 = 6371.2; /* standard Earth magnetic reference radius */
|
||||
|
||||
static double gnm_wmm2000[13][13] =
|
||||
static double gnm_wmm2005[13][13] =
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
|
||||
{5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
|
||||
{-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
|
||||
{3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
|
||||
{-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
|
||||
{-29556.8, -1671.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2340.6, 3046.9, 1657.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1335.4, -2305.1, 1246.7, 674.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{919.8, 798.1, 211.3, -379.4, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-227.4, 354.6, 208.7, -136.5, -168.3, -14.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{73.2, 69.7, 76.7, -151.2, -14.9, 14.6, -86.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{80.1, -74.5, -1.4, 38.5, 12.4, 9.5, 5.7, 1.8, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{24.9, 7.7, -11.6, -6.9, -18.2, 10.0, 9.2, -11.6, -5.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{5.6, 9.9, 3.5, -7.0, 5.1, -10.8, -1.3, 8.8, -6.7, -9.1, 0.0, 0.0, 0.0},
|
||||
{-2.3, -6.3, 1.6, -2.6, 0.0, 3.1, 0.4, 2.1, 3.9, -0.1, -2.3, 0.0, 0.0},
|
||||
{2.8, -1.6, -1.7, 1.7, -0.1, 0.1, -0.7, 0.7, 1.8, 0.0, 1.1, 4.1, 0.0},
|
||||
{-2.4, -0.4, 0.2, 0.8, -0.3, 1.1, -0.5, 0.4, -0.3, -0.3, -0.1, -0.3, -0.1},
|
||||
};
|
||||
|
||||
static double hnm_wmm2000[13][13]=
|
||||
static double hnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
|
||||
{0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
|
||||
{0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
|
||||
{0.0, 5079.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -2594.7, -516.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -199.9, 269.3, -524.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 281.5, -226.0, 145.8, -304.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 42.4, 179.8, -123.0, -19.5, 103.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.3, 54.7, 63.6, -63.4, -0.1, 50.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -61.5, -22.4, 7.2, 25.4, 11.0, -26.4, -5.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 11.2, -21.0, 9.6, -19.8, 16.1, 7.7, -12.9, -0.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.1, 12.9, 12.6, -6.7, -8.1, 8.0, 2.9, -7.9, 6.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.4, 0.2, 4.4, 4.8, -6.5, -1.1, -3.4, -0.8, -2.3, -7.9, 0.0, 0.0},
|
||||
{0.0, 0.3, 1.2, -0.8, -2.5, 0.9, -0.6, -2.7, -0.9, -1.3, -2.0, -1.2, 0.0},
|
||||
{0.0, -0.4, 0.3, 2.4, -2.6, 0.6, 0.3, 0.0, 0.0, 0.3, -0.9, -0.4, 0.8},
|
||||
};
|
||||
|
||||
static double gtnm_wmm2000[13][13]=
|
||||
static double gtnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
|
||||
{8.0, 10.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-15.1, -7.8, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.4, -2.6, -1.2, -6.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2.5, 2.8, -7.0, 6.2, -3.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2.8, 0.7, -3.2, -1.1, 0.1, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.7, 0.4, -0.3, 2.3, -2.1, -0.6, 1.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.2, -0.1, -0.3, 1.1, 0.6, 0.5, -0.4, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.1, 0.3, -0.4, 0.3, -0.3, 0.2, 0.4, -0.7, 0.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
};
|
||||
|
||||
static double htnm_wmm2000[13][13]=
|
||||
static double htnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -23.2, -14.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 5.0, -7.0, -0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.2, 1.6, 5.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 1.7, 2.1, 4.8, -1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.6, -1.9, -0.4, -0.5, -0.3, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.6, 0.4, 0.2, 0.3, -0.8, -0.2, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.2, 0.1, 0.3, 0.4, 0.1, -0.2, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
@@ -186,8 +197,8 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
{
|
||||
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
|
||||
int n,m;
|
||||
/* reference dates */
|
||||
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
|
||||
/* reference date for current model is 1 januari 2005 */
|
||||
long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
|
||||
|
||||
double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
|
||||
double sinpsi, cospsi, inv_s;
|
||||
@@ -272,13 +283,14 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
}
|
||||
}
|
||||
|
||||
/* compute gnm, hnm at dat */
|
||||
/* WMM2000 */
|
||||
yearfrac = (dat - date0_wmm2000) / 365.25;
|
||||
/* compute Gauss coefficients gnm and hnm of degree n and order m for the desired time
|
||||
achieved by adjusting the coefficients at time t0 for linear secular variation */
|
||||
/* WMM2005 */
|
||||
yearfrac = (dat - date0_wmm2005) / 365.25;
|
||||
for ( n = 1; n <= nmax; n++ ) {
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
|
||||
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
|
||||
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
|
||||
hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +352,7 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
|
||||
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
|
||||
int n,m;
|
||||
/* reference dates */
|
||||
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
|
||||
long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
|
||||
|
||||
double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z;
|
||||
|
||||
@@ -397,12 +409,12 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
|
||||
}
|
||||
|
||||
/* compute gnm, hnm at dat */
|
||||
/* WMM2000 */
|
||||
yearfrac = (dat - date0_wmm2000) / 365.25;
|
||||
/* WMM2005 */
|
||||
yearfrac = (dat - date0_wmm2005) / 365.25;
|
||||
for ( n = 1; n <= nmax; n++ ) {
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
|
||||
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
|
||||
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
|
||||
hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
includedir = @includedir@/math
|
||||
|
||||
noinst_PROGRAMS = SGMathTest
|
||||
check_PROGRAMS = SGMathTest
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
@@ -20,21 +19,20 @@ include_HEADERS = \
|
||||
sg_random.h \
|
||||
sg_types.hxx \
|
||||
vector.hxx \
|
||||
fastmath.hxx \
|
||||
SGCMath.hxx \
|
||||
SGGeoc.hxx \
|
||||
SGGeod.hxx \
|
||||
SGGeodesy.hxx \
|
||||
SGLimits.hxx \
|
||||
SGMatrix.hxx \
|
||||
SGMath.hxx \
|
||||
SGMathFwd.hxx \
|
||||
SGMisc.hxx \
|
||||
SGQuat.hxx \
|
||||
SGVec4.hxx \
|
||||
SGVec3.hxx
|
||||
|
||||
|
||||
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
|
||||
|
||||
libsgmath_a_SOURCES = \
|
||||
interpolater.cxx \
|
||||
leastsqs.cxx \
|
||||
@@ -42,7 +40,6 @@ libsgmath_a_SOURCES = \
|
||||
sg_geodesy.cxx \
|
||||
sg_random.c \
|
||||
vector.cxx \
|
||||
fastmath.cxx \
|
||||
SGGeodesy.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGCMath_H
|
||||
#define SGCMath_H
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
// We have cmath from the standard c++ lib available
|
||||
#include <cmath>
|
||||
#else
|
||||
// We only have math.h with the c89 double functions.
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+27
-20
@@ -27,12 +27,6 @@ class SGGeoc {
|
||||
public:
|
||||
/// Default constructor, initializes the instance to lat = lon = lat = 0
|
||||
SGGeoc(void);
|
||||
/// Initialize from a cartesian vector assumed to be in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeoc(const SGVec3<double>& cart);
|
||||
/// Initialize from a geodetic position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeoc(const SGGeod& geod);
|
||||
|
||||
/// Factory from angular values in radians and radius in ft
|
||||
static SGGeoc fromRadFt(double lon, double lat, double radius);
|
||||
@@ -42,6 +36,13 @@ public:
|
||||
static SGGeoc fromRadM(double lon, double lat, double radius);
|
||||
/// Factory from angular values in degrees and radius in m
|
||||
static SGGeoc fromDegM(double lon, double lat, double radius);
|
||||
/// Factory to convert position from a cartesian position assumed to be
|
||||
/// in wgs84 measured in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeoc fromCart(const SGVec3<double>& cart);
|
||||
/// Factory to convert position from a geodetic position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeoc fromGeod(const SGGeod& geod);
|
||||
|
||||
/// Return the geocentric longitude in radians
|
||||
double getLongitudeRad(void) const;
|
||||
@@ -103,20 +104,6 @@ SGGeoc::SGGeoc(double lon, double lat, double radius) :
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc::SGGeoc(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeodesy::SGCartToGeoc(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc::SGGeoc(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeodesy::SGCartToGeoc(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromRadFt(double lon, double lat, double radius)
|
||||
@@ -165,6 +152,26 @@ SGGeoc::fromDegM(double lon, double lat, double radius)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromCart(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
return geoc;
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
return geoc;
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeoc::getLongitudeRad(void) const
|
||||
|
||||
+27
-20
@@ -27,12 +27,6 @@ class SGGeod {
|
||||
public:
|
||||
/// Default constructor, initializes the instance to lat = lon = elev = 0
|
||||
SGGeod(void);
|
||||
/// Initialize from a cartesian vector assumed to be in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeod(const SGVec3<double>& cart);
|
||||
/// Initialize from a geocentric position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeod(const SGGeoc& geoc);
|
||||
|
||||
/// Factory from angular values in radians and elevation is 0
|
||||
static SGGeod fromRad(double lon, double lat);
|
||||
@@ -46,6 +40,13 @@ public:
|
||||
static SGGeod fromRadM(double lon, double lat, double elevation);
|
||||
/// Factory from angular values in degrees and elevation in m
|
||||
static SGGeod fromDegM(double lon, double lat, double elevation);
|
||||
/// Factory to convert position from a cartesian position assumed to be
|
||||
/// in wgs84 measured in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeod fromCart(const SGVec3<double>& cart);
|
||||
/// Factory to convert position from a geocentric position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeod fromGeoc(const SGGeoc& geoc);
|
||||
|
||||
/// Return the geodetic longitude in radians
|
||||
double getLongitudeRad(void) const;
|
||||
@@ -107,20 +108,6 @@ SGGeod::SGGeod(double lon, double lat, double elevation) :
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod::SGGeod(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeodesy::SGCartToGeod(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod::SGGeod(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
SGGeodesy::SGCartToGeod(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromRad(double lon, double lat)
|
||||
@@ -191,6 +178,26 @@ SGGeod::fromDegM(double lon, double lat, double elevation)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromCart(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(cart, geod);
|
||||
return geod;
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(cart, geod);
|
||||
return geod;
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeod::getLongitudeRad(void) const
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
#ifndef SGGeodesy_H
|
||||
#define SGGeodesy_H
|
||||
|
||||
class SGGeoc;
|
||||
class SGGeod;
|
||||
|
||||
template<typename T>
|
||||
class SGVec3;
|
||||
|
||||
class SGGeodesy {
|
||||
public:
|
||||
// Hard numbers from the WGS84 standard.
|
||||
|
||||
@@ -26,7 +26,4 @@
|
||||
template<typename T>
|
||||
class SGLimits : public std::numeric_limits<T> {};
|
||||
|
||||
typedef SGLimits<float> SGLimitsf;
|
||||
typedef SGLimits<double> SGLimitsd;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,14 +22,17 @@
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "SGMathFwd.hxx"
|
||||
|
||||
#include "SGCMath.hxx"
|
||||
#include "SGLimits.hxx"
|
||||
#include "SGMisc.hxx"
|
||||
#include "SGGeodesy.hxx"
|
||||
#include "SGVec3.hxx"
|
||||
#include "SGVec4.hxx"
|
||||
#include "SGQuat.hxx"
|
||||
#include "SGMatrix.hxx"
|
||||
#include "SGGeoc.hxx"
|
||||
#include "SGGeod.hxx"
|
||||
#include "SGQuat.hxx"
|
||||
#include "SGMatrix.hxx"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGMathFwd_H
|
||||
#define SGMathFwd_H
|
||||
|
||||
// All forward declarations in case they only need to be declared
|
||||
|
||||
class SGGeoc;
|
||||
class SGGeod;
|
||||
|
||||
template<typename T>
|
||||
class SGLimits;
|
||||
template<typename T>
|
||||
class SGMatrix;
|
||||
template<typename T>
|
||||
class SGMisc;
|
||||
template<typename T>
|
||||
class SGQuat;
|
||||
template<typename T>
|
||||
class SGVec3;
|
||||
template<typename T>
|
||||
class SGVec4;
|
||||
|
||||
typedef SGLimits<float> SGLimitsf;
|
||||
typedef SGLimits<double> SGLimitsd;
|
||||
typedef SGMatrix<float> SGMatrixf;
|
||||
typedef SGMatrix<double> SGMatrixd;
|
||||
typedef SGMisc<float> SGMiscf;
|
||||
typedef SGMisc<double> SGMiscd;
|
||||
typedef SGQuat<float> SGQuatf;
|
||||
typedef SGQuat<double> SGQuatd;
|
||||
typedef SGVec3<float> SGVec3f;
|
||||
typedef SGVec3<double> SGVec3d;
|
||||
typedef SGVec4<float> SGVec4f;
|
||||
typedef SGVec4<double> SGVec4d;
|
||||
|
||||
#endif
|
||||
@@ -213,16 +213,16 @@ GeodesyTest(void)
|
||||
geod0 = SGGeod::fromDegM(30, 20, 17);
|
||||
|
||||
// Test the conversion routines to cartesian coordinates
|
||||
cart0 = geod0;
|
||||
geod1 = cart0;
|
||||
cart0 = SGVec3<double>::fromGeod(geod0);
|
||||
geod1 = SGGeod::fromCart(cart0);
|
||||
if (epsDeg < fabs(geod0.getLongitudeDeg() - geod1.getLongitudeDeg()) ||
|
||||
epsDeg < fabs(geod0.getLatitudeDeg() - geod1.getLatitudeDeg()) ||
|
||||
epsM < fabs(geod0.getElevationM() - geod1.getElevationM()))
|
||||
return false;
|
||||
|
||||
// Test the conversion routines to radial coordinates
|
||||
geoc0 = cart0;
|
||||
cart1 = geoc0;
|
||||
geoc0 = SGGeoc::fromCart(cart0);
|
||||
cart1 = SGVec3<double>::fromGeoc(geoc0);
|
||||
if (!equivalent(cart0, cart1))
|
||||
return false;
|
||||
|
||||
@@ -346,8 +346,8 @@ main(void)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Check geodetic/geocentric/cartesian conversions
|
||||
// if (!GeodesyTest())
|
||||
// return EXIT_FAILURE;
|
||||
if (!GeodesyTest())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Check interaction with sg*/sgd*
|
||||
if (!sgInterfaceTest())
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
template<typename T>
|
||||
struct TransNegRef;
|
||||
|
||||
template<typename T>
|
||||
class SGMatrix;
|
||||
|
||||
/// 3D Matrix Class
|
||||
template<typename T>
|
||||
class SGMatrix {
|
||||
@@ -571,10 +568,6 @@ operator<<(std::basic_ostream<char_type, traits_type>& s, const SGMatrix<T>& m)
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGMatrix<float> SGMatrixf;
|
||||
typedef SGMatrix<double> SGMatrixd;
|
||||
|
||||
inline
|
||||
SGMatrixf
|
||||
toMatrixf(const SGMatrixd& m)
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#ifndef SGMisc_H
|
||||
#define SGMisc_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
template<typename T>
|
||||
class SGMisc {
|
||||
public:
|
||||
@@ -51,6 +49,11 @@ public:
|
||||
static T deg2rad(const T& val)
|
||||
{ return val*pi()/180; }
|
||||
|
||||
static T round(const T& v)
|
||||
{ return floor(v + T(0.5)); }
|
||||
static int roundToInt(const T& v)
|
||||
{ return int(round(v)); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Returns true if v is a NaN value
|
||||
/// Use with care: allways code that you do not need to use that!
|
||||
@@ -71,7 +74,4 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef SGMisc<float> SGMiscf;
|
||||
typedef SGMisc<double> SGMiscd;
|
||||
|
||||
#endif
|
||||
|
||||
+14
-4
@@ -18,6 +18,15 @@
|
||||
#ifndef SGQuat_H
|
||||
#define SGQuat_H
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
|
||||
/// 3D Vector Class
|
||||
template<typename T>
|
||||
class SGQuat {
|
||||
@@ -110,6 +119,11 @@ public:
|
||||
static SGQuat fromLonLatDeg(T lon, T lat)
|
||||
{ return fromLonLatRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
|
||||
|
||||
/// Return a quaternion rotation the the horizontal local frame from given
|
||||
/// longitude and latitude
|
||||
static SGQuat fromLonLat(const SGGeod& geod)
|
||||
{ return fromLonLatRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
|
||||
|
||||
/// Create a quaternion from the angle axis representation
|
||||
static SGQuat fromAngleAxis(T angle, const SGVec3<T>& axis)
|
||||
{
|
||||
@@ -552,10 +566,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGQuat<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGQuat<float> SGQuatf;
|
||||
typedef SGQuat<double> SGQuatd;
|
||||
|
||||
inline
|
||||
SGQuatf
|
||||
toQuatf(const SGQuatd& v)
|
||||
|
||||
+61
-12
@@ -43,14 +43,6 @@ public:
|
||||
/// make sure it has at least 3 elements
|
||||
explicit SGVec3(const T* data)
|
||||
{ _data[0] = data[0]; _data[1] = data[1]; _data[2] = data[2]; }
|
||||
/// Constructor. Initialize by a geodetic coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGVec3(const SGGeod& geod)
|
||||
{ SGGeodesy::SGGeodToCart(geod, *this); }
|
||||
/// Constructor. Initialize by a geocentric coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGVec3(const SGGeoc& geoc)
|
||||
{ SGGeodesy::SGGeocToCart(geoc, *this); }
|
||||
|
||||
/// Access by index, the index is unchecked
|
||||
const T& operator()(unsigned i) const
|
||||
@@ -125,11 +117,58 @@ public:
|
||||
static SGVec3 e3(void)
|
||||
{ return SGVec3(0, 0, 1); }
|
||||
|
||||
/// Constructor. Initialize by a geodetic coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGVec3 fromGeod(const SGGeod& geod);
|
||||
/// Constructor. Initialize by a geocentric coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGVec3 fromGeoc(const SGGeoc& geoc);
|
||||
|
||||
private:
|
||||
/// The actual data
|
||||
T _data[3];
|
||||
};
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<double>
|
||||
SGVec3<double>::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
return cart;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<float>
|
||||
SGVec3<float>::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
return SGVec3<float>(cart(0), cart(1), cart(2));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<double>
|
||||
SGVec3<double>::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
return cart;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<float>
|
||||
SGVec3<float>::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
return SGVec3<float>(cart(0), cart(1), cart(2));
|
||||
}
|
||||
|
||||
/// Unary +, do nothing ...
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -257,6 +296,20 @@ equivalent(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
return equivalent(v1, v2, tol, tol);
|
||||
}
|
||||
|
||||
/// The euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dist(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return norm(v1 - v2); }
|
||||
|
||||
/// The squared euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
distSqr(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ SGVec3<T> tmp = v1 - v2; return dot(tmp, tmp); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -275,10 +328,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec3<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGVec3<float> SGVec3f;
|
||||
typedef SGVec3<double> SGVec3d;
|
||||
|
||||
inline
|
||||
SGVec3f
|
||||
toVec3f(const SGVec3d& v)
|
||||
|
||||
+14
-4
@@ -248,6 +248,20 @@ equivalent(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
return equivalent(v1, v2, tol, tol);
|
||||
}
|
||||
|
||||
/// The euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dist(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return norm(v1 - v2); }
|
||||
|
||||
/// The squared euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
distSqr(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ SGVec4<T> tmp = v1 - v2; return dot(tmp, tmp); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -266,10 +280,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec4<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGVec4<float> SGVec4f;
|
||||
typedef SGVec4<double> SGVec4d;
|
||||
|
||||
inline
|
||||
SGVec4f
|
||||
toVec4f(const SGVec4d& v)
|
||||
|
||||
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* \file fastmath.cxx
|
||||
* fast mathematics routines.
|
||||
*
|
||||
* Refferences:
|
||||
*
|
||||
* A Fast, Compact Approximation of the Exponential Function
|
||||
* Nicol N. Schraudolph
|
||||
* IDSIA, Lugano, Switzerland
|
||||
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
|
||||
*
|
||||
* Base-2 exp, Laurent de Soras
|
||||
* http://www.musicdsp.org/archive.php?classid=5#106
|
||||
*
|
||||
* Fast log() Function, by Laurent de Soras:
|
||||
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
|
||||
*
|
||||
* Sin, Cos, Tan approximation
|
||||
* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=115
|
||||
*
|
||||
* fast floating point power computation:
|
||||
* http://playstation2-linux.com/download/adam/power.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include "fastmath.hxx"
|
||||
|
||||
/**
|
||||
* This function is on avarage 9 times faster than the system exp() function
|
||||
* and has an error of about 1.5%
|
||||
*/
|
||||
static union {
|
||||
double d;
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
int i, j;
|
||||
#else
|
||||
int j, i;
|
||||
#endif
|
||||
} n;
|
||||
} _eco;
|
||||
|
||||
double fast_exp(double val) {
|
||||
const double a = 1048576/M_LN2;
|
||||
const double b_c = 1072632447; /* 1072693248 - 60801 */
|
||||
|
||||
_eco.n.i = (int)(a*val + b_c);
|
||||
|
||||
return _eco.d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Linear approx. between 2 integer values of val. Uses 32-bit integers.
|
||||
* Not very efficient but faster than exp()
|
||||
*/
|
||||
double fast_exp2( const double val )
|
||||
{
|
||||
int e;
|
||||
double ret;
|
||||
|
||||
if (val >= 0) {
|
||||
e = int (val);
|
||||
ret = val - (e - 1);
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
|
||||
#else
|
||||
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
|
||||
#endif
|
||||
} else {
|
||||
e = int (val + 1023);
|
||||
ret = val - (e - 1024);
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
((*((int *) &ret)) &= ~(2047 << 20)) += e << 20;
|
||||
#else
|
||||
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
float _fast_log2(const float val)
|
||||
{
|
||||
float result, tmp;
|
||||
float mp = 0.346607f;
|
||||
|
||||
result = *(int*)&val;
|
||||
result *= 1.0/(1<<23);
|
||||
result = result - 127;
|
||||
|
||||
tmp = result - floor(result);
|
||||
tmp = (tmp - tmp*tmp) * mp;
|
||||
return tmp + result;
|
||||
}
|
||||
|
||||
float _fast_pow2(const float val)
|
||||
{
|
||||
float result;
|
||||
|
||||
float mp = 0.33971f;
|
||||
float tmp = val - floor(val);
|
||||
tmp = (tmp - tmp*tmp) * mp;
|
||||
|
||||
result = val + 127 - tmp;
|
||||
result *= (1<<23);
|
||||
*(int*)&result = (int)result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* While we're on the subject, someone might have use for these as well?
|
||||
* Float Shift Left and Float Shift Right. Do what you want with this.
|
||||
*/
|
||||
void fast_BSL(float &x, register unsigned long shiftAmount) {
|
||||
|
||||
*(unsigned long*)&x+=shiftAmount<<23;
|
||||
|
||||
}
|
||||
|
||||
void fast_BSR(float &x, register unsigned long shiftAmount) {
|
||||
|
||||
*(unsigned long*)&x-=shiftAmount<<23;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fastpow(f,n) gives a rather *rough* estimate of a float number f to the
|
||||
* power of an integer number n (y=f^n). It is fast but result can be quite a
|
||||
* bit off, since we directly mess with the floating point exponent.
|
||||
*
|
||||
* Use it only for getting rough estimates of the values and where precision
|
||||
* is not that important.
|
||||
*/
|
||||
float fast_pow(const float f, const int n)
|
||||
{
|
||||
long *lp,l;
|
||||
lp=(long*)(&f);
|
||||
l=*lp;l-=0x3F800000l;l<<=(n-1);l+=0x3F800000l;
|
||||
*lp=l;
|
||||
return f;
|
||||
}
|
||||
|
||||
float fast_root(const float f, const int n)
|
||||
{
|
||||
long *lp,l;
|
||||
lp=(long*)(&f);
|
||||
l=*lp;l-=0x3F800000l;l>>=(n-1);l+=0x3F800000l;
|
||||
*lp=l;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Code for approximation of cos, sin, tan and inv sin, etc.
|
||||
* Surprisingly accurate and very usable.
|
||||
*
|
||||
* Domain:
|
||||
* Sin/Cos [0, pi/2]
|
||||
* Tan [0,pi/4]
|
||||
* InvSin/Cos [0, 1]
|
||||
* InvTan [-1, 1]
|
||||
*/
|
||||
|
||||
float fast_sin(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = -2.39e-08f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.7526e-06f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.98409e-04f;
|
||||
fResult *= fASqr;
|
||||
fResult += 8.3333315e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.666666664e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_cos(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = -2.605e-07f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.47609e-05f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.3888397e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 4.16666418e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 4.999999963e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_tan(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = 9.5168091e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.900525e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.45650893e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult += 5.33740603e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.333923995e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 3.333314036e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
|
||||
}
|
||||
|
||||
float fast_asin(float val)
|
||||
{
|
||||
float fRoot = sqrt(1.0f-val);
|
||||
float fResult = -0.0187293f;
|
||||
fResult *= val;
|
||||
fResult += 0.0742610f;
|
||||
fResult *= val;
|
||||
fResult -= 0.2121144f;
|
||||
fResult *= val;
|
||||
fResult += 1.5707288f;
|
||||
fResult = SGD_PI_2 - fRoot*fResult;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_acos(float val)
|
||||
{
|
||||
float fRoot = sqrt(1.0f-val);
|
||||
float fResult = -0.0187293f;
|
||||
fResult *= val;
|
||||
fResult += 0.0742610f;
|
||||
fResult *= val;
|
||||
fResult -= 0.2121144f;
|
||||
fResult *= val;
|
||||
fResult += 1.5707288f;
|
||||
fResult *= fRoot;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_atan(float val)
|
||||
{
|
||||
float fVSqr = val*val;
|
||||
float fResult = 0.0028662257f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.0161657367f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.0429096138f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.0752896400f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.1065626393f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.1420889944f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.1999355085f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.3333314528f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* \file fastmath.hxx
|
||||
* fast mathematics routines.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* A Fast, Compact Approximation of the Exponential Function
|
||||
* Nicol N. Schraudolph
|
||||
* IDSIA, Lugano, Switzerland
|
||||
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
|
||||
*
|
||||
* Fast log() Function, by Laurent de Soras:
|
||||
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SG_FMATH_HXX
|
||||
#define _SG_FMATH_HXX 1
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
double fast_exp(double val);
|
||||
double fast_exp2(const double val);
|
||||
|
||||
float fast_pow(const float val1, const float val2);
|
||||
float fast_log2(const float cal);
|
||||
float fast_root(const float f, const int n);
|
||||
|
||||
float _fast_pow2(const float cal);
|
||||
float _fast_log2(const float val);
|
||||
|
||||
float fast_sin(const float val);
|
||||
float fast_cos(const float val);
|
||||
float fast_tan(const float val);
|
||||
float fast_asin(const float val);
|
||||
float fast_acos(const float val);
|
||||
float fast_atan(const float val);
|
||||
|
||||
void fast_BSL(float &x, register unsigned long shiftAmount);
|
||||
void fast_BSR(float &x, register unsigned long shiftAmount);
|
||||
|
||||
|
||||
inline float fast_log2 (float val)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
} v;
|
||||
v.f = val;
|
||||
const int log_2 = ((v.i >> 23) & 255) - 128;
|
||||
v.i &= ~(255 << 23);
|
||||
v.i += 127 << 23;
|
||||
|
||||
v.f = ((-1.0f/3) * v.f + 2) * v.f - 2.0f/3; // (1)
|
||||
|
||||
return (v.f + log_2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is about 3 times faster than the system log() function
|
||||
* and has an error of about 0.01%
|
||||
*/
|
||||
inline float fast_log (const float &val)
|
||||
{
|
||||
return (fast_log2 (val) * 0.69314718f);
|
||||
}
|
||||
|
||||
inline float fast_log10 (const float &val)
|
||||
{
|
||||
return (fast_log2(val) / 3.321928095f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is about twice as fast as the system pow(x,y) function
|
||||
*/
|
||||
inline float fast_pow(const float val1, const float val2)
|
||||
{
|
||||
return _fast_pow2(val2 * _fast_log2(val1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Haven't seen this elsewhere, probably because it is too obvious?
|
||||
* Anyway, these functions are intended for 32-bit floating point numbers
|
||||
* only and should work a bit faster than the regular ones.
|
||||
*/
|
||||
inline float fast_abs(float f)
|
||||
{
|
||||
int i=((*(int*)&f)&0x7fffffff);
|
||||
return (*(float*)&i);
|
||||
}
|
||||
|
||||
inline float fast_neg(float f)
|
||||
{
|
||||
int i=((*(int*)&f)^0x80000000);
|
||||
return (*(float*)&i);
|
||||
}
|
||||
|
||||
inline int fast_sgn(float f)
|
||||
{
|
||||
return 1+(((*(int*)&f)>>31)<<1);
|
||||
}
|
||||
|
||||
#endif // !_SG_FMATH_HXX
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#ifndef LININTP2_H
|
||||
#define LININTP2_H
|
||||
|
||||
template<class T>
|
||||
class mgcLinInterp2D
|
||||
{
|
||||
public:
|
||||
mgcLinInterp2D (int _numPoints, double* x, double* y, T* _f);
|
||||
|
||||
~mgcLinInterp2D ();
|
||||
|
||||
double XMin () { return xmin; }
|
||||
double XMax () { return xmax; }
|
||||
double XRange () { return xmax-xmin; }
|
||||
double YMin () { return ymin; }
|
||||
double YMax () { return ymax; }
|
||||
double YRange () { return ymax-ymin; }
|
||||
|
||||
int PointCount () { return numPoints; }
|
||||
void GetPoint (int i, double& x, double& y);
|
||||
|
||||
int EdgeCount () { return numEdges; }
|
||||
void GetEdge (int i, double& x0, double& y0, double& x1, double& y1);
|
||||
|
||||
int TriangleCount () { return numTriangles; }
|
||||
void GetTriangle (int i, double& x0, double& y0, double& x1, double& y1,
|
||||
double& x2, double& y2);
|
||||
|
||||
int Evaluate (double x, double y, T& F);
|
||||
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
double x, y;
|
||||
}
|
||||
Vertex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vertex[3]; // listed in counterclockwise order
|
||||
|
||||
int adj[3];
|
||||
// adj[0] points to triangle sharing edge (vertex[0],vertex[1])
|
||||
// adj[1] points to triangle sharing edge (vertex[1],vertex[2])
|
||||
// adj[2] points to triangle sharing edge (vertex[2],vertex[0])
|
||||
}
|
||||
Triangle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vertex[2];
|
||||
int triangle[2];
|
||||
int index[2];
|
||||
}
|
||||
Edge;
|
||||
|
||||
int numPoints;
|
||||
double** point;
|
||||
double** tmppoint;
|
||||
T* f;
|
||||
|
||||
double xmin, xmax, ymin, ymax;
|
||||
|
||||
|
||||
int numEdges;
|
||||
Edge* edge;
|
||||
|
||||
int numTriangles;
|
||||
Triangle* triangle;
|
||||
|
||||
int Delaunay2D ();
|
||||
void ComputeBarycenter (Vertex& v0, Vertex& v1, Vertex& v2, Vertex& ver,
|
||||
double c[3]);
|
||||
int InTriangle (Vertex& v0, Vertex& v1, Vertex& v2, Vertex& test);
|
||||
};
|
||||
|
||||
#include "linintp2.inl"
|
||||
|
||||
#endif
|
||||
@@ -1,540 +0,0 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "linintp2.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
mgcLinInterp2D<T>::mgcLinInterp2D (int _numPoints, double* x, double* y,
|
||||
T* _f)
|
||||
{
|
||||
if ( (numPoints = _numPoints) < 3 )
|
||||
{
|
||||
point = 0;
|
||||
edge = 0;
|
||||
triangle = 0;
|
||||
numTriangles = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// cout << "[ 20%] allocating memory \r";
|
||||
|
||||
point = new double*[numPoints];
|
||||
tmppoint = new double*[numPoints+3];
|
||||
f = new T[numPoints];
|
||||
int i;
|
||||
for (i = 0; i < numPoints; i++)
|
||||
point[i] = new double[2];
|
||||
for (i = 0; i < numPoints+3; i++)
|
||||
tmppoint[i] = new double[2];
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
point[i][0] = tmppoint[i][0] = x[i];
|
||||
point[i][1] = tmppoint[i][1] = y[i];
|
||||
|
||||
f[i] = _f[i];
|
||||
}
|
||||
|
||||
// cout << "[ 30%] creating delaunay diagram \r";
|
||||
|
||||
Delaunay2D();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
mgcLinInterp2D<T>::~mgcLinInterp2D ()
|
||||
{
|
||||
if ( numPoints < 3 )
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
||||
if ( point )
|
||||
{
|
||||
for (i = 0; i < numPoints; i++)
|
||||
delete[] point[i];
|
||||
delete[] point;
|
||||
}
|
||||
if ( tmppoint )
|
||||
{
|
||||
for (i = 0; i < numPoints+3; i++)
|
||||
delete[] tmppoint[i];
|
||||
delete[] tmppoint;
|
||||
}
|
||||
|
||||
delete[] f;
|
||||
delete[] edge;
|
||||
delete[] triangle;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::ComputeBarycenter (Vertex& v0, Vertex& v1, Vertex& v2,
|
||||
Vertex& ver, double c[3])
|
||||
{
|
||||
double A0 = v0.x-v2.x, B0 = v0.y-v2.y;
|
||||
double A1 = v1.x-v2.x, B1 = v1.y-v2.y;
|
||||
double A2 = ver.x-v2.x, B2 = ver.y-v2.y;
|
||||
|
||||
double m00 = A0*A0+B0*B0, m01 = A0*A1+B0*B1, m11 = A1*A1+B1*B1;
|
||||
double r0 = A2*A0+B2*B0, r1 = A2*A1+B2*B1;
|
||||
double det = m00*m11-m01*m01;
|
||||
|
||||
c[0] = (m11*r0-m01*r1)/det;
|
||||
c[1] = (m00*r1-m01*r0)/det;
|
||||
c[2] = 1-c[0]-c[1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::InTriangle (Vertex& v0, Vertex& v1, Vertex& v2,
|
||||
Vertex& test)
|
||||
{
|
||||
const double eps = 1e-08;
|
||||
double tx, ty, nx, ny;
|
||||
|
||||
// test against normal to first edge
|
||||
tx = test.x - v0.x;
|
||||
ty = test.y - v0.y;
|
||||
nx = v0.y - v1.y;
|
||||
ny = v1.x - v0.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
// test against normal to second edge
|
||||
tx = test.x - v1.x;
|
||||
ty = test.y - v1.y;
|
||||
nx = v1.y - v2.y;
|
||||
ny = v2.x - v1.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
// test against normal to third edge
|
||||
tx = test.x - v2.x;
|
||||
ty = test.y - v2.y;
|
||||
nx = v2.y - v0.y;
|
||||
ny = v0.x - v2.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::Evaluate (double x, double y, T& F)
|
||||
{
|
||||
Vertex ver = { x, y };
|
||||
// determine which triangle contains the target point
|
||||
|
||||
int i;
|
||||
Vertex v0, v1, v2;
|
||||
for (i = 0; i < numTriangles; i++)
|
||||
{
|
||||
Triangle& t = triangle[i];
|
||||
v0.x = point[t.vertex[0]][0];
|
||||
v0.y = point[t.vertex[0]][1];
|
||||
v1.x = point[t.vertex[1]][0];
|
||||
v1.y = point[t.vertex[1]][1];
|
||||
v2.x = point[t.vertex[2]][0];
|
||||
v2.y = point[t.vertex[2]][1];
|
||||
|
||||
if ( InTriangle(v0,v1,v2,ver) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i == numTriangles ) // point is outside interpolation region
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Triangle& t = triangle[i]; // (x,y) is in this triangle
|
||||
|
||||
// compute barycentric coordinates with respect to subtriangle
|
||||
double bary[3];
|
||||
ComputeBarycenter(v0,v1,v2,ver,bary);
|
||||
|
||||
// compute barycentric combination of function values at vertices
|
||||
F = bary[0]*f[t.vertex[0]]+bary[1]*f[t.vertex[1]]+bary[2]*f[t.vertex[2]];
|
||||
|
||||
return 1;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::Delaunay2D ()
|
||||
{
|
||||
int result;
|
||||
|
||||
const double EPSILON = 1e-12;
|
||||
const int TSIZE = 75;
|
||||
const double RANGE = 10.0;
|
||||
|
||||
xmin = tmppoint[0][0];
|
||||
xmax = xmin;
|
||||
ymin = tmppoint[0][1];
|
||||
ymax = ymin;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
double value = tmppoint[i][0];
|
||||
if ( xmax < value )
|
||||
xmax = value;
|
||||
if ( xmin > value )
|
||||
xmin = value;
|
||||
|
||||
value = tmppoint[i][1];
|
||||
if ( ymax < value )
|
||||
ymax = value;
|
||||
if ( ymin > value )
|
||||
ymin = value;
|
||||
}
|
||||
|
||||
double xrange = xmax-xmin, yrange = ymax-ymin;
|
||||
double maxrange = xrange;
|
||||
if ( maxrange < yrange )
|
||||
maxrange = yrange;
|
||||
|
||||
// need to scale the data later to do a correct triangle count
|
||||
double maxrange2 = maxrange*maxrange;
|
||||
|
||||
// tweak the points by very small random numbers
|
||||
double bgs = EPSILON*maxrange;
|
||||
srand(367);
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
tmppoint[i][0] += bgs*(0.5 - rand()/double(RAND_MAX));
|
||||
tmppoint[i][1] += bgs*(0.5 - rand()/double(RAND_MAX));
|
||||
}
|
||||
|
||||
double wrk[2][3] =
|
||||
{
|
||||
{ 5*RANGE, -RANGE, -RANGE },
|
||||
{ -RANGE, 5*RANGE, -RANGE }
|
||||
};
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
tmppoint[numPoints+i][0] = xmin+xrange*wrk[0][i];
|
||||
tmppoint[numPoints+i][1] = ymin+yrange*wrk[1][i];
|
||||
}
|
||||
|
||||
int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i11;
|
||||
int nts, ii[3];
|
||||
double xx;
|
||||
|
||||
int tsz = 2*TSIZE;
|
||||
int** tmp = new int*[tsz+1];
|
||||
tmp[0] = new int[2*(tsz+1)];
|
||||
for (i0 = 1; i0 < tsz+1; i0++)
|
||||
tmp[i0] = tmp[0] + 2*i0;
|
||||
i1 = 2*(numPoints + 2);
|
||||
|
||||
int* id = new int[i1];
|
||||
for (i0 = 0; i0 < i1; i0++)
|
||||
id[i0] = i0;
|
||||
|
||||
int** a3s = new int*[i1];
|
||||
a3s[0] = new int[3*i1];
|
||||
for (i0 = 1; i0 < i1; i0++)
|
||||
a3s[i0] = a3s[0] + 3*i0;
|
||||
a3s[0][0] = numPoints;
|
||||
a3s[0][1] = numPoints+1;
|
||||
a3s[0][2] = numPoints+2;
|
||||
|
||||
double** ccr = new double*[i1]; // circumscribed centers and radii
|
||||
ccr[0] = new double[3*i1];
|
||||
for (i0 = 1; i0 < i1; i0++)
|
||||
ccr[i0] = ccr[0] + 3*i0;
|
||||
ccr[0][0] = 0.0;
|
||||
ccr[0][1] = 0.0;
|
||||
ccr[0][2] = FLT_MAX;
|
||||
|
||||
nts = 1; // number of triangles
|
||||
i4 = 1;
|
||||
|
||||
// cout << "[ 40%] create triangulation \r";
|
||||
|
||||
// compute triangulation
|
||||
for (i0 = 0; i0 < numPoints; i0++)
|
||||
{
|
||||
i1 = i7 = -1;
|
||||
i9 = 0;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i1++;
|
||||
while ( a3s[i1][0] < 0 )
|
||||
i1++;
|
||||
xx = ccr[i1][2];
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
{
|
||||
double z = tmppoint[i0][i2]-ccr[i1][i2];
|
||||
xx -= z*z;
|
||||
if ( xx < 0 )
|
||||
goto Corner3;
|
||||
}
|
||||
i9--;
|
||||
i4--;
|
||||
id[i4] = i1;
|
||||
for (i2 = 0; i2 < 3; i2++)
|
||||
{
|
||||
ii[0] = 0;
|
||||
if (ii[0] == i2)
|
||||
ii[0]++;
|
||||
for (i3 = 1; i3 < 2; i3++)
|
||||
{
|
||||
ii[i3] = ii[i3-1] + 1;
|
||||
if (ii[i3] == i2)
|
||||
ii[i3]++;
|
||||
}
|
||||
if ( i7 > 1 )
|
||||
{
|
||||
i8 = i7;
|
||||
for (i3 = 0; i3 <= i8; i3++)
|
||||
{
|
||||
for (i5 = 0; i5 < 2; i5++)
|
||||
if ( a3s[i1][ii[i5]] != tmp[i3][i5] )
|
||||
goto Corner1;
|
||||
for (i6 = 0; i6 < 2; i6++)
|
||||
tmp[i3][i6] = tmp[i8][i6];
|
||||
i7--;
|
||||
goto Corner2;
|
||||
Corner1:;
|
||||
}
|
||||
}
|
||||
if ( ++i7 > tsz )
|
||||
{
|
||||
// temporary storage exceeded, increase TSIZE
|
||||
result = 0;
|
||||
goto ExitDelaunay;
|
||||
}
|
||||
for (i3 = 0; i3 < 2; i3++)
|
||||
tmp[i7][i3] = a3s[i1][ii[i3]];
|
||||
Corner2:;
|
||||
}
|
||||
a3s[i1][0] = -1;
|
||||
Corner3:;
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 <= i7; i1++)
|
||||
{
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
for (wrk[i2][2] = 0, i3 = 0; i3 < 2; i3++)
|
||||
{
|
||||
wrk[i2][i3] = tmppoint[tmp[i1][i2]][i3]-tmppoint[i0][i3];
|
||||
wrk[i2][2] +=
|
||||
0.5*wrk[i2][i3]*(tmppoint[tmp[i1][i2]][i3]+
|
||||
tmppoint[i0][i3]);
|
||||
}
|
||||
|
||||
xx = wrk[0][0]*wrk[1][1]-wrk[1][0]*wrk[0][1];
|
||||
ccr[id[i4]][0] = (wrk[0][2]*wrk[1][1]-wrk[1][2]*wrk[0][1])/xx;
|
||||
ccr[id[i4]][1] = (wrk[0][0]*wrk[1][2]-wrk[1][0]*wrk[0][2])/xx;
|
||||
|
||||
for (ccr[id[i4]][2] = 0, i2 = 0; i2 < 2; i2++)
|
||||
{
|
||||
double z = tmppoint[i0][i2]-ccr[id[i4]][i2];
|
||||
ccr[id[i4]][2] += z*z;
|
||||
a3s[id[i4]][i2] = tmp[i1][i2];
|
||||
}
|
||||
|
||||
a3s[id[i4]][2] = i0;
|
||||
i4++;
|
||||
i9++;
|
||||
}
|
||||
nts += i9;
|
||||
}
|
||||
|
||||
// count the number of triangles
|
||||
// cout << "[ 50%] count the number of triangles \r";
|
||||
|
||||
numTriangles = 0;
|
||||
i0 = -1;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i0++;
|
||||
while ( a3s[i0][0] < 0 )
|
||||
i0++;
|
||||
if ( a3s[i0][0] < numPoints )
|
||||
{
|
||||
for (i1 = 0; i1 < 2; i1++)
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
wrk[i1][i2] =
|
||||
tmppoint[a3s[i0][i1]][i2]-tmppoint[a3s[i0][2]][i2];
|
||||
|
||||
if ( fabs(wrk[0][0]*wrk[1][1]-wrk[0][1]*wrk[1][0]) > EPSILON*maxrange2 )
|
||||
numTriangles++;
|
||||
}
|
||||
}
|
||||
|
||||
// create the triangles
|
||||
// cout << "[ 60%] create the triangles \r";
|
||||
|
||||
triangle = new Triangle[numTriangles];
|
||||
|
||||
numTriangles = 0;
|
||||
i0 = -1;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i0++;
|
||||
while ( a3s[i0][0] < 0 )
|
||||
i0++;
|
||||
if ( a3s[i0][0] < numPoints )
|
||||
{
|
||||
for (i1 = 0; i1 < 2; i1++)
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
wrk[i1][i2] =
|
||||
tmppoint[a3s[i0][i1]][i2]-tmppoint[a3s[i0][2]][i2];
|
||||
xx = wrk[0][0]*wrk[1][1]-wrk[0][1]*wrk[1][0];
|
||||
if ( fabs(xx) > EPSILON*maxrange2 )
|
||||
{
|
||||
int delta = xx < 0 ? 1 : 0;
|
||||
Triangle& tri = triangle[numTriangles];
|
||||
tri.vertex[0] = a3s[i0][0];
|
||||
tri.vertex[1] = a3s[i0][1+delta];
|
||||
tri.vertex[2] = a3s[i0][2-delta];
|
||||
tri.adj[0] = -1;
|
||||
tri.adj[1] = -1;
|
||||
tri.adj[2] = -1;
|
||||
numTriangles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build edge table
|
||||
// cout << "[ 70%] build the edge table \r";
|
||||
|
||||
numEdges = 0;
|
||||
edge = new Edge[3*numTriangles];
|
||||
|
||||
int j, j0, j1;
|
||||
for (i = 0; i < numTriangles; i++)
|
||||
{
|
||||
// if ( (i%500) == 0)
|
||||
// cout << "[ 7" << 10*i/numTriangles << "%] build the edge table \r";
|
||||
|
||||
Triangle& t = triangle[i];
|
||||
|
||||
for (j0 = 0, j1 = 1; j0 < 3; j0++, j1 = (j1+1)%3)
|
||||
{
|
||||
for (j = 0; j < numEdges; j++)
|
||||
{
|
||||
Edge& e = edge[j];
|
||||
if ( (t.vertex[j0] == e.vertex[0]
|
||||
&& t.vertex[j1] == e.vertex[1])
|
||||
|| (t.vertex[j0] == e.vertex[1]
|
||||
&& t.vertex[j1] == e.vertex[0]) )
|
||||
break;
|
||||
}
|
||||
if ( j == numEdges ) // add edge to table
|
||||
{
|
||||
edge[j].vertex[0] = t.vertex[j0];
|
||||
edge[j].vertex[1] = t.vertex[j1];
|
||||
edge[j].triangle[0] = i;
|
||||
edge[j].index[0] = j0;
|
||||
edge[j].triangle[1] = -1;
|
||||
numEdges++;
|
||||
}
|
||||
else // edge already exists, add triangle to table
|
||||
{
|
||||
edge[j].triangle[1] = i;
|
||||
edge[j].index[1] = j0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// establish links between adjacent triangles
|
||||
// cout << "[ 80%] establishing links between adjacent triangles \r";
|
||||
|
||||
for (i = 0; i < numEdges; i++)
|
||||
{
|
||||
if ( edge[i].triangle[1] != -1 )
|
||||
{
|
||||
j0 = edge[i].triangle[0];
|
||||
j1 = edge[i].triangle[1];
|
||||
triangle[j0].adj[edge[i].index[0]] = j1;
|
||||
triangle[j1].adj[edge[i].index[1]] = j0;
|
||||
}
|
||||
}
|
||||
|
||||
result = 1;
|
||||
|
||||
ExitDelaunay:;
|
||||
delete[] tmp[0];
|
||||
delete[] tmp;
|
||||
delete[] id;
|
||||
delete[] a3s[0];
|
||||
delete[] a3s;
|
||||
delete[] ccr[0];
|
||||
delete[] ccr;
|
||||
|
||||
// cout << "[ 90%] finsishes delauney triangulation \r";
|
||||
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetPoint (int i, double& x, double& y)
|
||||
{
|
||||
// assumes i is valid [can use PointCount() before passing i]
|
||||
x = point[i][0];
|
||||
y = point[i][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetEdge (int i, double& x0, double& y0, double& x1,
|
||||
double& y1)
|
||||
{
|
||||
// assumes i is valid [can use EdgeCount() before passing i]
|
||||
int v0 = edge[i].vertex[0], v1 = edge[i].vertex[1];
|
||||
|
||||
x0 = point[v0][0];
|
||||
y0 = point[v0][1];
|
||||
x1 = point[v1][0];
|
||||
y1 = point[v1][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetTriangle (int i, double& x0, double& y0, double& x1,
|
||||
double& y1, double& x2, double& y2)
|
||||
{
|
||||
// assumes i is valid [can use TriangleCount() before passing i]
|
||||
int v0 = triangle[i].vertex[0];
|
||||
int v1 = triangle[i].vertex[1];
|
||||
int v2 = triangle[i].vertex[2];
|
||||
|
||||
x0 = point[v0][0];
|
||||
y0 = point[v0][1];
|
||||
x1 = point[v1][0];
|
||||
y1 = point[v1][1];
|
||||
x2 = point[v2][0];
|
||||
y2 = point[v2][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -73,10 +73,9 @@ static inline double M0( double e2 ) {
|
||||
}
|
||||
|
||||
|
||||
// given, alt, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// given, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
|
||||
int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
double lon1, double az1,
|
||||
int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 )
|
||||
{
|
||||
@@ -160,16 +159,15 @@ int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
double dM = a*M0(e2) - s;
|
||||
double paz = ( phi1 < 0.0 ? 180.0 : 0.0 );
|
||||
double zero = 0.0f;
|
||||
return geo_direct_wgs_84( alt, zero, lon1, paz, dM, lat2, lon2, az2 );
|
||||
return geo_direct_wgs_84( zero, lon1, paz, dM, lat2, lon2, az2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// given alt, lat1, lon1, lat2, lon2, calculate starting and ending
|
||||
// given lat1, lon1, lat2, lon2, calculate starting and ending
|
||||
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
|
||||
// distance in meters
|
||||
int geo_inverse_wgs_84( double alt, double lat1,
|
||||
double lon1, double lat2,
|
||||
int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s )
|
||||
{
|
||||
@@ -192,14 +190,14 @@ int geo_inverse_wgs_84( double alt, double lat1,
|
||||
return 0;
|
||||
} else if( fabs(cosphi1) < testv ) {
|
||||
// initial point is polar
|
||||
int k = geo_inverse_wgs_84( alt, lat2,lon2,lat1,lon1, az1,az2,s );
|
||||
int k = geo_inverse_wgs_84( lat2,lon2,lat1,lon1, az1,az2,s );
|
||||
k = k; // avoid compiler error since return result is unused
|
||||
b = *az1; *az1 = *az2; *az2 = b;
|
||||
return 0;
|
||||
} else if( fabs(cosphi2) < testv ) {
|
||||
// terminal point is polar
|
||||
double _lon1 = lon1 + 180.0f;
|
||||
int k = geo_inverse_wgs_84( alt, lat1, lon1, lat1, _lon1,
|
||||
int k = geo_inverse_wgs_84( lat1, lon1, lat1, _lon1,
|
||||
az1, az2, s );
|
||||
k = k; // avoid compiler error since return result is unused
|
||||
*s /= 2.0;
|
||||
@@ -211,8 +209,8 @@ int geo_inverse_wgs_84( double alt, double lat1,
|
||||
{
|
||||
// Geodesic passes through the pole (antipodal)
|
||||
double s1,s2;
|
||||
geo_inverse_wgs_84( alt, lat1,lon1, lat1,lon2, az1,az2, &s1 );
|
||||
geo_inverse_wgs_84( alt, lat2,lon2, lat1,lon2, az1,az2, &s2 );
|
||||
geo_inverse_wgs_84( lat1,lon1, lat1,lon2, az1,az2, &s1 );
|
||||
geo_inverse_wgs_84( lat2,lon2, lat1,lon2, az1,az2, &s2 );
|
||||
*az2 = *az1;
|
||||
*s = s1 + s2;
|
||||
return 0;
|
||||
|
||||
+54
-20
@@ -4,18 +4,6 @@
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include "SGMath.hxx"
|
||||
|
||||
// Returns the insersection of the line joining the center of the
|
||||
// earth and the specified cylindrical point with the surface of the
|
||||
// WGS84 ellipsoid. Works by finding a normalization constant (in
|
||||
// squashed space) that places the squashed point on the surface of
|
||||
// the sphere.
|
||||
inline double seaLevelRadius(double r, double z)
|
||||
{
|
||||
double sr = r * SGGeodesy::SQUASH;
|
||||
double zz = z*z;
|
||||
return SGGeodesy::POLRAD*sqrt((r*r + zz)/(sr*sr + zz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from geocentric coordinates to geodetic coordinates
|
||||
* @param lat_geoc (in) Geocentric latitude, radians, + = North
|
||||
@@ -56,11 +44,12 @@ inline void sgGeodToGeoc(double lat_geod, double alt,
|
||||
double *sl_radius, double *lat_geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(SGGeod::fromRadM(0, lat_geod, alt), cart);
|
||||
SGGeod geod = SGGeod::fromRadM(0, lat_geod, alt);
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
*lat_geoc = geoc.getLatitudeRad();
|
||||
*sl_radius = seaLevelRadius(cart(0), cart(2));
|
||||
*sl_radius = SGGeodesy::SGGeodToSeaLevelRadius(geod);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +119,7 @@ inline Point3D sgGeodToCart(const Point3D& geod)
|
||||
/**
|
||||
* Given a starting position and an offset radial and distance,
|
||||
* calculate an ending positon on a wgs84 ellipsoid.
|
||||
* @param alt (in) meters
|
||||
* @param alt (in) meters (unused)
|
||||
* @param lat1 (in) degrees
|
||||
* @param lon1 (in) degrees
|
||||
* @param az1 (in) degrees
|
||||
@@ -139,16 +128,39 @@ inline Point3D sgGeodToCart(const Point3D& geod)
|
||||
* @param lon2 (out) degrees
|
||||
* @param az2 (out) return course in degrees
|
||||
*/
|
||||
int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
double lon1, double az1,
|
||||
int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 );
|
||||
inline int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 )
|
||||
{ return geo_direct_wgs_84(lat1, lon1, az1, s, lat2, lon2, az2); }
|
||||
|
||||
/**
|
||||
* Given a starting position and an offset radial and distance,
|
||||
* calculate an ending positon on a wgs84 ellipsoid.
|
||||
* @param p1 (in) geodetic position
|
||||
* @param az1 (in) degrees
|
||||
* @param s (in) distance in meters
|
||||
* @param p2 (out) geodetic position
|
||||
* @param az2 (out) return course in degrees
|
||||
*/
|
||||
inline int geo_direct_wgs_84(const SGGeod& p1, double az1,
|
||||
double s, SGGeod& p2, double *az2 )
|
||||
{
|
||||
double lat2, lon2;
|
||||
int ret = geo_direct_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
|
||||
az1, s, &lat2, &lon2, az2);
|
||||
p2.setLatitudeDeg(lat2);
|
||||
p2.setLongitudeDeg(lon2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an altitude and two sets of (lat, lon) calculate great circle
|
||||
* distance between them as well as the starting and ending azimuths.
|
||||
* @param alt (in) meters
|
||||
* @param alt (in) meters (unused)
|
||||
* @param lat1 (in) degrees
|
||||
* @param lon1 (in) degrees
|
||||
* @param lat2 (in) degrees
|
||||
@@ -157,9 +169,31 @@ int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
* @param az2 (out) end heading degrees
|
||||
* @param s (out) distance meters
|
||||
*/
|
||||
int geo_inverse_wgs_84( double alt, double lat1,
|
||||
double lon1, double lat2,
|
||||
int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s );
|
||||
inline int geo_inverse_wgs_84( double alt, double lat1,
|
||||
double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s )
|
||||
{ return geo_inverse_wgs_84(lat1, lon1, lat2, lon2, az1, az2, s); }
|
||||
|
||||
|
||||
/**
|
||||
* Given an altitude and two sets of (lat, lon) calculate great circle
|
||||
* distance between them as well as the starting and ending azimuths.
|
||||
* @param p1 (in) first position
|
||||
* @param p2 (in) fsecond position
|
||||
* @param az1 (out) start heading degrees
|
||||
* @param az2 (out) end heading degrees
|
||||
* @param s (out) distance meters
|
||||
*/
|
||||
inline int geo_inverse_wgs_84(const SGGeod& p1, const SGGeod& p2,
|
||||
double *az1, double *az2, double *s )
|
||||
{
|
||||
return geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
|
||||
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
|
||||
az1, az2, s);
|
||||
}
|
||||
|
||||
#endif // _SG_GEODESY_HXX
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#ifndef SPHRINTP_H
|
||||
#define SPHRINTP_H
|
||||
|
||||
#include "linintp2.h"
|
||||
#include <plib/sg.h>
|
||||
|
||||
template<class T>
|
||||
class SphereInterpolate
|
||||
{
|
||||
public:
|
||||
SphereInterpolate (int n, const double* x, const double* y,
|
||||
const double* z, const T* f);
|
||||
SphereInterpolate (int n, const sgVec2* p, const T* f);
|
||||
|
||||
~SphereInterpolate ();
|
||||
|
||||
void GetSphericalCoords (const double x, const double y, const double z,
|
||||
double& thetaAngle, double& phiAngle) const;
|
||||
|
||||
int Evaluate (const double x, const double y, const double z, T& f) const;
|
||||
int Evaluate (const double thetaAngle, const double phiAngle, T& f) const;
|
||||
|
||||
T Evaluate(const sgVec2& p) const
|
||||
{
|
||||
T retval;
|
||||
Evaluate(p[1], p[0], retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
T Evaluate(const sgVec3& p) const
|
||||
{
|
||||
T retval;
|
||||
Evaluate(p[1], p[0], retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected:
|
||||
int numPoints;
|
||||
double* theta;
|
||||
double* phi;
|
||||
T* func;
|
||||
mgcLinInterp2D<T>* pInterp;
|
||||
};
|
||||
|
||||
#include "sphrintp.inl"
|
||||
|
||||
#endif
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "sphrintp.h"
|
||||
|
||||
static const double PI = 4.0*atan(1.0);
|
||||
static const double TWOPI = 2.0*PI;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
SphereInterpolate<T>::SphereInterpolate (int n, const double* x,
|
||||
const double* y, const double* z,
|
||||
const T* f)
|
||||
{
|
||||
// Assumes (x[i],y[i],z[i]) is unit length for all 0 <= i < n.
|
||||
// For complete spherical coverage, include the two antipodal points
|
||||
// (0,0,1,f(0,0,1)) and (0,0,-1,f(0,0,-1)) in the data set.
|
||||
|
||||
// cout << "Initialising spherical interpolator.\n";
|
||||
// cout << "[ 0%] Allocating memory \r";
|
||||
|
||||
theta = new double[3*n];
|
||||
phi = new double[3*n];
|
||||
func = new T[3*n];
|
||||
|
||||
// convert data to spherical coordinates
|
||||
int i;
|
||||
T empty;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
GetSphericalCoords(x[i],y[i],z[i],theta[i],phi[i]);
|
||||
func[i] = f[i];
|
||||
}
|
||||
|
||||
// use periodicity to get wrap-around in the Delaunay triangulation
|
||||
// cout << "[ 10%] copying vertices for wrap-around\r";
|
||||
int j, k;
|
||||
for (i = 0, j = n, k = 2*n; i < n; i++, j++, k++)
|
||||
{
|
||||
theta[j] = theta[i]+TWOPI;
|
||||
theta[k] = theta[i]-TWOPI;
|
||||
phi[j] = phi[i];
|
||||
phi[k] = phi[i];
|
||||
func[j] = func[i];
|
||||
func[k] = func[i];
|
||||
}
|
||||
|
||||
pInterp = new mgcLinInterp2D<T>(3*n,theta,phi,func);
|
||||
|
||||
// cout << "[100%] Finished initialising spherical interpolator. \n";
|
||||
}
|
||||
|
||||
template<class T>
|
||||
SphereInterpolate<T>::SphereInterpolate (int n, const sgVec2* p, const T* f)
|
||||
{
|
||||
// Assumes (x[i],y[i],z[i]) is unit length for all 0 <= i < n.
|
||||
// For complete spherical coverage, include the two antipodal points
|
||||
// (0,0,1,f(0,0,1)) and (0,0,-1,f(0,0,-1)) in the data set.
|
||||
// cout << "Initialising spherical interpolator.\n";
|
||||
// cout << "[ 0%] Allocating memory \r";
|
||||
|
||||
theta = new double[3*n];
|
||||
phi = new double[3*n];
|
||||
func = new T[3*n];
|
||||
|
||||
// convert data to spherical coordinates
|
||||
// cout << "[ 10%] copying vertices for wrap-around \r";
|
||||
|
||||
int i, j, k;
|
||||
for (i = 0, j = n, k = 2*n; i < n; i++, j++, k++)
|
||||
{
|
||||
phi[i] = p[i][0];
|
||||
theta[i] = p[i][1];
|
||||
func[i] = f[i];
|
||||
|
||||
// use periodicity to get wrap-around in the Delaunay triangulation
|
||||
phi[j] = phi[i];
|
||||
phi[k] = phi[i];
|
||||
theta[j] = theta[i]+TWOPI;
|
||||
theta[k] = theta[i]-TWOPI;
|
||||
func[j] = func[i];
|
||||
func[k] = func[i];
|
||||
}
|
||||
|
||||
pInterp = new mgcLinInterp2D<T>(3*n,theta,phi,func);
|
||||
|
||||
// cout << "[100%] Finished initialising spherical interpolator. \n";
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
SphereInterpolate<T>::~SphereInterpolate ()
|
||||
{
|
||||
delete pInterp;
|
||||
delete[] theta;
|
||||
delete[] phi;
|
||||
delete[] func;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void SphereInterpolate<T>::GetSphericalCoords (const double x, const double y, const double z,
|
||||
double& thetaAngle,
|
||||
double& phiAngle) const
|
||||
{
|
||||
// Assumes (x,y,z) is unit length. Returns -PI <= thetaAngle <= PI
|
||||
// and 0 <= phiAngle <= PI.
|
||||
|
||||
if ( z < 1.0f )
|
||||
{
|
||||
if ( z > -1.0f )
|
||||
{
|
||||
thetaAngle = atan2(y,x);
|
||||
phiAngle = acos(z);
|
||||
}
|
||||
else
|
||||
{
|
||||
thetaAngle = -PI;
|
||||
phiAngle = PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thetaAngle = -PI;
|
||||
phiAngle = 0.0f;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int SphereInterpolate<T>::Evaluate (const double x, const double y, const double z, T& f) const
|
||||
{
|
||||
// assumes (x,y,z) is unit length
|
||||
|
||||
double thetaAngle, phiAngle;
|
||||
GetSphericalCoords(x,y,z,thetaAngle,phiAngle);
|
||||
return pInterp->Evaluate(thetaAngle,phiAngle,f);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int SphereInterpolate<T>::Evaluate (const double thetaAngle, const double phiAngle, T& f) const
|
||||
{
|
||||
return pInterp->Evaluate(thetaAngle,phiAngle,f);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
+11
-23
@@ -200,29 +200,15 @@ void naFreeContext(struct Context* c)
|
||||
UNLOCK();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is the original code which might not work properly on all
|
||||
* platforms since it allows one to work on the same variable in one
|
||||
* statement without the prior knowledge how this will behave.
|
||||
*
|
||||
* e.g. ctx->opStack[ctx->opTop++] = ctx->opStack[ctx->opTop-1];
|
||||
* ^^^^^ ^^^^^
|
||||
*/
|
||||
# define PUSH(r) do { \
|
||||
// Note that opTop is incremented separately, to avoid situations
|
||||
// where the "r" expression also references opTop. The SGI compiler
|
||||
// is known to have issues with such code.
|
||||
#define PUSH(r) do { \
|
||||
if(ctx->opTop >= MAX_STACK_DEPTH) ERR(ctx, "stack overflow"); \
|
||||
ctx->opStack[ctx->opTop++] = r; \
|
||||
ctx->opStack[ctx->opTop] = r; \
|
||||
ctx->opTop++; \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
|
||||
# define PUSH(r) _PUSH((ctx), (r))
|
||||
void _PUSH(struct Context* ctx, naRef r) {
|
||||
if(ctx->opTop >= MAX_STACK_DEPTH) ERR(ctx, "stack overflow");
|
||||
ctx->opStack[ctx->opTop++] = r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void setupArgs(naContext ctx, struct Frame* f, naRef* args, int nargs)
|
||||
{
|
||||
int i;
|
||||
@@ -402,15 +388,14 @@ static int getMember(struct Context* ctx, naRef obj, naRef fld,
|
||||
}
|
||||
|
||||
// OP_EACH works like a vector get, except that it leaves the vector
|
||||
// and index on the stack, increments the index after use, and pops
|
||||
// the arguments and pushes a nil if the index is beyond the end.
|
||||
// and index on the stack, increments the index after use, and
|
||||
// pushes a nil if the index is beyond the end.
|
||||
static void evalEach(struct Context* ctx, int useIndex)
|
||||
{
|
||||
int idx = (int)(ctx->opStack[ctx->opTop-1].num);
|
||||
naRef vec = ctx->opStack[ctx->opTop-2];
|
||||
if(!IS_VEC(vec)) naRuntimeError(ctx, "foreach enumeration of non-vector");
|
||||
if(!vec.ref.ptr.vec->rec || idx >= vec.ref.ptr.vec->rec->size) {
|
||||
ctx->opTop -= 2; // pop two values
|
||||
PUSH(naNil());
|
||||
return;
|
||||
}
|
||||
@@ -616,6 +601,9 @@ static naRef run(struct Context* ctx)
|
||||
ctx->markTop--;
|
||||
break;
|
||||
case OP_BREAK: // restore stack state (FOLLOW WITH JMP!)
|
||||
ctx->opTop = ctx->markStack[ctx->markTop-1];
|
||||
break;
|
||||
case OP_BREAK2: // same, but also pop the mark stack
|
||||
ctx->opTop = ctx->markStack[--ctx->markTop];
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -22,7 +22,7 @@ enum {
|
||||
OP_DUP, OP_XCHG, OP_INSERT, OP_EXTRACT, OP_MEMBER, OP_SETMEMBER,
|
||||
OP_LOCAL, OP_SETLOCAL, OP_NEWVEC, OP_VAPPEND, OP_NEWHASH, OP_HAPPEND,
|
||||
OP_MARK, OP_UNMARK, OP_BREAK, OP_FTAIL, OP_MTAIL, OP_SETSYM, OP_DUP2,
|
||||
OP_INDEX
|
||||
OP_INDEX, OP_BREAK2
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
|
||||
@@ -480,9 +480,9 @@ static void genForEach(struct Parser* p, struct Token* t)
|
||||
vec = RIGHT(h);
|
||||
body = RIGHT(t)->children;
|
||||
|
||||
pushLoop(p, label);
|
||||
genExpr(p, vec);
|
||||
emit(p, OP_PUSHZERO);
|
||||
pushLoop(p, label);
|
||||
loopTop = p->cg->codesz;
|
||||
emit(p, t->type == TOK_FOREACH ? OP_EACH : OP_INDEX);
|
||||
jumpEnd = emitJump(p, OP_JIFNIL);
|
||||
@@ -491,6 +491,8 @@ static void genForEach(struct Parser* p, struct Token* t)
|
||||
emit(p, assignOp);
|
||||
emit(p, OP_POP);
|
||||
genLoop(p, body, 0, label, loopTop, jumpEnd);
|
||||
emit(p, OP_POP); // Pull off the vector and index
|
||||
emit(p, OP_POP);
|
||||
}
|
||||
|
||||
static int tokMatch(struct Token* a, struct Token* b)
|
||||
@@ -518,7 +520,7 @@ static void genBreakContinue(struct Parser* p, struct Token* t)
|
||||
bp = p->cg->loops[p->cg->loopTop - levels].breakIP;
|
||||
cp = p->cg->loops[p->cg->loopTop - levels].contIP;
|
||||
for(i=0; i<levels; i++)
|
||||
emit(p, OP_BREAK);
|
||||
emit(p, (i<levels-1) ? OP_BREAK2 : OP_BREAK);
|
||||
if(t->type == TOK_BREAK)
|
||||
emit(p, OP_PUSHNIL); // breakIP is always a JIFNOT/JIFNIL!
|
||||
emitImmediate(p, OP_JMP, t->type == TOK_BREAK ? bp : cp);
|
||||
|
||||
+7
-20
@@ -136,28 +136,15 @@ static void naGhost_gcclean(struct naGhost* g)
|
||||
|
||||
static void freeelem(struct naPool* p, struct naObj* o)
|
||||
{
|
||||
// Free any intrinsic (i.e. non-garbage collected) storage the
|
||||
// object might have
|
||||
// Clean up any intrinsic storage the object might have...
|
||||
switch(p->type) {
|
||||
case T_STR:
|
||||
naStr_gcclean((struct naStr*)o);
|
||||
break;
|
||||
case T_VEC:
|
||||
naVec_gcclean((struct naVec*)o);
|
||||
break;
|
||||
case T_HASH:
|
||||
naHash_gcclean((struct naHash*)o);
|
||||
break;
|
||||
case T_CODE:
|
||||
naCode_gcclean((struct naCode*)o);
|
||||
break;
|
||||
case T_GHOST:
|
||||
naGhost_gcclean((struct naGhost*)o);
|
||||
break;
|
||||
case T_STR: naStr_gcclean ((struct naStr*) o); break;
|
||||
case T_VEC: naVec_gcclean ((struct naVec*) o); break;
|
||||
case T_HASH: naHash_gcclean ((struct naHash*) o); break;
|
||||
case T_CODE: naCode_gcclean ((struct naCode*) o); break;
|
||||
case T_GHOST: naGhost_gcclean((struct naGhost*)o); break;
|
||||
}
|
||||
|
||||
// And add it to the free list
|
||||
p->free[p->nfree++] = o;
|
||||
p->free[p->nfree++] = o; // ...and add it to the free list
|
||||
}
|
||||
|
||||
static void newBlock(struct naPool* p, int need)
|
||||
|
||||
@@ -49,7 +49,7 @@ static unsigned int hashcolumn(struct HashRec* h, naRef key)
|
||||
return (HASH_MAGIC * hashcode(key)) >> (32 - h->lgalloced);
|
||||
}
|
||||
|
||||
static struct HashRec* hashrealloc(struct naHash* hash)
|
||||
static struct HashRec* resize(struct naHash* hash)
|
||||
{
|
||||
struct HashRec *h, *h0 = hash->rec;
|
||||
int lga, cols, need = h0 ? h0->size - h0->dels : MIN_HASH_SIZE;
|
||||
@@ -119,6 +119,7 @@ static void tmpStr(naRef* out, struct naStr* str, char* key)
|
||||
{
|
||||
str->len = 0;
|
||||
str->data = (unsigned char*)key;
|
||||
str->hashcode = 0;
|
||||
while(key[str->len]) str->len++;
|
||||
*out = naNil();
|
||||
out->ref.ptr.str = str;
|
||||
@@ -171,7 +172,7 @@ void naHash_newsym(struct naHash* hash, naRef* sym, naRef* val)
|
||||
int col;
|
||||
struct HashRec* h = hash->rec;
|
||||
while(!h || h->size >= 1<<h->lgalloced)
|
||||
h = hashrealloc(hash);
|
||||
h = resize(hash);
|
||||
col = (HASH_MAGIC * sym->ref.ptr.str->hashcode) >> (32 - h->lgalloced);
|
||||
INSERT(h, *sym, *val, col);
|
||||
}
|
||||
@@ -198,7 +199,7 @@ void naHash_set(naRef hash, naRef key, naRef val)
|
||||
if((n = find(hash.ref.ptr.hash, key))) { n->val = val; return; }
|
||||
h = hash.ref.ptr.hash->rec;
|
||||
while(!h || h->size >= 1<<h->lgalloced)
|
||||
h = hashrealloc(hash.ref.ptr.hash);
|
||||
h = resize(hash.ref.ptr.hash);
|
||||
col = hashcolumn(h, key);
|
||||
INSERT(h, key, val, hashcolumn(h, key));
|
||||
chkcycle(h->table[col], h->size - h->dels);
|
||||
|
||||
+15
-8
@@ -67,7 +67,7 @@ static naRef subvec(naContext c, naRef me, int argc, naRef* args)
|
||||
nlen = argc > 2 ? naNumValue(args[2]) : naNil();
|
||||
if(!naIsNil(nlen))
|
||||
len = (int)nlen.num;
|
||||
if(!naIsVector(v) || start < 0 || start >= naVec_size(v) || len < 0)
|
||||
if(!naIsVector(v) || start < 0 || start > naVec_size(v) || len < 0)
|
||||
return naNil();
|
||||
if(naIsNil(nlen) || len > naVec_size(v) - start)
|
||||
len = naVec_size(v) - start;
|
||||
@@ -180,8 +180,8 @@ static naRef f_compile(naContext c, naRef me, int argc, naRef* args)
|
||||
int errLine;
|
||||
naRef script, code, fname;
|
||||
script = argc > 0 ? args[0] : naNil();
|
||||
if(!naIsString(script)) return naNil();
|
||||
fname = NEWCSTR(c, "<compile>");
|
||||
fname = argc > 1 ? args[1] : NEWCSTR(c, "<compile>");
|
||||
if(!naIsString(script) || !naIsString(fname)) return naNil();
|
||||
code = naParseCode(c, fname, 1,
|
||||
naStr_data(script), naStr_len(script), &errLine);
|
||||
if(!naIsCode(code)) return naNil(); // FIXME: export error to caller...
|
||||
@@ -208,9 +208,17 @@ static naRef f_call(naContext c, naRef me, int argc, naRef* args)
|
||||
callme, callns);
|
||||
c->callChild = 0;
|
||||
if(argc > 2 && IS_VEC(args[argc-1])) {
|
||||
if(!IS_NIL(subc->dieArg)) naVec_append(args[argc-1], subc->dieArg);
|
||||
naRef v = args[argc-1];
|
||||
if(!IS_NIL(subc->dieArg)) naVec_append(v, subc->dieArg);
|
||||
else if(naGetError(subc))
|
||||
naVec_append(args[argc-1], NEWCSTR(subc, naGetError(subc)));
|
||||
naVec_append(v, NEWCSTR(subc, naGetError(subc)));
|
||||
if(naVec_size(v)) {
|
||||
int i, sd = naStackDepth(subc);
|
||||
for(i=0; i<sd; i++) {
|
||||
naVec_append(v, naGetSourceFile(subc, i));
|
||||
naVec_append(v, naNum(naGetLine(subc, i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
naFreeContext(subc);
|
||||
return result;
|
||||
@@ -349,10 +357,9 @@ static naRef f_caller(naContext ctx, naRef me, int argc, naRef* args)
|
||||
static naRef f_closure(naContext ctx, naRef me, int argc, naRef* args)
|
||||
{
|
||||
int i;
|
||||
naRef func, idx;
|
||||
struct naFunc* f;
|
||||
func = argc > 0 ? args[0] : naNil();
|
||||
idx = argc > 1 ? naNumValue(args[1]) : naNil();
|
||||
naRef func = argc > 0 ? args[0] : naNil();
|
||||
naRef idx = argc > 1 ? naNumValue(args[1]) : naNum(0);
|
||||
if(!IS_FUNC(func) || IS_NIL(idx))
|
||||
naRuntimeError(ctx, "bad arguments to closure()");
|
||||
i = (int)idx.num;
|
||||
|
||||
@@ -13,7 +13,7 @@ static struct VecRec* newvecrec(struct VecRec* old)
|
||||
return vr;
|
||||
}
|
||||
|
||||
static void vecrealloc(struct naVec* v)
|
||||
static void resize(struct naVec* v)
|
||||
{
|
||||
struct VecRec* vr = newvecrec(v->rec);
|
||||
naGC_swapfree((void**)&(v->rec), vr);
|
||||
@@ -60,7 +60,7 @@ int naVec_append(naRef vec, naRef o)
|
||||
if(IS_VEC(vec)) {
|
||||
struct VecRec* r = vec.ref.ptr.vec->rec;
|
||||
while(!r || r->size >= r->alloced) {
|
||||
vecrealloc(vec.ref.ptr.vec);
|
||||
resize(vec.ref.ptr.vec);
|
||||
r = vec.ref.ptr.vec->rec;
|
||||
}
|
||||
r->array[r->size] = o;
|
||||
@@ -91,7 +91,7 @@ naRef naVec_removelast(naRef vec)
|
||||
o = v->array[v->size - 1];
|
||||
v->size--;
|
||||
if(v->size < (v->alloced >> 1))
|
||||
vecrealloc(vec.ref.ptr.vec);
|
||||
resize(vec.ref.ptr.vec);
|
||||
return o;
|
||||
}
|
||||
return naNil();
|
||||
|
||||
@@ -756,7 +756,13 @@ SGPropertyNode::~SGPropertyNode ()
|
||||
_removedChildren[i]->_parent = 0;
|
||||
delete _path_cache;
|
||||
clearValue();
|
||||
delete _listeners;
|
||||
|
||||
if (_listeners) {
|
||||
vector<SGPropertyChangeListener*>::iterator it;
|
||||
for (it = _listeners->begin(); it != _listeners->end(); ++it)
|
||||
(*it)->unregister_property(this);
|
||||
delete _listeners;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2280,12 +2286,8 @@ SGPropertyNode::hash_table::hashcode (const char * key)
|
||||
|
||||
SGPropertyChangeListener::~SGPropertyChangeListener ()
|
||||
{
|
||||
// This will come back and remove
|
||||
// the current item each time. Is
|
||||
// that OK?
|
||||
vector<SGPropertyNode *>::iterator it;
|
||||
for (it = _properties.begin(); it != _properties.end(); it++)
|
||||
(*it)->removeChangeListener(this);
|
||||
for (int i = _properties.size() - 1; i >= 0; i--)
|
||||
_properties[i]->removeChangeListener(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+16
-7
@@ -70,11 +70,14 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a waypoint.
|
||||
* Add waypoint (default), or insert waypoint at position n.
|
||||
* @param wp a waypoint
|
||||
*/
|
||||
inline void add_waypoint( const SGWayPoint &wp ) {
|
||||
route.push_back( wp );
|
||||
void add_waypoint( const SGWayPoint &wp, int n = -1 ) {
|
||||
if ( n < 0 || n >= (int)route.size() )
|
||||
route.push_back( wp );
|
||||
else
|
||||
route.insert( route.begin() + n, 1, wp );
|
||||
|
||||
int size = route.size();
|
||||
if ( size > 1 ) {
|
||||
@@ -146,10 +149,16 @@ public:
|
||||
}
|
||||
|
||||
/** Delete the front waypoint */
|
||||
inline void delete_first() {
|
||||
if ( route.size() ) {
|
||||
route.erase( route.begin() );
|
||||
}
|
||||
inline void delete_first() { delete_waypoint(0); }
|
||||
|
||||
/** Delete waypoint waypoint with index n (last one if n < 0) */
|
||||
void delete_waypoint( int n = 0 ) {
|
||||
if ( !route.size() )
|
||||
return;
|
||||
if ( n < 0 || n >= (int)route.size() )
|
||||
n = route.size() - 1;
|
||||
|
||||
route.erase( route.begin() + n );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,6 +43,9 @@ SG_USING_STD(map);
|
||||
|
||||
#include "mat.hxx"
|
||||
|
||||
static map<string, ssgTexture *> _tex_cache;
|
||||
static map<string, ssgTexture *>::iterator _tex_cache_iter;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Constructors and destructor.
|
||||
@@ -120,6 +123,7 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
|
||||
string tname = "unknown.rgb";
|
||||
SGPath tpath( fg_root );
|
||||
tpath.append("Textures");
|
||||
tpath.append("Terrain");
|
||||
tpath.append(tname);
|
||||
_internal_state st( NULL, tpath.str(), true );
|
||||
_status.push_back( st );
|
||||
@@ -132,6 +136,13 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
|
||||
mipmap = props->getBoolValue("mipmap", true);
|
||||
light_coverage = props->getDoubleValue("light-coverage", 0.0);
|
||||
|
||||
// surface values for use with ground reactions
|
||||
solid = props->getBoolValue("solid", true);
|
||||
friction_factor = props->getDoubleValue("friction-factor", 1.0);
|
||||
rolling_friction = props->getDoubleValue("rolling-friction", 0.02);
|
||||
bumpiness = props->getDoubleValue("bumpiness", 0.0);
|
||||
load_resistence = props->getDoubleValue("load-resistence", 1e30);
|
||||
|
||||
// Taken from default values as used in ac3d
|
||||
ambient[0] = props->getDoubleValue("ambient/r", 0.2);
|
||||
ambient[1] = props->getDoubleValue("ambient/g", 0.2);
|
||||
@@ -159,6 +170,14 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
|
||||
((SGPropertyNode *)props)->getChildren("object-group");
|
||||
for (unsigned int i = 0; i < object_group_nodes.size(); i++)
|
||||
object_groups.push_back(new SGMatModelGroup(object_group_nodes[i]));
|
||||
|
||||
// read glyph table for taxi-/runway-signs
|
||||
vector<SGPropertyNode_ptr> glyph_nodes = props->getChildren("glyph");
|
||||
for (unsigned int i = 0; i < glyph_nodes.size(); i++) {
|
||||
const char *name = glyph_nodes[i]->getStringValue("name");
|
||||
if (name)
|
||||
glyphs[name] = new SGMaterialGlyph(glyph_nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,8 +195,16 @@ SGMaterial::init ()
|
||||
ysize = 0;
|
||||
wrapu = true;
|
||||
wrapv = true;
|
||||
|
||||
mipmap = true;
|
||||
light_coverage = 0.0;
|
||||
|
||||
solid = true;
|
||||
friction_factor = 1;
|
||||
rolling_friction = 0.02;
|
||||
bumpiness = 0;
|
||||
load_resistence = 1e30;
|
||||
|
||||
shininess = 1.0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ambient[i] = (i < 3) ? 0.2 : 1.0;
|
||||
@@ -198,9 +225,8 @@ SGMaterial::load_texture ( int n )
|
||||
if ( !_status[i].texture_loaded ) {
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture "
|
||||
<< _status[i].texture_path );
|
||||
_status[i].state->setTexture(
|
||||
(char *)_status[i].texture_path.c_str(),
|
||||
wrapu, wrapv, mipmap );
|
||||
assignTexture(_status[i].state, _status[i].texture_path,
|
||||
wrapu, wrapv, mipmap );
|
||||
_status[i].texture_loaded = true;
|
||||
}
|
||||
}
|
||||
@@ -244,8 +270,7 @@ SGMaterial::build_ssg_state( bool defer_tex_load )
|
||||
|
||||
if ( !defer_tex_load ) {
|
||||
SG_LOG(SG_INPUT, SG_INFO, " " << _status[i].texture_path );
|
||||
state->setTexture( (char *)_status[i].texture_path.c_str(),
|
||||
wrapu, wrapv );
|
||||
assignTexture( state, _status[i].texture_path, wrapu, wrapv );
|
||||
_status[i].texture_loaded = true;
|
||||
} else {
|
||||
_status[i].texture_loaded = false;
|
||||
@@ -276,4 +301,42 @@ void SGMaterial::set_ssg_state( ssgSimpleState *s )
|
||||
_status.push_back( _internal_state( s, "", true ) );
|
||||
}
|
||||
|
||||
void SGMaterial::assignTexture( ssgSimpleState *state, string &fname,
|
||||
int _wrapu, int _wrapv, int _mipmap )
|
||||
{
|
||||
_tex_cache_iter = _tex_cache.find(fname);
|
||||
if (_tex_cache_iter == _tex_cache.end())
|
||||
{
|
||||
state->setTexture((char *)fname.c_str(), _wrapu, _wrapv, _mipmap);
|
||||
_tex_cache[fname] = state->getTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
state->setTexture(_tex_cache_iter->second);
|
||||
// cout << "Cache hit: " << fname << endl;
|
||||
}
|
||||
}
|
||||
|
||||
SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const
|
||||
{
|
||||
map<string, SGSharedPtr<SGMaterialGlyph> >::const_iterator it;
|
||||
it = glyphs.find(name);
|
||||
if (it == glyphs.end())
|
||||
return 0;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SGMaterialGlyph.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SGMaterialGlyph::SGMaterialGlyph(SGPropertyNode *p) :
|
||||
_left(p->getDoubleValue("left", 0.0)),
|
||||
_right(p->getDoubleValue("right", 1.0))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// end of mat.cxx
|
||||
|
||||
+104
-12
@@ -34,6 +34,9 @@
|
||||
|
||||
#include STL_STRING // Standard C++ string library
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
@@ -46,6 +49,10 @@
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
|
||||
|
||||
class SGMaterialGlyph;
|
||||
|
||||
|
||||
/**
|
||||
@@ -99,7 +106,7 @@ public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~SGMaterial( void );
|
||||
~SGMaterial( void );
|
||||
|
||||
|
||||
|
||||
@@ -113,31 +120,31 @@ public:
|
||||
* @return true if the texture loaded, false if it was loaded
|
||||
* already.
|
||||
*/
|
||||
virtual bool load_texture (int n = -1);
|
||||
bool load_texture (int n = -1);
|
||||
|
||||
|
||||
/**
|
||||
* Get the textured state.
|
||||
*/
|
||||
virtual ssgSimpleState *get_state (int n = -1) const;
|
||||
ssgSimpleState *get_state (int n = -1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of textures assigned to this material.
|
||||
*/
|
||||
virtual inline int get_num() const { return _status.size(); }
|
||||
inline int get_num() const { return _status.size(); }
|
||||
|
||||
|
||||
/**
|
||||
* Get the xsize of the texture, in meters.
|
||||
*/
|
||||
virtual inline double get_xsize() const { return xsize; }
|
||||
inline double get_xsize() const { return xsize; }
|
||||
|
||||
|
||||
/**
|
||||
* Get the ysize of the texture, in meters.
|
||||
*/
|
||||
virtual inline double get_ysize() const { return ysize; }
|
||||
inline double get_ysize() const { return ysize; }
|
||||
|
||||
|
||||
/**
|
||||
@@ -147,22 +154,61 @@ public:
|
||||
*
|
||||
* @return The area (m^2?) covered by each light.
|
||||
*/
|
||||
virtual inline double get_light_coverage () const { return light_coverage; }
|
||||
inline double get_light_coverage () const { return light_coverage; }
|
||||
|
||||
/**
|
||||
* Return if the surface material is solid, if it is not solid, a fluid
|
||||
* can be assumed, that is usually water.
|
||||
*/
|
||||
bool get_solid () const { return solid; }
|
||||
|
||||
/**
|
||||
* Get the friction factor for that material
|
||||
*/
|
||||
double get_friction_factor () const { return friction_factor; }
|
||||
|
||||
/**
|
||||
* Get the rolling friction for that material
|
||||
*/
|
||||
double get_rolling_friction () const { return rolling_friction; }
|
||||
|
||||
/**
|
||||
* Get the bumpines for that material
|
||||
*/
|
||||
double get_bumpiness () const { return bumpiness; }
|
||||
|
||||
/**
|
||||
* Get the load resistence
|
||||
*/
|
||||
double get_load_resistence () const { return load_resistence; }
|
||||
|
||||
/**
|
||||
* Get the list of names for this material
|
||||
*/
|
||||
const vector<string>& get_names() const { return _names; }
|
||||
|
||||
/**
|
||||
* add the given name to the list of names this material is known
|
||||
*/
|
||||
void add_name(const string& name) { _names.push_back(name); }
|
||||
|
||||
/**
|
||||
* Get the number of randomly-placed objects defined for this material.
|
||||
*/
|
||||
virtual int get_object_group_count () const { return object_groups.size(); }
|
||||
|
||||
int get_object_group_count () const { return object_groups.size(); }
|
||||
|
||||
/**
|
||||
* Get a randomly-placed object for this material.
|
||||
*/
|
||||
virtual SGMatModelGroup * get_object_group (int index) const {
|
||||
SGMatModelGroup * get_object_group (int index) const {
|
||||
return object_groups[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return pointer to glyph class, or 0 if it doesn't exist.
|
||||
*/
|
||||
SGMaterialGlyph * get_glyph (const string& name) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -173,7 +219,7 @@ protected:
|
||||
/**
|
||||
* Initialization method, invoked by all public constructors.
|
||||
*/
|
||||
virtual void init();
|
||||
void init();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -210,12 +256,33 @@ private:
|
||||
// coverage of night lighting.
|
||||
double light_coverage;
|
||||
|
||||
// True if the material is solid, false if it is a fluid
|
||||
bool solid;
|
||||
|
||||
// the friction factor of that surface material
|
||||
double friction_factor;
|
||||
|
||||
// the rolling friction of that surface material
|
||||
double rolling_friction;
|
||||
|
||||
// the bumpiness of that surface material
|
||||
double bumpiness;
|
||||
|
||||
// the load resistence of that surface material
|
||||
double load_resistence;
|
||||
|
||||
// material properties
|
||||
sgVec4 ambient, diffuse, specular, emission;
|
||||
SGVec4f ambient, diffuse, specular, emission;
|
||||
double shininess;
|
||||
|
||||
// the list of names for this material. May be empty.
|
||||
vector<string> _names;
|
||||
|
||||
vector<SGSharedPtr<SGMatModelGroup> > object_groups;
|
||||
|
||||
// taxiway-/runway-sign texture elements
|
||||
map<string, SGSharedPtr<SGMaterialGlyph> > glyphs;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Internal constructors and methods.
|
||||
@@ -227,7 +294,32 @@ private:
|
||||
void build_ssg_state( bool defer_tex_load );
|
||||
void set_ssg_state( ssgSimpleState *s );
|
||||
|
||||
void assignTexture( ssgSimpleState *state, string &fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE );
|
||||
|
||||
};
|
||||
|
||||
|
||||
class SGMaterialGlyph : public SGReferenced {
|
||||
public:
|
||||
SGMaterialGlyph(SGPropertyNode *);
|
||||
inline double get_left() const { return _left; }
|
||||
inline double get_right() const { return _right; }
|
||||
inline double get_width() const { return _right - _left; }
|
||||
|
||||
protected:
|
||||
double _left;
|
||||
double _right;
|
||||
};
|
||||
|
||||
class SGMaterialUserData : public ssgBase {
|
||||
public:
|
||||
SGMaterialUserData(const SGMaterial* material) :
|
||||
mMaterial(material)
|
||||
{}
|
||||
const SGMaterial* getMaterial() const
|
||||
{ return mMaterial; }
|
||||
private:
|
||||
SGSharedPtr<const SGMaterial> mMaterial;
|
||||
};
|
||||
|
||||
#endif // _SG_MAT_HXX
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
@@ -46,6 +48,7 @@
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/scene/tgdb/userdata.hxx>
|
||||
|
||||
#include "mat.hxx"
|
||||
|
||||
@@ -55,6 +58,10 @@ SG_USING_NAMESPACE(std);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
// FIXME: should make this configurable
|
||||
static const bool sprite_lighting = true;
|
||||
|
||||
|
||||
// Constructor
|
||||
SGMaterialLib::SGMaterialLib ( void ) {
|
||||
}
|
||||
@@ -99,6 +106,42 @@ static int gen_test_light_map() {
|
||||
#endif
|
||||
|
||||
|
||||
// generate a light sprite texture map
|
||||
static int gen_standard_light_sprite( int r, int g, int b, int alpha ) {
|
||||
const int env_tex_res = 32;
|
||||
int half_res = env_tex_res / 2;
|
||||
unsigned char env_map[env_tex_res][env_tex_res][4];
|
||||
GLuint tex_name;
|
||||
|
||||
for ( int i = 0; i < env_tex_res; ++i ) {
|
||||
for ( int j = 0; j < env_tex_res; ++j ) {
|
||||
double x = (i - half_res) / (double)half_res;
|
||||
double y = (j - half_res) / (double)half_res;
|
||||
double dist = sqrt(x*x + y*y);
|
||||
if ( dist > 1.0 ) { dist = 1.0; }
|
||||
double bright = cos( dist * SGD_PI_2 );
|
||||
if ( bright < 0.01 ) { bright = 0.0; }
|
||||
env_map[i][j][0] = r;
|
||||
env_map[i][j][1] = g;
|
||||
env_map[i][j][2] = b;
|
||||
env_map[i][j][3] = (int)(bright * alpha);
|
||||
}
|
||||
}
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
glGenTextures( 1, &tex_name );
|
||||
glBindTexture( GL_TEXTURE_2D, tex_name );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, env_map);
|
||||
|
||||
return tex_name;
|
||||
}
|
||||
|
||||
|
||||
// generate standard colored directional light environment texture map
|
||||
static int gen_standard_dir_light_map( int r, int g, int b, int alpha ) {
|
||||
const int env_tex_res = 32;
|
||||
@@ -188,17 +231,20 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
throw;
|
||||
}
|
||||
|
||||
SGSharedPtr<SGMaterial> m;
|
||||
|
||||
int nMaterials = materials.nChildren();
|
||||
for (int i = 0; i < nMaterials; i++) {
|
||||
const SGPropertyNode * node = materials.getChild(i);
|
||||
if (!strcmp(node->getName(), "material")) {
|
||||
SGSharedPtr<SGMaterial> m = new SGMaterial( fg_root, node, season );
|
||||
m = new SGMaterial( fg_root, node, season );
|
||||
|
||||
vector<SGPropertyNode_ptr>names = node->getChildren("name");
|
||||
for ( unsigned int j = 0; j < names.size(); j++ ) {
|
||||
string name = names[j]->getStringValue();
|
||||
// cerr << "Material " << name << endl;
|
||||
matlib[name] = m;
|
||||
m->add_name(name);
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
|
||||
<< names[j]->getStringValue() );
|
||||
}
|
||||
@@ -219,12 +265,18 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
gnd_lights->enable( GL_BLEND );
|
||||
gnd_lights->disable( GL_ALPHA_TEST );
|
||||
gnd_lights->disable( GL_LIGHTING );
|
||||
matlib["GROUND_LIGHTS"] = new SGMaterial( gnd_lights );
|
||||
m = new SGMaterial( gnd_lights );
|
||||
m->add_name("GROUND_LIGHTS");
|
||||
matlib["GROUND_LIGHTS"] = m;
|
||||
|
||||
GLuint tex_name;
|
||||
|
||||
// hard coded runway white light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
|
||||
}
|
||||
ssgSimpleState *rwy_white_lights = new ssgSimpleState();
|
||||
rwy_white_lights->disable( GL_LIGHTING );
|
||||
rwy_white_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -237,14 +289,22 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_lights->setTexture( tex_name );
|
||||
matlib["RWY_WHITE_LIGHTS"] = new SGMaterial( rwy_white_lights );
|
||||
m = new SGMaterial( rwy_white_lights );
|
||||
m->add_name("RWY_WHITE_LIGHTS");
|
||||
matlib["RWY_WHITE_LIGHTS"] = m;
|
||||
// For backwards compatibility ... remove someday
|
||||
matlib["RUNWAY_LIGHTS"] = new SGMaterial( rwy_white_lights );
|
||||
matlib["RWY_LIGHTS"] = new SGMaterial( rwy_white_lights );
|
||||
m->add_name("RUNWAY_LIGHTS");
|
||||
matlib["RUNWAY_LIGHTS"] = m;
|
||||
m->add_name("RWY_LIGHTS");
|
||||
matlib["RWY_LIGHTS"] = m;
|
||||
// end of backwards compatitibilty
|
||||
|
||||
// hard coded runway medium intensity white light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 235, 195, 205 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
|
||||
}
|
||||
ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
|
||||
rwy_white_medium_lights->disable( GL_LIGHTING );
|
||||
rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -257,11 +317,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_medium_lights->setTexture( tex_name );
|
||||
matlib["RWY_WHITE_MEDIUM_LIGHTS"]
|
||||
= new SGMaterial( rwy_white_medium_lights );
|
||||
m = new SGMaterial( rwy_white_medium_lights );
|
||||
m->add_name("RWY_WHITE_MEDIUM_LIGHTS");
|
||||
matlib["RWY_WHITE_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway low intensity white light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 235, 195, 155 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
|
||||
}
|
||||
ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
|
||||
rwy_white_low_lights->disable( GL_LIGHTING );
|
||||
rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -274,11 +339,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_white_low_lights->setTexture( tex_name );
|
||||
matlib["RWY_WHITE_LOW_LIGHTS"]
|
||||
= new SGMaterial( rwy_white_low_lights );
|
||||
m = new SGMaterial( rwy_white_low_lights );
|
||||
m->add_name("RWY_WHITE_LOW_LIGHTS");
|
||||
matlib["RWY_WHITE_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway yellow light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 215, 20, 255 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
|
||||
}
|
||||
ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
|
||||
rwy_yellow_lights->disable( GL_LIGHTING );
|
||||
rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -291,10 +361,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_lights->setTexture( tex_name );
|
||||
matlib["RWY_YELLOW_LIGHTS"] = new SGMaterial( rwy_yellow_lights );
|
||||
m = new SGMaterial( rwy_yellow_lights );
|
||||
m->add_name("RWY_YELLOW_LIGHTS");
|
||||
matlib["RWY_YELLOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway medium intensity yellow light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 215, 20, 205 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
|
||||
}
|
||||
ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
|
||||
rwy_yellow_medium_lights->disable( GL_LIGHTING );
|
||||
rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -307,11 +383,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_medium_lights->setTexture( tex_name );
|
||||
matlib["RWY_YELLOW_MEDIUM_LIGHTS"]
|
||||
= new SGMaterial( rwy_yellow_medium_lights );
|
||||
m = new SGMaterial( rwy_yellow_medium_lights );
|
||||
m->add_name("RWY_YELLOW_MEDIUM_LIGHTS");
|
||||
matlib["RWY_YELLOW_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway low intensity yellow light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 215, 20, 155 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
|
||||
}
|
||||
ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
|
||||
rwy_yellow_low_lights->disable( GL_LIGHTING );
|
||||
rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -324,11 +405,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_yellow_low_lights->setTexture( tex_name );
|
||||
matlib["RWY_YELLOW_LOW_LIGHTS"]
|
||||
= new SGMaterial( rwy_yellow_low_lights );
|
||||
m = new SGMaterial( rwy_yellow_low_lights );
|
||||
m->add_name("RWY_YELLOW_LOW_LIGHTS");
|
||||
matlib["RWY_YELLOW_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway red light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 90, 90, 255 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
|
||||
}
|
||||
ssgSimpleState *rwy_red_lights = new ssgSimpleState();
|
||||
rwy_red_lights->disable( GL_LIGHTING );
|
||||
rwy_red_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -341,11 +427,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_lights->setTexture( tex_name );
|
||||
matlib["RWY_RED_LIGHTS"]
|
||||
= new SGMaterial( rwy_red_lights );
|
||||
m = new SGMaterial( rwy_red_lights );
|
||||
m->add_name("RWY_RED_LIGHTS");
|
||||
matlib["RWY_RED_LIGHTS"] = m;
|
||||
|
||||
// hard coded medium intensity runway red light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 90, 90, 205 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
|
||||
}
|
||||
ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
|
||||
rwy_red_medium_lights->disable( GL_LIGHTING );
|
||||
rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -358,11 +449,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_medium_lights->setTexture( tex_name );
|
||||
matlib["RWY_RED_MEDIUM_LIGHTS"]
|
||||
= new SGMaterial( rwy_red_medium_lights );
|
||||
m = new SGMaterial( rwy_red_medium_lights );
|
||||
m->add_name("RWY_RED_MEDIUM_LIGHTS");
|
||||
matlib["RWY_RED_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity runway red light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 90, 90, 155 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
|
||||
}
|
||||
ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
|
||||
rwy_red_low_lights->disable( GL_LIGHTING );
|
||||
rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -375,11 +471,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_red_low_lights->setTexture( tex_name );
|
||||
matlib["RWY_RED_LOW_LIGHTS"]
|
||||
= new SGMaterial( rwy_red_low_lights );
|
||||
m = new SGMaterial( rwy_red_low_lights );
|
||||
m->add_name("RWY_RED_LOW_LIGHTS");
|
||||
matlib["RWY_RED_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway green light state
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 20, 235, 20, 255 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
|
||||
}
|
||||
ssgSimpleState *rwy_green_lights = new ssgSimpleState();
|
||||
rwy_green_lights->disable( GL_LIGHTING );
|
||||
rwy_green_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -392,11 +493,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_lights->setTexture( tex_name );
|
||||
matlib["RWY_GREEN_LIGHTS"]
|
||||
= new SGMaterial( rwy_green_lights );
|
||||
m = new SGMaterial( rwy_green_lights );
|
||||
m->add_name("RWY_GREEN_LIGHTS");
|
||||
matlib["RWY_GREEN_LIGHTS"] = m;
|
||||
|
||||
// hard coded medium intensity runway green light state
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 20, 235, 20, 205 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
|
||||
}
|
||||
ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
|
||||
rwy_green_medium_lights->disable( GL_LIGHTING );
|
||||
rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -409,11 +515,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_medium_lights->setTexture( tex_name );
|
||||
matlib["RWY_GREEN_MEDIUM_LIGHTS"]
|
||||
= new SGMaterial( rwy_green_medium_lights );
|
||||
m = new SGMaterial( rwy_green_medium_lights );
|
||||
m->add_name("RWY_GREEN_MEDIUM_LIGHTS");
|
||||
matlib["RWY_GREEN_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity runway green light state
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 20, 235, 20, 155 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
|
||||
}
|
||||
ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
|
||||
rwy_green_low_lights->disable( GL_LIGHTING );
|
||||
rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -426,13 +537,18 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
rwy_green_low_lights->setTexture( tex_name );
|
||||
matlib["RWY_GREEN_LOW_LIGHTS"]
|
||||
= new SGMaterial( rwy_green_low_lights );
|
||||
matlib["RWY_GREEN_TAXIWAY_LIGHTS"]
|
||||
= new SGMaterial( rwy_green_low_lights );
|
||||
m = new SGMaterial( rwy_green_low_lights );
|
||||
m->add_name("RWY_GREEN_LOW_LIGHTS");
|
||||
matlib["RWY_GREEN_LOW_LIGHTS"] = m;
|
||||
m->add_name("RWY_GREEN_TAXIWAY_LIGHTS");
|
||||
matlib["RWY_GREEN_TAXIWAY_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity taxiway blue light state
|
||||
tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 90, 90, 235, 205 );
|
||||
} else {
|
||||
tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
|
||||
}
|
||||
ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
|
||||
taxiway_blue_low_lights->disable( GL_LIGHTING );
|
||||
taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -445,11 +561,16 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
|
||||
taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
taxiway_blue_low_lights->setTexture( tex_name );
|
||||
matlib["RWY_BLUE_TAXIWAY_LIGHTS"]
|
||||
= new SGMaterial( taxiway_blue_low_lights );
|
||||
m = new SGMaterial( taxiway_blue_low_lights );
|
||||
m->add_name("RWY_BLUE_TAXIWAY_LIGHTS");
|
||||
matlib["RWY_BLUE_TAXIWAY_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway vasi light state
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
|
||||
if ( sprite_lighting ) {
|
||||
tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
|
||||
} else {
|
||||
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
|
||||
}
|
||||
ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
|
||||
rwy_vasi_lights->disable( GL_LIGHTING );
|
||||
rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
|
||||
@@ -463,7 +584,9 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
|
||||
// rwy_vasi_lights->setTexture( gen_vasi_light_map_old() );
|
||||
rwy_vasi_lights->setTexture( tex_name );
|
||||
matlib["RWY_VASI_LIGHTS"] = new SGMaterial( rwy_vasi_lights );
|
||||
m = new SGMaterial( rwy_vasi_lights );
|
||||
m->add_name("RWY_VASI_LIGHTS");
|
||||
matlib["RWY_VASI_LIGHTS"] = m;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -491,6 +614,7 @@ bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
|
||||
<< mat_name << " (" << full_path << ")");
|
||||
|
||||
matlib[mat_name] = new SGMaterial( full_path );
|
||||
matlib[mat_name]->add_name(mat_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -500,6 +624,7 @@ bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
|
||||
bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
|
||||
{
|
||||
matlib[mat_name] = new SGMaterial( state );
|
||||
matlib[mat_name]->add_name(mat_name);
|
||||
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, " Loading material given a premade "
|
||||
<< "ssgSimpleState = " << mat_name );
|
||||
@@ -538,3 +663,20 @@ void SGMaterialLib::load_next_deferred() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the material from that given leaf
|
||||
const SGMaterial* SGMaterialLib::findMaterial(/*const*/ssgLeaf* leaf) const
|
||||
{
|
||||
if (!leaf)
|
||||
return 0;
|
||||
|
||||
ssgBase* base = leaf->getUserData();
|
||||
if (!base)
|
||||
return 0;
|
||||
|
||||
SGMaterialUserData* matUserData = dynamic_cast<SGMaterialUserData*>(base);
|
||||
if (!matUserData)
|
||||
return 0;
|
||||
|
||||
return matUserData->getMaterial();
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
material_map_iterator end() { return matlib.end(); }
|
||||
const_material_map_iterator end() const { return matlib.end(); }
|
||||
|
||||
const SGMaterial* findMaterial(/*const*/ssgLeaf* leaf) const;
|
||||
|
||||
// Destructor
|
||||
~SGMaterialLib ( void );
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ include_HEADERS = \
|
||||
model.hxx \
|
||||
modellib.hxx \
|
||||
personality.hxx \
|
||||
persparam.hxx \
|
||||
placement.hxx \
|
||||
placementtrans.hxx \
|
||||
shadowvolume.hxx
|
||||
@@ -22,6 +23,7 @@ libsgmodel_a_SOURCES = \
|
||||
model.cxx \
|
||||
modellib.cxx \
|
||||
personality.cxx \
|
||||
persparam.cxx \
|
||||
placement.cxx \
|
||||
placementtrans.cxx \
|
||||
shadowvolume.cxx \
|
||||
|
||||
@@ -359,7 +359,9 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root,
|
||||
_use_personality( props->getBoolValue("use-personality",false) ),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_last_time_sec( sim_time_sec ),
|
||||
_condition(0)
|
||||
_condition(0),
|
||||
_factor( props, "factor", 1.0 ),
|
||||
_position_deg( props, "starting-position-deg", 0.0 )
|
||||
{
|
||||
SGPropertyNode_ptr node = props->getChild("condition");
|
||||
if (node != 0)
|
||||
@@ -394,38 +396,6 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root,
|
||||
_center[2] = props->getFloatValue("center/z-m", 0);
|
||||
}
|
||||
sgNormalizeVec3(_axis);
|
||||
|
||||
//_factor(props->getDoubleValue("factor", 1.0)),
|
||||
_factor = 1.0;
|
||||
_factor_min = 1.0;
|
||||
_factor_max = 1.0;
|
||||
SGPropertyNode_ptr factor_n = props->getNode( "factor" );
|
||||
if ( factor_n != 0 ) {
|
||||
SGPropertyNode_ptr rand_n = factor_n->getNode( "random" );
|
||||
if ( rand_n != 0 ) {
|
||||
_factor_min = rand_n->getDoubleValue( "min", 0.0 );
|
||||
_factor_max = rand_n->getDoubleValue( "max", 1.0 );
|
||||
_factor = _factor_min + sg_random() * ( _factor_max - _factor_min );
|
||||
} else {
|
||||
_factor = _factor_min = _factor_max = props->getDoubleValue("factor", 1.0);
|
||||
}
|
||||
}
|
||||
//_position_deg(props->getDoubleValue("starting-position-deg", 0)),
|
||||
_position_deg = 0.0;
|
||||
_position_deg_min = 0.0;
|
||||
_position_deg_max = 0.0;
|
||||
SGPropertyNode_ptr position_deg_n = props->getNode( "starting-position-deg" );
|
||||
if ( position_deg_n != 0 ) {
|
||||
SGPropertyNode_ptr rand_n = position_deg_n->getNode( "random" );
|
||||
if ( rand_n != 0 ) {
|
||||
_position_deg_min = rand_n->getDoubleValue( "min", 0.0 );
|
||||
_position_deg_max = rand_n->getDoubleValue( "max", 1.0 );
|
||||
_position_deg = _position_deg_min + sg_random() * ( _position_deg_max - _position_deg_min );
|
||||
} else {
|
||||
_position_deg = _position_deg_min = _position_deg_max =
|
||||
props->getDoubleValue("starting-position-deg", 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SGSpinAnimation::~SGSpinAnimation ()
|
||||
@@ -438,17 +408,14 @@ SGSpinAnimation::update()
|
||||
if ( _condition == 0 || _condition->test() ) {
|
||||
double dt;
|
||||
float velocity_rpms;
|
||||
if ( _use_personality ) {
|
||||
if ( _use_personality && current_object ) {
|
||||
SGPersonalityBranch *key = current_object;
|
||||
if ( !key->getIntValue( this, INIT_SPIN ) ) {
|
||||
double v = _factor_min + sg_random() * ( _factor_max - _factor_min );
|
||||
key->setDoubleValue( v, this, FACTOR_SPIN );
|
||||
key->setDoubleValue( _factor.shuffle(), this, FACTOR_SPIN );
|
||||
key->setDoubleValue( _position_deg.shuffle(), this, POSITION_DEG_SPIN );
|
||||
|
||||
key->setDoubleValue( sim_time_sec, this, LAST_TIME_SEC_SPIN );
|
||||
key->setIntValue( 1, this, INIT_SPIN );
|
||||
|
||||
v = _position_deg_min + sg_random() * ( _position_deg_max - _position_deg_min );
|
||||
key->setDoubleValue( v, this, POSITION_DEG_SPIN );
|
||||
}
|
||||
|
||||
_factor = key->getDoubleValue( this, FACTOR_SPIN );
|
||||
@@ -545,7 +512,7 @@ SGTimedAnimation::init()
|
||||
int
|
||||
SGTimedAnimation::update()
|
||||
{
|
||||
if ( _use_personality ) {
|
||||
if ( _use_personality && current_object ) {
|
||||
SGPersonalityBranch *key = current_object;
|
||||
if ( !key->getIntValue( this, INIT_TIMED ) ) {
|
||||
double total = 0;
|
||||
@@ -695,11 +662,12 @@ SGRotateAnimation::update()
|
||||
SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root,
|
||||
SGPropertyNode_ptr props )
|
||||
: SGAnimation(props, new ssgTransform),
|
||||
_use_personality( props->getBoolValue("use-personality",false) ),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_table(read_interpolation_table(props)),
|
||||
_prev_value(1.0),
|
||||
_offset(props->getDoubleValue("offset", 0.0)),
|
||||
_factor(props->getDoubleValue("factor", 1.0)),
|
||||
_offset(props,"offset",0.0),
|
||||
_factor(props,"factor",1.0),
|
||||
_has_min(props->hasValue("min")),
|
||||
_min(props->getDoubleValue("min", 0.0)),
|
||||
_has_max(props->hasValue("max")),
|
||||
@@ -717,6 +685,19 @@ SGBlendAnimation::update()
|
||||
{
|
||||
double _blend;
|
||||
|
||||
if ( _use_personality && current_object ) {
|
||||
SGPersonalityBranch *key = current_object;
|
||||
if ( !key->getIntValue( this, INIT_BLEND ) ) {
|
||||
key->setDoubleValue( _factor.shuffle(), this, FACTOR_BLEND );
|
||||
key->setDoubleValue( _offset.shuffle(), this, OFFSET_BLEND );
|
||||
|
||||
key->setIntValue( 1, this, INIT_BLEND );
|
||||
}
|
||||
|
||||
_factor = key->getDoubleValue( this, FACTOR_BLEND );
|
||||
_offset = key->getDoubleValue( this, OFFSET_BLEND );
|
||||
}
|
||||
|
||||
if (_table == 0) {
|
||||
_blend = 1.0 - (_prop->getDoubleValue() * _factor + _offset);
|
||||
|
||||
@@ -744,16 +725,17 @@ SGBlendAnimation::update()
|
||||
SGTranslateAnimation::SGTranslateAnimation( SGPropertyNode *prop_root,
|
||||
SGPropertyNode_ptr props )
|
||||
: SGAnimation(props, new ssgTransform),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_offset_m(props->getDoubleValue("offset-m", 0.0)),
|
||||
_factor(props->getDoubleValue("factor", 1.0)),
|
||||
_use_personality( props->getBoolValue("use-personality",false) ),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_table(read_interpolation_table(props)),
|
||||
_has_min(props->hasValue("min-m")),
|
||||
_min_m(props->getDoubleValue("min-m")),
|
||||
_has_max(props->hasValue("max-m")),
|
||||
_max_m(props->getDoubleValue("max-m")),
|
||||
_position_m(props->getDoubleValue("starting-position-m", 0)),
|
||||
_condition(0)
|
||||
_condition(0),
|
||||
_factor( props, "factor", 1.0 ),
|
||||
_offset_m( props, "offset-m", 0.0 )
|
||||
{
|
||||
SGPropertyNode_ptr node = props->getChild("condition");
|
||||
if (node != 0)
|
||||
@@ -774,6 +756,19 @@ int
|
||||
SGTranslateAnimation::update()
|
||||
{
|
||||
if (_condition == 0 || _condition->test()) {
|
||||
if ( _use_personality && current_object ) {
|
||||
SGPersonalityBranch *key = current_object;
|
||||
if ( !key->getIntValue( this, INIT_TRANSLATE ) ) {
|
||||
key->setDoubleValue( _factor.shuffle(), this, FACTOR_TRANSLATE );
|
||||
key->setDoubleValue( _offset_m.shuffle(), this, OFFSET_TRANSLATE );
|
||||
}
|
||||
|
||||
_factor = key->getDoubleValue( this, FACTOR_TRANSLATE );
|
||||
_offset_m = key->getDoubleValue( this, OFFSET_TRANSLATE );
|
||||
|
||||
key->setIntValue( 1, this, INIT_TRANSLATE );
|
||||
}
|
||||
|
||||
if (_table == 0) {
|
||||
_position_m = (_prop->getDoubleValue() * _factor) + _offset_m;
|
||||
if (_has_min && _position_m < _min_m)
|
||||
@@ -783,6 +778,7 @@ SGTranslateAnimation::update()
|
||||
} else {
|
||||
_position_m = _table->interpolate(_prop->getDoubleValue());
|
||||
}
|
||||
|
||||
set_translation(_matrix, _position_m, _axis);
|
||||
((ssgTransform *)_branch)->setTransform(_matrix);
|
||||
}
|
||||
@@ -798,13 +794,14 @@ SGTranslateAnimation::update()
|
||||
SGScaleAnimation::SGScaleAnimation( SGPropertyNode *prop_root,
|
||||
SGPropertyNode_ptr props )
|
||||
: SGAnimation(props, new ssgTransform),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_x_factor(props->getDoubleValue("x-factor", 1.0)),
|
||||
_y_factor(props->getDoubleValue("y-factor", 1.0)),
|
||||
_z_factor(props->getDoubleValue("z-factor", 1.0)),
|
||||
_x_offset(props->getDoubleValue("x-offset", 1.0)),
|
||||
_y_offset(props->getDoubleValue("y-offset", 1.0)),
|
||||
_z_offset(props->getDoubleValue("z-offset", 1.0)),
|
||||
_use_personality( props->getBoolValue("use-personality",false) ),
|
||||
_prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)),
|
||||
_x_factor(props,"x-factor",1.0),
|
||||
_y_factor(props,"y-factor",1.0),
|
||||
_z_factor(props,"z-factor",1.0),
|
||||
_x_offset(props,"x-offset",1.0),
|
||||
_y_offset(props,"y-offset",1.0),
|
||||
_z_offset(props,"z-offset",1.0),
|
||||
_table(read_interpolation_table(props)),
|
||||
_has_min_x(props->hasValue("x-min")),
|
||||
_has_min_y(props->hasValue("y-min")),
|
||||
@@ -829,6 +826,27 @@ SGScaleAnimation::~SGScaleAnimation ()
|
||||
int
|
||||
SGScaleAnimation::update()
|
||||
{
|
||||
if ( _use_personality && current_object ) {
|
||||
SGPersonalityBranch *key = current_object;
|
||||
if ( !key->getIntValue( this, INIT_SCALE ) ) {
|
||||
key->setDoubleValue( _x_factor.shuffle(), this, X_FACTOR_SCALE );
|
||||
key->setDoubleValue( _x_offset.shuffle(), this, X_OFFSET_SCALE );
|
||||
key->setDoubleValue( _y_factor.shuffle(), this, Y_FACTOR_SCALE );
|
||||
key->setDoubleValue( _y_offset.shuffle(), this, Y_OFFSET_SCALE );
|
||||
key->setDoubleValue( _z_factor.shuffle(), this, Z_FACTOR_SCALE );
|
||||
key->setDoubleValue( _z_offset.shuffle(), this, Z_OFFSET_SCALE );
|
||||
|
||||
key->setIntValue( 1, this, INIT_SCALE );
|
||||
}
|
||||
|
||||
_x_factor = key->getDoubleValue( this, X_FACTOR_SCALE );
|
||||
_x_offset = key->getDoubleValue( this, X_OFFSET_SCALE );
|
||||
_y_factor = key->getDoubleValue( this, Y_FACTOR_SCALE );
|
||||
_y_offset = key->getDoubleValue( this, Y_OFFSET_SCALE );
|
||||
_z_factor = key->getDoubleValue( this, Z_FACTOR_SCALE );
|
||||
_z_offset = key->getDoubleValue( this, Z_OFFSET_SCALE );
|
||||
}
|
||||
|
||||
if (_table == 0) {
|
||||
_x_scale = _prop->getDoubleValue() * _x_factor + _x_offset;
|
||||
if (_has_min_x && _x_scale < _min_x)
|
||||
@@ -880,8 +898,13 @@ SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root,
|
||||
_min_deg(props->getDoubleValue("min-deg")),
|
||||
_has_max(props->hasValue("max-deg")),
|
||||
_max_deg(props->getDoubleValue("max-deg")),
|
||||
_position_deg(props->getDoubleValue("starting-position-deg", 0))
|
||||
_position_deg(props->getDoubleValue("starting-position-deg", 0)),
|
||||
_condition(0)
|
||||
{
|
||||
SGPropertyNode *node = props->getChild("condition");
|
||||
if (node != 0)
|
||||
_condition = sgReadCondition(prop_root, node);
|
||||
|
||||
_center[0] = props->getFloatValue("center/x", 0);
|
||||
_center[1] = props->getFloatValue("center/y", 0);
|
||||
_center[2] = props->getFloatValue("center/z", 0);
|
||||
@@ -899,6 +922,9 @@ SGTexRotateAnimation::~SGTexRotateAnimation ()
|
||||
int
|
||||
SGTexRotateAnimation::update()
|
||||
{
|
||||
if (_condition && !_condition->test())
|
||||
return 1;
|
||||
|
||||
if (_table == 0) {
|
||||
_position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
|
||||
if (_has_min && _position_deg < _min_deg)
|
||||
@@ -931,8 +957,13 @@ SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root,
|
||||
_min(props->getDoubleValue("min")),
|
||||
_has_max(props->hasValue("max")),
|
||||
_max(props->getDoubleValue("max")),
|
||||
_position(props->getDoubleValue("starting-position", 0))
|
||||
_position(props->getDoubleValue("starting-position", 0)),
|
||||
_condition(0)
|
||||
{
|
||||
SGPropertyNode *node = props->getChild("condition");
|
||||
if (node != 0)
|
||||
_condition = sgReadCondition(prop_root, node);
|
||||
|
||||
_axis[0] = props->getFloatValue("axis/x", 0);
|
||||
_axis[1] = props->getFloatValue("axis/y", 0);
|
||||
_axis[2] = props->getFloatValue("axis/z", 0);
|
||||
@@ -947,6 +978,9 @@ SGTexTranslateAnimation::~SGTexTranslateAnimation ()
|
||||
int
|
||||
SGTexTranslateAnimation::update()
|
||||
{
|
||||
if (_condition && !_condition->test())
|
||||
return 1;
|
||||
|
||||
if (_table == 0) {
|
||||
_position = (apply_mods(_prop->getDoubleValue(), _step, _scroll) + _offset) * _factor;
|
||||
if (_has_min && _position < _min)
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
@@ -24,6 +21,11 @@ SG_USING_STD(map);
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <simgear/scene/model/persparam.hxx>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
|
||||
|
||||
// Don't pull in the headers, since we don't need them here.
|
||||
class SGInterpTable;
|
||||
@@ -51,10 +53,14 @@ class SGPersonalityBranch;
|
||||
class SGAnimation : public ssgBase
|
||||
{
|
||||
public:
|
||||
enum PersonalityVar { INIT_SPIN, LAST_TIME_SEC_SPIN, FACTOR_SPIN,
|
||||
POSITION_DEG_SPIN, INIT_TIMED, LAST_TIME_SEC_TIMED,
|
||||
TOTAL_DURATION_SEC_TIMED, BRANCH_DURATION_SEC_TIMED,
|
||||
STEP_TIMED };
|
||||
enum PersonalityVar { INIT_SPIN, LAST_TIME_SEC_SPIN, FACTOR_SPIN,
|
||||
POSITION_DEG_SPIN,
|
||||
INIT_TIMED, LAST_TIME_SEC_TIMED, TOTAL_DURATION_SEC_TIMED,
|
||||
BRANCH_DURATION_SEC_TIMED, STEP_TIMED,
|
||||
INIT_TRANSLATE, FACTOR_TRANSLATE, OFFSET_TRANSLATE,
|
||||
INIT_BLEND, FACTOR_BLEND, OFFSET_BLEND,
|
||||
INIT_SCALE, X_FACTOR_SCALE, Y_FACTOR_SCALE, Z_FACTOR_SCALE,
|
||||
X_OFFSET_SCALE, Y_OFFSET_SCALE, Z_OFFSET_SCALE };
|
||||
|
||||
SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch);
|
||||
|
||||
@@ -178,12 +184,8 @@ public:
|
||||
private:
|
||||
bool _use_personality;
|
||||
SGPropertyNode_ptr _prop;
|
||||
double _factor;
|
||||
double _factor_min;
|
||||
double _factor_max;
|
||||
double _position_deg;
|
||||
double _position_deg_min;
|
||||
double _position_deg_max;
|
||||
SGPersonalityParameter<double> _factor;
|
||||
SGPersonalityParameter<double> _position_deg;
|
||||
double _last_time_sec;
|
||||
sgMat4 _matrix;
|
||||
sgVec3 _center;
|
||||
@@ -257,9 +259,10 @@ public:
|
||||
virtual ~SGTranslateAnimation ();
|
||||
virtual int update();
|
||||
private:
|
||||
bool _use_personality;
|
||||
SGPropertyNode_ptr _prop;
|
||||
double _offset_m;
|
||||
double _factor;
|
||||
SGPersonalityParameter<double> _offset_m;
|
||||
SGPersonalityParameter<double> _factor;
|
||||
SGInterpTable * _table;
|
||||
bool _has_min;
|
||||
double _min_m;
|
||||
@@ -282,11 +285,12 @@ public:
|
||||
virtual ~SGBlendAnimation ();
|
||||
virtual int update();
|
||||
private:
|
||||
bool _use_personality;
|
||||
SGPropertyNode_ptr _prop;
|
||||
SGInterpTable * _table;
|
||||
double _prev_value;
|
||||
double _offset;
|
||||
double _factor;
|
||||
SGPersonalityParameter<double> _offset;
|
||||
SGPersonalityParameter<double> _factor;
|
||||
bool _has_min;
|
||||
double _min;
|
||||
bool _has_max;
|
||||
@@ -304,13 +308,14 @@ public:
|
||||
virtual ~SGScaleAnimation ();
|
||||
virtual int update();
|
||||
private:
|
||||
bool _use_personality;
|
||||
SGPropertyNode_ptr _prop;
|
||||
double _x_factor;
|
||||
double _y_factor;
|
||||
double _z_factor;
|
||||
double _x_offset;
|
||||
double _y_offset;
|
||||
double _z_offset;
|
||||
SGPersonalityParameter<double> _x_factor;
|
||||
SGPersonalityParameter<double> _y_factor;
|
||||
SGPersonalityParameter<double> _z_factor;
|
||||
SGPersonalityParameter<double> _x_offset;
|
||||
SGPersonalityParameter<double> _y_offset;
|
||||
SGPersonalityParameter<double> _z_offset;
|
||||
SGInterpTable * _table;
|
||||
bool _has_min_x;
|
||||
bool _has_min_y;
|
||||
@@ -354,6 +359,7 @@ private:
|
||||
sgMat4 _matrix;
|
||||
sgVec3 _center;
|
||||
sgVec3 _axis;
|
||||
SGCondition * _condition;
|
||||
};
|
||||
|
||||
|
||||
@@ -381,6 +387,7 @@ private:
|
||||
double _position;
|
||||
sgMat4 _matrix;
|
||||
sgVec3 _axis;
|
||||
SGCondition * _condition;
|
||||
};
|
||||
|
||||
|
||||
@@ -508,7 +515,7 @@ private:
|
||||
};
|
||||
SGCondition *_condition;
|
||||
bool _last_condition;
|
||||
SGPropertyNode *_prop_root;
|
||||
SGPropertyNode_ptr _prop_root;
|
||||
string _prop_base;
|
||||
SGPath _texture_base;
|
||||
SGPath _texture;
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#include "plib/ssg.h"
|
||||
#include "custtrans.hxx"
|
||||
void _ssgPushMatrix ( sgMat4 m );
|
||||
void _ssgPopMatrix ();
|
||||
void _ssgReadInt ( FILE *fd, int *var );
|
||||
void _ssgWriteInt ( FILE *fd, const int var );
|
||||
extern sgMat4 _ssgOpenGLAxisSwapMatrix;
|
||||
|
||||
void SGCustomTransform::copy_from( SGCustomTransform *src, int clone_flags )
|
||||
{
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef _SG_CUSTOM_TRANSFORM_HXX
|
||||
#define _SG_CUSTOM_TRANSFORM_HXX 1
|
||||
|
||||
#include "plib/ssg.h"
|
||||
|
||||
class SGCustomTransform : public ssgBranch
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -83,6 +83,8 @@ public:
|
||||
|
||||
//! Return the position relative to the given scenery center.
|
||||
virtual float * get_view_pos( const Point3D& scenery_center );
|
||||
float * get_view_pos( const SGVec3d& sc )
|
||||
{ return get_view_pos(Point3D(sc[0], sc[1], sc[2])); }
|
||||
|
||||
// Get world up vector
|
||||
virtual float *get_world_up()
|
||||
@@ -111,6 +113,9 @@ public:
|
||||
recalcAbsolutePosition();
|
||||
return UP;
|
||||
}
|
||||
const sgVec4 *getUpMatrix( const SGVec3d& sc )
|
||||
{ return getUpMatrix(Point3D(sc[0], sc[1], sc[2])); }
|
||||
|
||||
virtual const sgVec4 *getCachedUpMatrix() { return UP; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string.h> // for strcmp()
|
||||
|
||||
#include <vector>
|
||||
@@ -21,6 +19,7 @@
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/props/condition.hxx>
|
||||
|
||||
#include "animation.hxx"
|
||||
#include "model.hxx"
|
||||
@@ -66,6 +65,23 @@ restore_callback (ssgEntity * entity, int mask)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback and userData class for conditional rendering.
|
||||
*/
|
||||
class SGConditionalRender : public ssgBase {
|
||||
public:
|
||||
SGConditionalRender(SGCondition *c) : _condition(c) {}
|
||||
bool test() { return _condition->test(); }
|
||||
private:
|
||||
SGCondition *_condition;
|
||||
};
|
||||
|
||||
static int
|
||||
model_condition_callback (ssgEntity * entity, int mask)
|
||||
{
|
||||
return ((SGConditionalRender *)entity->getUserData())->test();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locate a named SSG node in a branch.
|
||||
@@ -236,6 +252,13 @@ static void makeDList( ssgBranch *b, const set<ssgBranch *> &ignore )
|
||||
}
|
||||
}
|
||||
|
||||
class SGLoaderOptions : public ssgLoaderOptions {
|
||||
public:
|
||||
SGLoaderOptions() { ssgSetCurrentOptions( this ); } // Install our own loader options at startup
|
||||
void endLoad() {} // Avoid clearing the texture cache after every model load
|
||||
};
|
||||
|
||||
static SGLoaderOptions loaderOptions;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -328,6 +351,13 @@ sgLoad3DModel( const string &fg_root, const string &path,
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Failed to load submodel: " << t.getFormattedMessage());
|
||||
throw;
|
||||
}
|
||||
|
||||
SGPropertyNode *cond = node->getNode("condition", false);
|
||||
if (cond) {
|
||||
align->setUserData(new SGConditionalRender(sgReadCondition(prop_root, cond)));
|
||||
align->setTravCallback(SSG_CALLBACK_PRETRAV, model_condition_callback);
|
||||
}
|
||||
|
||||
align->addKid(kid);
|
||||
align->setName(node->getStringValue("name", ""));
|
||||
model->addKid(align);
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
|
||||
@@ -61,22 +61,6 @@ SGModelLib::flush1()
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
personality_pretrav_callback(ssgEntity * entity, int mask)
|
||||
{
|
||||
((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
|
||||
SGAnimation::current_object = (SGPersonalityBranch *)entity;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
personality_posttrav_callback(ssgEntity * entity, int mask)
|
||||
{
|
||||
SGAnimation::current_object = ((SGPersonalityBranch *)entity)->_old_current;
|
||||
((SGPersonalityBranch *)entity)->_old_current = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssgEntity *
|
||||
SGModelLib::load_model( const string &fg_root,
|
||||
const string &path,
|
||||
@@ -86,8 +70,6 @@ SGModelLib::load_model( const string &fg_root,
|
||||
SGModelData *data )
|
||||
{
|
||||
ssgBranch *personality_branch = new SGPersonalityBranch;
|
||||
personality_branch->setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
|
||||
personality_branch->setTravCallback(SSG_CALLBACK_POSTTRAV, personality_posttrav_callback);
|
||||
|
||||
// FIXME: normalize path to
|
||||
// avoid duplicates.
|
||||
|
||||
@@ -2,9 +2,34 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "personality.hxx"
|
||||
#include "animation.hxx"
|
||||
|
||||
static int
|
||||
personality_pretrav_callback(ssgEntity * entity, int mask)
|
||||
{
|
||||
((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
|
||||
SGAnimation::current_object = (SGPersonalityBranch *)entity;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
personality_posttrav_callback(ssgEntity * entity, int mask)
|
||||
{
|
||||
SGAnimation::current_object = ((SGPersonalityBranch *)entity)->_old_current;
|
||||
((SGPersonalityBranch *)entity)->_old_current = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SGPersonalityBranch::SGPersonalityBranch()
|
||||
{
|
||||
setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
|
||||
setTravCallback(SSG_CALLBACK_POSTTRAV, personality_posttrav_callback);
|
||||
}
|
||||
|
||||
void SGPersonalityBranch::setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num )
|
||||
{
|
||||
|
||||
@@ -5,16 +5,18 @@
|
||||
#ifndef _SG_PERSONALITY_HXX
|
||||
#define _SG_PERSONALITY_HXX 1
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
SG_USING_STD(map);
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
class SGAnimation;
|
||||
|
||||
class SGPersonalityBranch : public ssgBranch {
|
||||
public:
|
||||
SGPersonalityBranch();
|
||||
void setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num = 0 );
|
||||
void setIntValue( int value, SGAnimation *anim, int var_id, int var_num = 0 );
|
||||
double getDoubleValue( SGAnimation *anim, int var_id, int var_num = 0 ) const;
|
||||
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
#include "persparam.hxx"
|
||||
|
||||
template <> double
|
||||
SGPersonalityParameter<double>::getNodeValue( SGPropertyNode *props,
|
||||
const char *name,
|
||||
double defval ) const
|
||||
{
|
||||
return props->getDoubleValue( name, defval );
|
||||
}
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SG_PERSPARAM_HXX
|
||||
#define _SG_PERSPARAM_HXX 1
|
||||
|
||||
#include <simgear/math/sg_random.h>
|
||||
|
||||
|
||||
template <class T>
|
||||
class SGPersonalityParameter {
|
||||
public:
|
||||
SGPersonalityParameter( SGPropertyNode *props, const char *name, T defval )
|
||||
: _var( defval ), _min( defval ), _max( defval ) {
|
||||
SGPropertyNode_ptr node = props->getNode( name );
|
||||
if ( node != 0 ) {
|
||||
SGPropertyNode_ptr rand_n = node->getNode( "random" );
|
||||
if ( rand_n != 0 ) {
|
||||
_min = getNodeValue( rand_n, "min", (T)0 );
|
||||
_max = getNodeValue( rand_n, "max", (T)1 );
|
||||
shuffle();
|
||||
} else {
|
||||
_var = _min = _max = getNodeValue( props, name, defval );
|
||||
}
|
||||
}
|
||||
}
|
||||
SGPersonalityParameter<T> &operator=( T v ) { _var = v; return *this; }
|
||||
SGPersonalityParameter<T> &operator+=( T v ) { _var += v; return *this; }
|
||||
SGPersonalityParameter<T> &operator-=( T v ) { _var -= v; return *this; }
|
||||
T shuffle() { return ( _var = _min + sg_random() * ( _max - _min ) ); }
|
||||
T value() const { return _var; }
|
||||
T getNodeValue( SGPropertyNode *props, const char *name, T defval ) const;
|
||||
operator T() const { return _var; }
|
||||
|
||||
private:
|
||||
T _var;
|
||||
T _min;
|
||||
T _max;
|
||||
};
|
||||
|
||||
template <> double
|
||||
SGPersonalityParameter<double>::getNodeValue( SGPropertyNode *props,
|
||||
const char *name,
|
||||
double defval ) const;
|
||||
|
||||
#endif // _SG_PERSPARAM_HXX
|
||||
|
||||
@@ -41,6 +41,7 @@ SGModelPlacement::SGModelPlacement ()
|
||||
|
||||
SGModelPlacement::~SGModelPlacement ()
|
||||
{
|
||||
delete _location;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -102,6 +103,14 @@ SGModelPlacement::setPosition (double lon_deg, double lat_deg, double elev_ft)
|
||||
_elev_ft = elev_ft;
|
||||
}
|
||||
|
||||
void
|
||||
SGModelPlacement::setPosition(const SGGeod& position)
|
||||
{
|
||||
_lon_deg = position.getLongitudeDeg();
|
||||
_lat_deg = position.getLatitudeDeg();
|
||||
_elev_ft = position.getElevationFt();
|
||||
}
|
||||
|
||||
void
|
||||
SGModelPlacement::setRollDeg (double roll_deg)
|
||||
{
|
||||
@@ -129,4 +138,10 @@ SGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
|
||||
_heading_deg = heading_deg;
|
||||
}
|
||||
|
||||
void
|
||||
SGModelPlacement::setOrientation (const SGQuatd& orientation)
|
||||
{
|
||||
orientation.getEulerDeg(_heading_deg, _pitch_deg, _roll_deg);
|
||||
}
|
||||
|
||||
// end of model.cxx
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
virtual void setLatitudeDeg (double lat_deg);
|
||||
virtual void setElevationFt (double elev_ft);
|
||||
virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
|
||||
void setPosition(const SGGeod& position);
|
||||
|
||||
virtual double getRollDeg () const { return _roll_deg; }
|
||||
virtual double getPitchDeg () const { return _pitch_deg; }
|
||||
@@ -76,6 +77,7 @@ public:
|
||||
virtual void setHeadingDeg (double heading_deg);
|
||||
virtual void setOrientation (double roll_deg, double pitch_deg,
|
||||
double heading_deg);
|
||||
void setOrientation(const SGQuatd& orientation);
|
||||
|
||||
ssgPlacementTransform * getTransform(void)
|
||||
{ return _position; }
|
||||
|
||||
@@ -114,6 +114,9 @@ static int null_shader_callback( ssgEntity *e ) {
|
||||
}
|
||||
|
||||
static int heat_haze_shader_callback( ssgEntity *e ) {
|
||||
if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
|
||||
return true;
|
||||
|
||||
GLuint dlist = 0;
|
||||
ssgLeaf *leaf = (ssgLeaf *) e;
|
||||
#ifdef _SSG_USE_DLIST
|
||||
@@ -312,6 +315,9 @@ static int heat_haze_shader_callback( ssgEntity *e ) {
|
||||
}
|
||||
|
||||
static int fresnel_shader_callback( ssgEntity *e ) {
|
||||
if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
|
||||
return true;
|
||||
|
||||
GLuint dlist = 0;
|
||||
ssgLeaf *leaf = (ssgLeaf *) e;
|
||||
#ifdef _SSG_USE_DLIST
|
||||
@@ -385,6 +391,9 @@ static int fresnel_shader_callback( ssgEntity *e ) {
|
||||
|
||||
|
||||
static int chrome_shader_callback( ssgEntity *e ) {
|
||||
if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() )
|
||||
return true;
|
||||
|
||||
GLuint dlist = 0;
|
||||
ssgLeaf *leaf = (ssgLeaf *) e;
|
||||
#ifdef _SSG_USE_DLIST
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/screen/extensions.hxx>
|
||||
#include <simgear/scene/model/animation.hxx>
|
||||
|
||||
@@ -23,9 +23,13 @@
|
||||
#ifndef _SHADOWVOLUME_HXX
|
||||
#define _SHADOWVOLUME_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/structure/ssgSharedPtr.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
#include <plib/ssg.h>
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ SGBbCache::SGBbCache(void) :
|
||||
}
|
||||
|
||||
SGBbCache::~SGBbCache(void) {
|
||||
if(rt)
|
||||
delete rt;
|
||||
delete rt;
|
||||
freeTextureMemory();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/screen/extensions.hxx>
|
||||
#include <simgear/screen/texture.hxx>
|
||||
#include <simgear/structure/ssgSharedPtr.hxx>
|
||||
@@ -57,6 +56,9 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__CYGWIN__)
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
static ssgSharedPtr<ssgStateSelector> layer_states[SGCloudLayer::SG_MAX_CLOUD_COVERAGES];
|
||||
static bool state_initialized = false;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define _SG_CLOUD_HXX_
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ SG_USING_STD(vector);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (__CYGWIN__)
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
extern SGSky *thesky;
|
||||
|
||||
static list_of_culledCloud inViewClouds;
|
||||
|
||||
+314
-104
@@ -30,9 +30,6 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
@@ -44,30 +41,29 @@
|
||||
#endif
|
||||
|
||||
#include <simgear/screen/colors.hxx>
|
||||
|
||||
#include "sphere.hxx"
|
||||
#include "oursun.hxx"
|
||||
|
||||
|
||||
static double sun_exp2_punch_through;
|
||||
|
||||
// Set up sun rendering call backs
|
||||
static int sgSunOrbPreDraw( ssgEntity *e ) {
|
||||
static int sgSunPreDraw( ssgEntity *e ) {
|
||||
/* cout << endl << "Sun orb pre draw" << endl << "----------------"
|
||||
<< endl << endl; */
|
||||
|
||||
ssgLeaf *f = (ssgLeaf *)e;
|
||||
if ( f -> hasState () ) f->getState()->apply() ;
|
||||
|
||||
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
|
||||
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
|
||||
// cout << "push error = " << glGetError() << endl;
|
||||
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_FOG );
|
||||
|
||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sgSunOrbPostDraw( ssgEntity *e ) {
|
||||
static int sgSunPostDraw( ssgEntity *e ) {
|
||||
/* cout << endl << "Sun orb post draw" << endl << "----------------"
|
||||
<< endl << endl; */
|
||||
|
||||
@@ -229,93 +225,190 @@ void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// initialize the sun object and connect it into our scene graph root
|
||||
ssgBranch * SGSun::build( SGPath path, double sun_size ) {
|
||||
ssgBranch * SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node ) {
|
||||
|
||||
// set up the orb state
|
||||
orb_state = new ssgSimpleState();
|
||||
orb_state->setShadeModel( GL_SMOOTH );
|
||||
orb_state->disable( GL_LIGHTING );
|
||||
// orb_state->enable( GL_LIGHTING );
|
||||
orb_state->disable( GL_CULL_FACE );
|
||||
orb_state->disable( GL_TEXTURE_2D );
|
||||
orb_state->enable( GL_COLOR_MATERIAL );
|
||||
orb_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
||||
orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
||||
orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
||||
orb_state->disable( GL_BLEND );
|
||||
orb_state->disable( GL_ALPHA_TEST );
|
||||
env_node = property_tree_Node;
|
||||
|
||||
SGPath ihalopath = path, ohalopath = path;
|
||||
|
||||
cl = new ssgColourArray( 1 );
|
||||
sgVec4 color;
|
||||
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
|
||||
cl->add( color );
|
||||
|
||||
ssgBranch *orb = ssgMakeSphere( orb_state, cl, sun_size, 10, 10,
|
||||
sgSunOrbPreDraw, sgSunOrbPostDraw );
|
||||
sun_cl = new ssgColourArray( 1 );
|
||||
sun_cl->add( color );
|
||||
|
||||
ihalo_cl = new ssgColourArray( 1 );
|
||||
ihalo_cl->add( color );
|
||||
|
||||
ohalo_cl = new ssgColourArray( 1 );
|
||||
ohalo_cl->add( color );
|
||||
|
||||
// force a repaint of the sun colors with arbitrary defaults
|
||||
repaint( 0.0, 1.0 );
|
||||
|
||||
|
||||
// set up the sun-state
|
||||
path.append( "sun.rgba" );
|
||||
sun_state = new ssgSimpleState();
|
||||
sun_state->setShadeModel( GL_SMOOTH );
|
||||
sun_state->disable( GL_LIGHTING );
|
||||
sun_state->disable( GL_CULL_FACE );
|
||||
sun_state->setTexture( (char *)path.c_str() );
|
||||
sun_state->enable( GL_TEXTURE_2D );
|
||||
sun_state->enable( GL_COLOR_MATERIAL );
|
||||
sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
||||
sun_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
||||
sun_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
||||
sun_state->enable( GL_BLEND );
|
||||
sun_state->setAlphaClamp( 0.01 );
|
||||
sun_state->enable( GL_ALPHA_TEST );
|
||||
|
||||
// Build ssg structure
|
||||
|
||||
sgVec3 va;
|
||||
sun_vl = new ssgVertexArray;
|
||||
sgSetVec3( va, -sun_size, 0.0, -sun_size );
|
||||
sun_vl->add( va );
|
||||
sgSetVec3( va, sun_size, 0.0, -sun_size );
|
||||
sun_vl->add( va );
|
||||
sgSetVec3( va, -sun_size, 0.0, sun_size );
|
||||
sun_vl->add( va );
|
||||
sgSetVec3( va, sun_size, 0.0, sun_size );
|
||||
sun_vl->add( va );
|
||||
|
||||
sgVec2 vb;
|
||||
sun_tl = new ssgTexCoordArray;
|
||||
sgSetVec2( vb, 0.0f, 0.0f );
|
||||
sun_tl->add( vb );
|
||||
sgSetVec2( vb, 1.0, 0.0 );
|
||||
sun_tl->add( vb );
|
||||
sgSetVec2( vb, 0.0, 1.0 );
|
||||
sun_tl->add( vb );
|
||||
sgSetVec2( vb, 1.0, 1.0 );
|
||||
sun_tl->add( vb );
|
||||
|
||||
|
||||
ssgLeaf *sun =
|
||||
new ssgVtxTable ( GL_TRIANGLE_STRIP, sun_vl, NULL, sun_tl, sun_cl );
|
||||
sun->setState( sun_state );
|
||||
|
||||
sun->setCallback( SSG_CALLBACK_PREDRAW, sgSunPreDraw );
|
||||
sun->setCallback( SSG_CALLBACK_POSTDRAW, sgSunPostDraw );
|
||||
|
||||
|
||||
|
||||
// build the halo
|
||||
// sun_texbuf = new GLubyte[64*64*3];
|
||||
// sun_texid = makeHalo( sun_texbuf, 64 );
|
||||
// my_glWritePPMFile("sunhalo.ppm", sun_texbuf, 64, 64, RGB);
|
||||
|
||||
// set up the halo state
|
||||
path.append( "halo.rgba" );
|
||||
halo_state = new ssgSimpleState();
|
||||
halo_state->setTexture( (char *)path.c_str() );
|
||||
halo_state->enable( GL_TEXTURE_2D );
|
||||
halo_state->disable( GL_LIGHTING );
|
||||
// halo_state->enable( GL_LIGHTING );
|
||||
halo_state->setShadeModel( GL_SMOOTH );
|
||||
halo_state->disable( GL_CULL_FACE );
|
||||
halo_state->enable( GL_COLOR_MATERIAL );
|
||||
halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
||||
halo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
||||
halo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
||||
halo_state->enable( GL_ALPHA_TEST );
|
||||
halo_state->setAlphaClamp(0.01);
|
||||
halo_state->enable ( GL_BLEND ) ;
|
||||
// set up the inner-halo state
|
||||
|
||||
ihalopath.append( "inner_halo.rgba" );
|
||||
|
||||
ihalo_state = new ssgSimpleState();
|
||||
ihalo_state->setTexture( (char *)ihalopath.c_str() );
|
||||
ihalo_state->enable( GL_TEXTURE_2D );
|
||||
ihalo_state->disable( GL_LIGHTING );
|
||||
ihalo_state->setShadeModel( GL_SMOOTH );
|
||||
ihalo_state->disable( GL_CULL_FACE );
|
||||
ihalo_state->enable( GL_COLOR_MATERIAL );
|
||||
ihalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
||||
ihalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
||||
ihalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
||||
ihalo_state->enable( GL_ALPHA_TEST );
|
||||
ihalo_state->setAlphaClamp(0.01);
|
||||
ihalo_state->enable ( GL_BLEND ) ;
|
||||
|
||||
// Build ssg structure
|
||||
double size = sun_size * 10.0;
|
||||
sgVec3 v3;
|
||||
halo_vl = new ssgVertexArray;
|
||||
sgSetVec3( v3, -size, 0.0, -size );
|
||||
halo_vl->add( v3 );
|
||||
sgSetVec3( v3, size, 0.0, -size );
|
||||
halo_vl->add( v3 );
|
||||
sgSetVec3( v3, -size, 0.0, size );
|
||||
halo_vl->add( v3 );
|
||||
sgSetVec3( v3, size, 0.0, size );
|
||||
halo_vl->add( v3 );
|
||||
double ihalo_size = sun_size * 2.0;
|
||||
sgVec3 vc;
|
||||
ihalo_vl = new ssgVertexArray;
|
||||
sgSetVec3( vc, -ihalo_size, 0.0, -ihalo_size );
|
||||
ihalo_vl->add( vc );
|
||||
sgSetVec3( vc, ihalo_size, 0.0, -ihalo_size );
|
||||
ihalo_vl->add( vc );
|
||||
sgSetVec3( vc, -ihalo_size, 0.0, ihalo_size );
|
||||
ihalo_vl->add( vc );
|
||||
sgSetVec3( vc, ihalo_size, 0.0, ihalo_size );
|
||||
ihalo_vl->add( vc );
|
||||
|
||||
sgVec2 v2;
|
||||
halo_tl = new ssgTexCoordArray;
|
||||
sgSetVec2( v2, 0.0f, 0.0f );
|
||||
halo_tl->add( v2 );
|
||||
sgSetVec2( v2, 1.0, 0.0 );
|
||||
halo_tl->add( v2 );
|
||||
sgSetVec2( v2, 0.0, 1.0 );
|
||||
halo_tl->add( v2 );
|
||||
sgSetVec2( v2, 1.0, 1.0 );
|
||||
halo_tl->add( v2 );
|
||||
sgVec2 vd;
|
||||
ihalo_tl = new ssgTexCoordArray;
|
||||
sgSetVec2( vd, 0.0f, 0.0f );
|
||||
ihalo_tl->add( vd );
|
||||
sgSetVec2( vd, 1.0, 0.0 );
|
||||
ihalo_tl->add( vd );
|
||||
sgSetVec2( vd, 0.0, 1.0 );
|
||||
ihalo_tl->add( vd );
|
||||
sgSetVec2( vd, 1.0, 1.0 );
|
||||
ihalo_tl->add( vd );
|
||||
|
||||
ssgLeaf *ihalo =
|
||||
new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl );
|
||||
ihalo->setState( ihalo_state );
|
||||
|
||||
|
||||
// set up the outer halo state
|
||||
|
||||
ohalopath.append( "outer_halo.rgba" );
|
||||
|
||||
ohalo_state = new ssgSimpleState();
|
||||
ohalo_state->setTexture( (char *)ohalopath.c_str() );
|
||||
ohalo_state->enable( GL_TEXTURE_2D );
|
||||
ohalo_state->disable( GL_LIGHTING );
|
||||
ohalo_state->setShadeModel( GL_SMOOTH );
|
||||
ohalo_state->disable( GL_CULL_FACE );
|
||||
ohalo_state->enable( GL_COLOR_MATERIAL );
|
||||
ohalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
||||
ohalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
||||
ohalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
||||
ohalo_state->enable( GL_ALPHA_TEST );
|
||||
ohalo_state->setAlphaClamp(0.01);
|
||||
ohalo_state->enable ( GL_BLEND ) ;
|
||||
|
||||
// Build ssg structure
|
||||
double ohalo_size = sun_size * 7.0;
|
||||
sgVec3 ve;
|
||||
ohalo_vl = new ssgVertexArray;
|
||||
sgSetVec3( ve, -ohalo_size, 0.0, -ohalo_size );
|
||||
ohalo_vl->add( ve );
|
||||
sgSetVec3( ve, ohalo_size, 0.0, -ohalo_size );
|
||||
ohalo_vl->add( ve );
|
||||
sgSetVec3( ve, -ohalo_size, 0.0, ohalo_size );
|
||||
ohalo_vl->add( ve );
|
||||
sgSetVec3( ve, ohalo_size, 0.0, ohalo_size );
|
||||
ohalo_vl->add( ve );
|
||||
|
||||
sgVec2 vf;
|
||||
ohalo_tl = new ssgTexCoordArray;
|
||||
sgSetVec2( vf, 0.0f, 0.0f );
|
||||
ohalo_tl->add( vf );
|
||||
sgSetVec2( vf, 1.0, 0.0 );
|
||||
ohalo_tl->add( vf );
|
||||
sgSetVec2( vf, 0.0, 1.0 );
|
||||
ohalo_tl->add( vf );
|
||||
sgSetVec2( vf, 1.0, 1.0 );
|
||||
ohalo_tl->add( vf );
|
||||
|
||||
ssgLeaf *ohalo =
|
||||
new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl );
|
||||
ohalo->setState( ohalo_state );
|
||||
|
||||
ssgLeaf *halo =
|
||||
new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl );
|
||||
halo->setState( halo_state );
|
||||
|
||||
// build the ssg scene graph sub tree for the sky and connected
|
||||
// into the provide scene graph branch
|
||||
sun_transform = new ssgTransform;
|
||||
|
||||
halo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
|
||||
halo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
|
||||
sun_transform->addKid( halo );
|
||||
sun_transform->addKid( orb );
|
||||
ihalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
|
||||
ihalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
|
||||
ohalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
|
||||
ohalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
|
||||
|
||||
sun_transform->addKid( ohalo );
|
||||
sun_transform->addKid( ihalo );
|
||||
sun_transform->addKid( sun );
|
||||
|
||||
#ifdef FG_TEST_CHEESY_LENS_FLARE
|
||||
// cheesy lens flair
|
||||
@@ -332,45 +425,129 @@ ssgBranch * SGSun::build( SGPath path, double sun_size ) {
|
||||
// 90 degrees = sun rise/set
|
||||
// 180 degrees = darkest midnight
|
||||
bool SGSun::repaint( double sun_angle, double new_visibility ) {
|
||||
if ( visibility != new_visibility ) {
|
||||
visibility = new_visibility;
|
||||
|
||||
if ( visibility != new_visibility ) {
|
||||
visibility = new_visibility;
|
||||
|
||||
static double sqrt_m_log01 = sqrt( -log( 0.01 ) );
|
||||
sun_exp2_punch_through = sqrt_m_log01 / (visibility * 15);
|
||||
}
|
||||
static const double sqrt_m_log01 = sqrt( -log( 0.01 ) );
|
||||
sun_exp2_punch_through = sqrt_m_log01 / ( visibility * 15 );
|
||||
}
|
||||
|
||||
if (prev_sun_angle != sun_angle) {
|
||||
prev_sun_angle = sun_angle;
|
||||
if ( prev_sun_angle != sun_angle ) {
|
||||
prev_sun_angle = sun_angle;
|
||||
|
||||
double nv = (new_visibility > 5000.0) ? new_visibility : 5000.0;
|
||||
double vis_factor = 10000.0 / (nv - 5000.0);
|
||||
if ( vis_factor < 0.25 ) {
|
||||
vis_factor = 0.25;
|
||||
} else if ( vis_factor > 1.0) {
|
||||
vis_factor = 1.0;
|
||||
}
|
||||
// determine how much aerosols are in the air (rough guess)
|
||||
double aerosol_factor;
|
||||
if ( visibility < 100 ){
|
||||
aerosol_factor = 8000;
|
||||
}
|
||||
else {
|
||||
aerosol_factor = 80.5 / log( visibility / 100 );
|
||||
}
|
||||
|
||||
float sun_factor = 4 * (cos(sun_angle) + cos(sun_angle)/2) * vis_factor;
|
||||
// get environmental data from property tree or use defaults
|
||||
double rel_humidity, density_avg;
|
||||
|
||||
if (sun_factor > 1) sun_factor = 1.0;
|
||||
if (sun_factor < -1) sun_factor = -1.0;
|
||||
sun_factor = (sun_factor/2) + 0.5;
|
||||
if ( !env_node )
|
||||
{
|
||||
rel_humidity = 0.5;
|
||||
density_avg = 0.7;
|
||||
}
|
||||
else
|
||||
{
|
||||
rel_humidity = env_node->getFloatValue( "relative-humidity" );
|
||||
density_avg = env_node->getFloatValue( "atmosphere/density-tropo-avg" );
|
||||
}
|
||||
|
||||
sgVec4 color;
|
||||
color[1] = sqrt(sun_factor);
|
||||
color[0] = sqrt(color[1]);
|
||||
color[2] = sun_factor * sun_factor;
|
||||
color[2] *= color[2];
|
||||
color[3] = 1.0;
|
||||
// ok, now let's go and generate the sun color
|
||||
sgVec4 i_halo_color, o_halo_color, sun_color;
|
||||
|
||||
gamma_correct_rgb( color );
|
||||
// Some comments:
|
||||
// When the sunangle changes, light has to travel a longer distance through the atmosphere.
|
||||
// So it's scattered more due to raleigh scattering, which affects blue more than green light.
|
||||
// Red is almost not scattered and effectively only get's touched when the sun is near the horizon.
|
||||
// Visability also affects suncolor inasmuch as more particles are in the air that cause more scattering.
|
||||
// We base our calculation on the halo's color, which is most scattered.
|
||||
|
||||
// Red - is almost not scattered
|
||||
// Lambda is 700 nm
|
||||
|
||||
double red_scat_f = ( aerosol_factor * path_distance * density_avg ) / 5E+07;
|
||||
sun_color[0] = 1 - red_scat_f;
|
||||
i_halo_color[0] = 1 - ( 1.1 * red_scat_f );
|
||||
o_halo_color[0] = 1 - ( 1.4 * red_scat_f );
|
||||
|
||||
// cout << "color = " << color[0] << " " << color[1] << " "
|
||||
// << color[2] << endl;
|
||||
// Green - 546.1 nm
|
||||
double green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 8.8938E+06;
|
||||
sun_color[1] = 1 - green_scat_f;
|
||||
i_halo_color[1] = 1 - ( 1.1 * green_scat_f );
|
||||
o_halo_color[1] = 1 - ( 1.4 * green_scat_f );
|
||||
|
||||
// Blue - 435.8 nm
|
||||
double blue_scat_f = ( aerosol_factor * path_distance * density_avg ) / 3.607E+06;
|
||||
sun_color[2] = 1 - blue_scat_f;
|
||||
i_halo_color[2] = 1 - ( 1.1 * blue_scat_f );
|
||||
o_halo_color[2] = 1 - ( 1.4 * blue_scat_f );
|
||||
|
||||
float *ptr;
|
||||
ptr = cl->get( 0 );
|
||||
sgCopyVec4( ptr, color );
|
||||
// Alpha
|
||||
sun_color[3] = 1;
|
||||
i_halo_color[3] = 1;
|
||||
|
||||
o_halo_color[3] = blue_scat_f;
|
||||
if ( ( new_visibility < 10000 ) && ( blue_scat_f > 1 )){
|
||||
o_halo_color[3] = 2 - blue_scat_f;
|
||||
}
|
||||
|
||||
|
||||
// Now that we have the color calculated
|
||||
// let's consider the saturation which is produced by mie scattering
|
||||
double saturation = 1 - ( rel_humidity / 200 );
|
||||
sun_color[1] += (( 1 - saturation ) * ( 1 - sun_color[1] ));
|
||||
sun_color[2] += (( 1 - saturation ) * ( 1 - sun_color[2] ));
|
||||
|
||||
i_halo_color[1] += (( 1 - saturation ) * ( 1 - i_halo_color[1] ));
|
||||
i_halo_color[2] += (( 1 - saturation ) * ( 1 - i_halo_color[2] ));
|
||||
|
||||
o_halo_color[1] += (( 1 - saturation ) * ( 1 - o_halo_color[1] ));
|
||||
o_halo_color[2] += (( 1 - saturation ) * ( 1 - o_halo_color[2] ));
|
||||
|
||||
// just to make sure we're in the limits
|
||||
if ( sun_color[0] < 0 ) sun_color[0] = 0;
|
||||
else if ( sun_color[0] > 1) sun_color[0] = 1;
|
||||
if ( i_halo_color[0] < 0 ) i_halo_color[0] = 0;
|
||||
else if ( i_halo_color[0] > 1) i_halo_color[0] = 1;
|
||||
if ( o_halo_color[0] < 0 ) o_halo_color[0] = 0;
|
||||
else if ( o_halo_color[0] > 1) o_halo_color[0] = 1;
|
||||
|
||||
if ( sun_color[1] < 0 ) sun_color[1] = 0;
|
||||
else if ( sun_color[1] > 1) sun_color[1] = 1;
|
||||
if ( i_halo_color[1] < 0 ) i_halo_color[1] = 0;
|
||||
else if ( i_halo_color[1] > 1) i_halo_color[1] = 1;
|
||||
if ( o_halo_color[1] < 0 ) o_halo_color[1] = 0;
|
||||
else if ( o_halo_color[1] > 1) o_halo_color[1] = 1;
|
||||
|
||||
if ( sun_color[2] < 0 ) sun_color[2] = 0;
|
||||
else if ( sun_color[2] > 1) sun_color[2] = 1;
|
||||
if ( i_halo_color[2] < 0 ) i_halo_color[2] = 0;
|
||||
else if ( i_halo_color[2] > 1) i_halo_color[2] = 1;
|
||||
if ( o_halo_color[2] < 0 ) o_halo_color[2] = 0;
|
||||
else if ( o_halo_color[2] > 1) o_halo_color[2] = 1;
|
||||
if ( o_halo_color[3] < 0 ) o_halo_color[2] = 0;
|
||||
else if ( o_halo_color[3] > 1) o_halo_color[3] = 1;
|
||||
|
||||
|
||||
gamma_correct_rgb( i_halo_color );
|
||||
gamma_correct_rgb( o_halo_color );
|
||||
gamma_correct_rgb( sun_color );
|
||||
|
||||
|
||||
float *ptr;
|
||||
ptr = sun_cl->get( 0 );
|
||||
sgCopyVec4( ptr, sun_color );
|
||||
ptr = ihalo_cl->get( 0 );
|
||||
sgCopyVec4( ptr, i_halo_color );
|
||||
ptr = ohalo_cl->get( 0 );
|
||||
sgCopyVec4( ptr, o_halo_color );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -381,16 +558,17 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
|
||||
// declination, offset by our current position (p) so that it appears
|
||||
// fixed at a great distance from the viewer. Also add in an optional
|
||||
// rotation (i.e. for the current time of day.)
|
||||
// Then calculate stuff needed for the sun-coloring
|
||||
bool SGSun::reposition( sgVec3 p, double angle,
|
||||
double rightAscension, double declination,
|
||||
double sun_dist )
|
||||
double sun_dist, double lat, double alt_asl, double sun_angle)
|
||||
{
|
||||
// GST - GMT sidereal time
|
||||
sgMat4 T1, T2, GST, RA, DEC;
|
||||
sgVec3 axis;
|
||||
sgVec3 v;
|
||||
|
||||
sgMakeTransMat4( T1, p );
|
||||
|
||||
sgSetVec3( axis, 0.0, 0.0, -1.0 );
|
||||
sgMakeRotMat4( GST, angle, axis );
|
||||
|
||||
@@ -419,5 +597,37 @@ bool SGSun::reposition( sgVec3 p, double angle,
|
||||
|
||||
sun_transform->setTransform( &skypos );
|
||||
|
||||
// Suncolor related things:
|
||||
if ( prev_sun_angle != sun_angle ) {
|
||||
if ( sun_angle == 0 ) sun_angle = 0.1;
|
||||
const double r_earth_pole = 6356752.314;
|
||||
const double r_tropo_pole = 6356752.314 + 8000;
|
||||
const double epsilon_earth2 = 6.694380066E-3;
|
||||
const double epsilon_tropo2 = 9.170014946E-3;
|
||||
|
||||
double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( lat ), 2 )));
|
||||
double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( lat ), 2 )));
|
||||
|
||||
double position_radius = r_earth + alt_asl;
|
||||
|
||||
double gamma = SG_PI - sun_angle;
|
||||
double sin_beta = ( position_radius * sin ( gamma ) ) / r_tropo;
|
||||
double alpha = SG_PI - gamma - asin( sin_beta );
|
||||
|
||||
// OK, now let's calculate the distance the light travels
|
||||
path_distance = sqrt( pow( position_radius, 2 ) + pow( r_tropo, 2 )
|
||||
- ( 2 * position_radius * r_tropo * cos( alpha ) ));
|
||||
|
||||
double alt_half = sqrt( pow ( r_tropo, 2 ) + pow( path_distance / 2, 2 ) - r_tropo * path_distance * cos( asin( sin_beta )) ) - r_earth;
|
||||
|
||||
if ( alt_half < 0.0 ) alt_half = 0.0;
|
||||
|
||||
// Push the data to the property tree, so it can be used in the enviromental code
|
||||
if ( env_node ){
|
||||
env_node->setDoubleValue( "atmosphere/altitude-troposphere-top", r_tropo - r_earth );
|
||||
env_node->setDoubleValue( "atmosphere/altitude-half-to-sun", alt_half );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,23 +32,36 @@
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
class SGSun {
|
||||
|
||||
ssgTransform *sun_transform;
|
||||
ssgSimpleState *orb_state;
|
||||
ssgSimpleState *halo_state;
|
||||
ssgSimpleState *sun_state;
|
||||
ssgSimpleState *ihalo_state;
|
||||
ssgSimpleState *ohalo_state;
|
||||
|
||||
ssgColourArray *cl;
|
||||
ssgColourArray *sun_cl;
|
||||
ssgColourArray *ihalo_cl;
|
||||
ssgColourArray *ohalo_cl;
|
||||
|
||||
ssgVertexArray *halo_vl;
|
||||
ssgTexCoordArray *halo_tl;
|
||||
ssgVertexArray *sun_vl;
|
||||
ssgVertexArray *ihalo_vl;
|
||||
ssgVertexArray *ohalo_vl;
|
||||
|
||||
ssgTexCoordArray *sun_tl;
|
||||
ssgTexCoordArray *ihalo_tl;
|
||||
ssgTexCoordArray *ohalo_tl;
|
||||
|
||||
GLuint sun_texid;
|
||||
GLubyte *sun_texbuf;
|
||||
|
||||
double visibility;
|
||||
double prev_sun_angle;
|
||||
// distance of light traveling through the atmosphere
|
||||
double path_distance;
|
||||
|
||||
SGPropertyNode *env_node;
|
||||
|
||||
public:
|
||||
|
||||
@@ -59,7 +72,7 @@ public:
|
||||
~SGSun( void );
|
||||
|
||||
// return the sun object
|
||||
ssgBranch *build( SGPath path, double sun_size );
|
||||
ssgBranch *build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node );
|
||||
|
||||
// repaint the sun colors based on current value of sun_anglein
|
||||
// degrees relative to verticle
|
||||
@@ -74,13 +87,13 @@ public:
|
||||
// an optional rotation (i.e. for the current time of day.)
|
||||
bool reposition( sgVec3 p, double angle,
|
||||
double rightAscension, double declination,
|
||||
double sun_dist );
|
||||
double sun_dist, double lat, double alt_asl, double sun_angle );
|
||||
|
||||
// retrun the current color of the sun
|
||||
inline float *get_color() { return cl->get( 0 ); }
|
||||
inline float *get_color() { return ohalo_cl->get( 0 ); }
|
||||
|
||||
// return the texture id of the sun halo texture
|
||||
inline GLuint get_texture_id() { return halo_state->getTextureHandle(); }
|
||||
inline GLuint get_texture_id() { return ohalo_state->getTextureHandle(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ SGSky::~SGSky( void )
|
||||
void SGSky::build( double h_radius_m, double v_radius_m,
|
||||
double sun_size, double moon_size,
|
||||
int nplanets, sgdVec3 *planet_data,
|
||||
int nstars, sgdVec3 *star_data )
|
||||
int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node )
|
||||
{
|
||||
pre_root = new ssgRoot;
|
||||
post_root = new ssgRoot;
|
||||
@@ -87,7 +87,7 @@ void SGSky::build( double h_radius_m, double v_radius_m,
|
||||
pre_transform -> addKid( moon->build(tex_path, moon_size) );
|
||||
|
||||
oursun = new SGSun;
|
||||
pre_transform -> addKid( oursun->build(tex_path, sun_size) );
|
||||
pre_transform -> addKid( oursun->build(tex_path, sun_size, property_tree_node ) );
|
||||
|
||||
pre_selector->addKid( pre_transform );
|
||||
pre_selector->clrTraversalMaskBits( SSGTRAV_HOT );
|
||||
@@ -116,7 +116,6 @@ bool SGSky::repaint( const SGSkyColor &sc )
|
||||
|
||||
stars->repaint( sc.sun_angle, sc.nstars, sc.star_data );
|
||||
planets->repaint( sc.sun_angle, sc.nplanets, sc.planet_data );
|
||||
|
||||
oursun->repaint( sc.sun_angle, effective_visibility );
|
||||
moon->repaint( sc.moon_angle );
|
||||
|
||||
@@ -152,7 +151,7 @@ bool SGSky::reposition( SGSkyState &st, double dt )
|
||||
planets->reposition( st.view_pos, angle );
|
||||
|
||||
oursun->reposition( st.view_pos, angle,
|
||||
st.sun_ra, st.sun_dec, st.sun_dist );
|
||||
st.sun_ra, st.sun_dec, st.sun_dist, st.lat, st.alt, st.sun_angle );
|
||||
|
||||
moon->reposition( st.view_pos, angle,
|
||||
st.moon_ra, st.moon_dec, st.moon_dist );
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -60,6 +61,7 @@ typedef struct {
|
||||
double gst;
|
||||
double sun_ra, sun_dec, sun_dist;
|
||||
double moon_ra, moon_dec, moon_dist;
|
||||
double sun_angle;
|
||||
} SGSkyState;
|
||||
|
||||
typedef struct {
|
||||
@@ -259,7 +261,7 @@ public:
|
||||
void build( double h_radius_m, double v_radius_m,
|
||||
double sun_size, double moon_size,
|
||||
int nplanets, sgdVec3 *planet_data,
|
||||
int nstars, sgdVec3 *star_data );
|
||||
int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node );
|
||||
|
||||
/**
|
||||
* Repaint the sky components based on current value of sun_angle,
|
||||
|
||||
@@ -24,94 +24,326 @@
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/scene/tgdb/leaf.hxx>
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
|
||||
#include "apt_signs.hxx"
|
||||
|
||||
#define SIGN "OBJECT_SIGN: "
|
||||
#define RWY "OBJECT_RUNWAY_SIGN: "
|
||||
|
||||
ssgBranch *sgMakeTaxiSign( SGMaterialLib *matlib,
|
||||
const string path, const string content )
|
||||
SG_USING_STD(vector);
|
||||
|
||||
// for temporary storage of sign elements
|
||||
struct element_info {
|
||||
element_info(SGMaterial *m, ssgSimpleState *s, SGMaterialGlyph *g, double h)
|
||||
: material(m), state(s), glyph(g), height(h)
|
||||
{
|
||||
scale = h * m->get_xsize()
|
||||
/ (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
|
||||
}
|
||||
SGMaterial *material;
|
||||
ssgSimpleState *state;
|
||||
SGMaterialGlyph *glyph;
|
||||
double height;
|
||||
double scale;
|
||||
};
|
||||
|
||||
|
||||
// standard panel height sizes
|
||||
const double HT[5] = {0.460, 0.610, 0.760, 1.220, 0.760};
|
||||
|
||||
|
||||
// translation table for "command" to "glyph name"
|
||||
struct pair {
|
||||
const char *keyword;
|
||||
const char *glyph_name;
|
||||
} cmds[] = {
|
||||
{"@u", "up"},
|
||||
{"@d", "down"},
|
||||
{"@l", "left"},
|
||||
{"@lu", "left-up"},
|
||||
{"@ul", "left-up"},
|
||||
{"@ld", "left-down"},
|
||||
{"@dl", "left-down"},
|
||||
{"@r", "right"},
|
||||
{"@ru", "right-up"},
|
||||
{"@ur", "right-up"},
|
||||
{"@rd", "right-down"},
|
||||
{"@dr", "right-down"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
|
||||
// see $FG_ROOT/Docs/README.scenery
|
||||
//
|
||||
ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string content)
|
||||
{
|
||||
// for demo purposes we assume each element (letter) is 1x1 meter.
|
||||
// Sign is placed 0.25 meters above the ground
|
||||
double sign_height = 1.0; // meter
|
||||
bool lighted = true;
|
||||
string newmat = "BlackSign";
|
||||
|
||||
vector<element_info *> elements;
|
||||
element_info *close = 0;
|
||||
double total_width = 0.0;
|
||||
bool cmd = false;
|
||||
int size = -1;
|
||||
char oldtype = 0, newtype = 0;
|
||||
|
||||
ssgBranch *object = new ssgBranch();
|
||||
object->setName( (char *)content.c_str() );
|
||||
object->setName((char *)content.c_str());
|
||||
|
||||
double offset = content.length() / 2.0;
|
||||
SGMaterial *material;
|
||||
ssgSimpleState *lighted_state;
|
||||
ssgSimpleState *unlighted_state;
|
||||
|
||||
for ( unsigned int i = 0; i < content.length(); ++i ) {
|
||||
string material;
|
||||
// Part I: parse & measure
|
||||
for (const char *s = content.data(); *s; s++) {
|
||||
string name;
|
||||
string value;
|
||||
|
||||
char item = content[i];
|
||||
if ( item == '<' ) {
|
||||
material = "ArrowL.rgb";
|
||||
} else if ( item == '>' ) {
|
||||
material = "ArrowR.rgb";
|
||||
} else if ( item >= 'A' && item <= 'Z' ) {
|
||||
material = "Letter";
|
||||
material += item;
|
||||
material += ".rgb";
|
||||
} else if ( item >= 'a' && item <= 'z' ) {
|
||||
int tmp = item - 'a';
|
||||
char c = 'A' + tmp;
|
||||
material = "Black";
|
||||
material += c;
|
||||
material += ".rgb";
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||
"Unknown taxi sign code = '" << item << "' !!!!" );
|
||||
return NULL;
|
||||
}
|
||||
if (*s == '{') {
|
||||
if (cmd)
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected { in sign contents");
|
||||
cmd = true;
|
||||
continue;
|
||||
|
||||
point_list nodes; nodes.clear();
|
||||
point_list normals; normals.clear();
|
||||
point_list texcoords; texcoords.clear();
|
||||
int_list vertex_index; vertex_index.clear();
|
||||
int_list normal_index; normal_index.clear();
|
||||
int_list tex_index; tex_index.clear();
|
||||
} else if (*s == '}') {
|
||||
if (!cmd)
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected } in sign contents");
|
||||
cmd = false;
|
||||
continue;
|
||||
|
||||
nodes.push_back( Point3D( -offset + i, 0, 0.25 ) );
|
||||
nodes.push_back( Point3D( -offset + i + 1, 0, 0.25 ) );
|
||||
nodes.push_back( Point3D( -offset + i, 0, 1.25 ) );
|
||||
nodes.push_back( Point3D( -offset + i + 1, 0, 1.25 ) );
|
||||
} else if (!cmd) {
|
||||
name = *s;
|
||||
|
||||
normals.push_back( Point3D( 0, -1, 0 ) );
|
||||
} else {
|
||||
if (*s == ',')
|
||||
continue;
|
||||
|
||||
texcoords.push_back( Point3D( 0, 0, 0 ) );
|
||||
texcoords.push_back( Point3D( 1, 0, 0 ) );
|
||||
texcoords.push_back( Point3D( 0, 1, 0 ) );
|
||||
texcoords.push_back( Point3D( 1, 1, 0 ) );
|
||||
for (; *s; s++) {
|
||||
name += *s;
|
||||
if (s[1] == ',' || s[1] == '}' || s[1] == '=')
|
||||
break;
|
||||
}
|
||||
if (!*s) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
||||
} else if (s[1] == '=') {
|
||||
for (s += 2; *s; s++) {
|
||||
value += *s;
|
||||
if (s[1] == ',' || s[1] == '}')
|
||||
break;
|
||||
}
|
||||
if (!*s)
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
||||
}
|
||||
|
||||
vertex_index.push_back( 0 );
|
||||
vertex_index.push_back( 1 );
|
||||
vertex_index.push_back( 2 );
|
||||
vertex_index.push_back( 3 );
|
||||
if (name == "@size") {
|
||||
sign_height = strtod(value.data(), 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
normal_index.push_back( 0 );
|
||||
normal_index.push_back( 0 );
|
||||
normal_index.push_back( 0 );
|
||||
normal_index.push_back( 0 );
|
||||
if (name == "@light") {
|
||||
lighted = (value != "0" && value != "no" && value != "off" && value != "false");
|
||||
continue;
|
||||
}
|
||||
|
||||
tex_index.push_back( 0 );
|
||||
tex_index.push_back( 1 );
|
||||
tex_index.push_back( 2 );
|
||||
tex_index.push_back( 3 );
|
||||
if (name == "@material") {
|
||||
newmat = value.data();
|
||||
continue;
|
||||
|
||||
ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP, matlib, material,
|
||||
nodes, normals, texcoords,
|
||||
vertex_index, normal_index, tex_index,
|
||||
false, NULL );
|
||||
} else if (name.size() == 2 || name.size() == 3) {
|
||||
string n = name;
|
||||
if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') {
|
||||
size = n[2] - '1';
|
||||
n = n.substr(0, 2);
|
||||
}
|
||||
|
||||
object->addKid( leaf );
|
||||
if (n == "@Y") {
|
||||
if (size < 3) {
|
||||
sign_height = HT[size < 0 ? 2 : size];
|
||||
newmat = "YellowSign";
|
||||
newtype = 'Y';
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (n == "@R") {
|
||||
if (size < 3) {
|
||||
sign_height = HT[size < 0 ? 2 : size];
|
||||
newmat = "RedSign";
|
||||
newtype = 'R';
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (n == "@L") {
|
||||
if (size < 3) {
|
||||
sign_height = HT[size < 0 ? 2 : size];
|
||||
newmat = "FramedSign";
|
||||
newtype = 'L';
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (n == "@B") {
|
||||
if (size < 0 || size == 3 || size == 4) {
|
||||
sign_height = HT[size < 0 ? 3 : size];
|
||||
newmat = "BlackSign";
|
||||
newtype = 'B';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; cmds[i].keyword; i++) {
|
||||
if (name == cmds[i].keyword) {
|
||||
name = cmds[i].glyph_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (name[0] == '@') {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown command `" << name << '\'');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (newmat.size()) {
|
||||
material = matlib->find(newmat);
|
||||
if (!material) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
|
||||
continue;
|
||||
}
|
||||
|
||||
// set material states (lighted & unlighted)
|
||||
lighted_state = material->get_state();
|
||||
string u = newmat + ".unlighted";
|
||||
|
||||
SGMaterial *m = matlib->find(u);
|
||||
if (m) {
|
||||
unlighted_state = m->get_state();
|
||||
} else {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
|
||||
unlighted_state = lighted_state;
|
||||
}
|
||||
newmat = "";
|
||||
}
|
||||
|
||||
SGMaterialGlyph *glyph = material->get_glyph(name);
|
||||
if (!glyph) {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph `" << *s << '\'');
|
||||
continue;
|
||||
}
|
||||
|
||||
// in managed mode push frame stop and frame start first
|
||||
ssgSimpleState *state = lighted ? lighted_state : unlighted_state;
|
||||
element_info *e;
|
||||
if (newtype && newtype != oldtype) {
|
||||
if (close) {
|
||||
elements.push_back(close);
|
||||
total_width += close->glyph->get_width() * close->scale;
|
||||
close = 0;
|
||||
}
|
||||
oldtype = newtype;
|
||||
SGMaterialGlyph *g = material->get_glyph("stop-frame");
|
||||
if (g)
|
||||
close = new element_info(material, state, g, sign_height);
|
||||
g = material->get_glyph("start-frame");
|
||||
if (g) {
|
||||
e = new element_info(material, state, g, sign_height);
|
||||
elements.push_back(e);
|
||||
total_width += e->glyph->get_width() * e->scale;
|
||||
}
|
||||
}
|
||||
// now the actually requested glyph
|
||||
e = new element_info(material, state, glyph, sign_height);
|
||||
elements.push_back(e);
|
||||
total_width += e->glyph->get_width() * e->scale;
|
||||
}
|
||||
|
||||
// in managed mode close frame
|
||||
if (close) {
|
||||
elements.push_back(close);
|
||||
total_width += close->glyph->get_width() * close->scale;
|
||||
close = 0;
|
||||
}
|
||||
|
||||
|
||||
// Part II: typeset
|
||||
double hpos = -total_width / 2;
|
||||
const double dist = 0.25; // hard-code distance from surface for now
|
||||
|
||||
sgVec3 normal;
|
||||
sgSetVec3(normal, 0, -1, 0);
|
||||
|
||||
sgVec4 color;
|
||||
sgSetVec4(color, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
for (unsigned int i = 0; i < elements.size(); i++) {
|
||||
element_info *element = elements[i];
|
||||
|
||||
double xoffset = element->glyph->get_left();
|
||||
double height = element->height;
|
||||
double width = element->glyph->get_width();
|
||||
double abswidth = width * element->scale;
|
||||
|
||||
// vertices
|
||||
ssgVertexArray *vl = new ssgVertexArray(4);
|
||||
vl->add(0, hpos, dist);
|
||||
vl->add(0, hpos + abswidth, dist);
|
||||
vl->add(0, hpos, dist + height);
|
||||
vl->add(0, hpos + abswidth, dist + height);
|
||||
|
||||
// texture coordinates
|
||||
ssgTexCoordArray *tl = new ssgTexCoordArray(4);
|
||||
tl->add(xoffset, 0);
|
||||
tl->add(xoffset + width, 0);
|
||||
tl->add(xoffset, 1);
|
||||
tl->add(xoffset + width, 1);
|
||||
|
||||
// normals
|
||||
ssgNormalArray *nl = new ssgNormalArray(1);
|
||||
nl->add(normal);
|
||||
|
||||
// colors
|
||||
ssgColourArray *cl = new ssgColourArray(1);
|
||||
cl->add(color);
|
||||
|
||||
ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, tl, cl);
|
||||
leaf->setState(element->state);
|
||||
|
||||
object->addKid(leaf);
|
||||
hpos += abswidth;
|
||||
delete element;
|
||||
}
|
||||
|
||||
|
||||
// minimalistic backside
|
||||
ssgVertexArray *vl = new ssgVertexArray(4);
|
||||
vl->add(0, hpos, dist);
|
||||
vl->add(0, hpos - total_width, dist);
|
||||
vl->add(0, hpos, dist + sign_height);
|
||||
vl->add(0, hpos - total_width, dist + sign_height);
|
||||
|
||||
ssgNormalArray *nl = new ssgNormalArray(1);
|
||||
nl->add(0, 1, 0);
|
||||
|
||||
ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, 0, 0);
|
||||
SGMaterial *mat = matlib->find("BlackSign");
|
||||
if (mat)
|
||||
leaf->setState(mat->get_state());
|
||||
object->addKid(leaf);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
|
||||
const string path, const string name )
|
||||
{
|
||||
@@ -123,14 +355,14 @@ ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
|
||||
|
||||
double width = name.length() / 3.0;
|
||||
|
||||
string material = name + ".rgb";
|
||||
string material = name;
|
||||
|
||||
point_list nodes; nodes.clear();
|
||||
point_list normals; normals.clear();
|
||||
point_list texcoords; texcoords.clear();
|
||||
int_list vertex_index; vertex_index.clear();
|
||||
int_list normal_index; normal_index.clear();
|
||||
int_list tex_index; tex_index.clear();
|
||||
point_list nodes;
|
||||
point_list normals;
|
||||
point_list texcoords;
|
||||
int_list vertex_index;
|
||||
int_list normal_index;
|
||||
int_list tex_index;
|
||||
|
||||
nodes.push_back( Point3D( -width, 0, 0.25 ) );
|
||||
nodes.push_back( Point3D( width + 1, 0, 0.25 ) );
|
||||
|
||||
@@ -41,9 +41,9 @@ class SGMaterialLib; // forward declaration
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
// Generate a taxi sign
|
||||
ssgBranch *sgMakeTaxiSign( SGMaterialLib *matlib,
|
||||
const string path, const string content );
|
||||
// Generate a generic sign
|
||||
ssgBranch *sgMakeSign( SGMaterialLib *matlib,
|
||||
const string path, const string content );
|
||||
|
||||
|
||||
// Generate a runway sign
|
||||
|
||||
@@ -250,6 +250,7 @@ ssgLeaf *sgMakeLeaf( const string& path,
|
||||
|
||||
// lookup the state record
|
||||
|
||||
leaf->setUserData( new SGMaterialUserData(mat) );
|
||||
leaf->setState( state );
|
||||
|
||||
if ( calc_lights ) {
|
||||
|
||||
@@ -176,6 +176,7 @@ bool sgGenTile( const string& path, SGBucket b,
|
||||
ssgLeaf *leaf =
|
||||
new ssgVtxTable ( GL_TRIANGLE_FAN, vl, nl, tl, cl );
|
||||
|
||||
leaf->setUserData( new SGMaterialUserData(mat) );
|
||||
leaf->setState( state );
|
||||
geometry->addKid( leaf );
|
||||
|
||||
|
||||
@@ -25,19 +25,78 @@
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/screen/extensions.hxx>
|
||||
|
||||
#include "vasi.hxx"
|
||||
|
||||
#include "pt_lights.hxx"
|
||||
|
||||
|
||||
// static variables for use in ssg callbacks
|
||||
static bool extensions_checked = false;
|
||||
static bool glPointParameterIsSupported = false;
|
||||
static glPointParameterfProc glPointParameterfPtr;
|
||||
static glPointParameterfvProc glPointParameterfvPtr;
|
||||
static bool SGPointLightsUseSprites = false;
|
||||
static bool SGPointLightsEnhancedLighting = false;
|
||||
static bool SGPointLightsDistanceAttenuation = false;
|
||||
|
||||
|
||||
// Specify the way we want to draw directional point lights (assuming the
|
||||
// appropriate extensions are available.)
|
||||
|
||||
void sgConfigureDirectionalLights( bool use_point_sprites,
|
||||
bool enhanced_lighting,
|
||||
bool distance_attenuation ) {
|
||||
SGPointLightsUseSprites = use_point_sprites;
|
||||
SGPointLightsEnhancedLighting = enhanced_lighting;
|
||||
SGPointLightsDistanceAttenuation = distance_attenuation;
|
||||
}
|
||||
|
||||
|
||||
// runtime check for the availability of various opengl extensions.
|
||||
static void check_for_extensions() {
|
||||
// get the address of our OpenGL extensions
|
||||
if (SGIsOpenGLExtensionSupported("GL_EXT_point_parameters") ) {
|
||||
glPointParameterIsSupported = true;
|
||||
glPointParameterfPtr = (glPointParameterfProc)
|
||||
SGLookupFunction("glPointParameterfEXT");
|
||||
glPointParameterfvPtr = (glPointParameterfvProc)
|
||||
SGLookupFunction("glPointParameterfvEXT");
|
||||
} else if ( SGIsOpenGLExtensionSupported("GL_ARB_point_parameters") ) {
|
||||
glPointParameterIsSupported = true;
|
||||
glPointParameterfPtr = (glPointParameterfProc)
|
||||
SGLookupFunction("glPointParameterfARB");
|
||||
glPointParameterfvPtr = (glPointParameterfvProc)
|
||||
SGLookupFunction("glPointParameterfvARB");
|
||||
} else {
|
||||
glPointParameterIsSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// strobe pre-draw (we want a larger point size)
|
||||
static int StrobePreDraw( ssgEntity *e ) {
|
||||
// check for the availability of point parameter extension, but
|
||||
// just once.
|
||||
if ( !extensions_checked ) {
|
||||
check_for_extensions();
|
||||
extensions_checked = true;
|
||||
}
|
||||
|
||||
glPushAttrib( GL_POINT_BIT );
|
||||
glPointSize(4.0);
|
||||
if ( glPointParameterIsSupported && SGPointLightsEnhancedLighting ) {
|
||||
if ( SGPointLightsUseSprites ) {
|
||||
glPointSize(10.0);
|
||||
} else {
|
||||
glPointSize(8.0);
|
||||
}
|
||||
} else {
|
||||
glPointSize(4.0);
|
||||
}
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
return true;
|
||||
@@ -53,8 +112,23 @@ static int StrobePostDraw( ssgEntity *e ) {
|
||||
|
||||
// vasi pre-draw (we want a larger point size)
|
||||
static int VASIPreDraw( ssgEntity *e ) {
|
||||
// check for the availability of point parameter extension, but
|
||||
// just once.
|
||||
if ( !extensions_checked ) {
|
||||
check_for_extensions();
|
||||
extensions_checked = true;
|
||||
}
|
||||
|
||||
glPushAttrib( GL_POINT_BIT );
|
||||
glPointSize(2.0);
|
||||
if ( glPointParameterIsSupported && SGPointLightsEnhancedLighting ) {
|
||||
if ( SGPointLightsUseSprites ) {
|
||||
glPointSize(10.0);
|
||||
} else {
|
||||
glPointSize(8.0);
|
||||
}
|
||||
} else {
|
||||
glPointSize(4.0);
|
||||
}
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <plib/ssg.h> // plib include
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
@@ -89,5 +90,12 @@ ssgBranch *sgMakeDirectionalLights( const point_list &nodes,
|
||||
const string &material,
|
||||
sgdVec3 dup );
|
||||
|
||||
// Specify the way we want to draw directional point lights (assuming the
|
||||
// appropriate extensions are available.)
|
||||
|
||||
void sgConfigureDirectionalLights( bool use_point_sprites,
|
||||
bool enhanced_lighting,
|
||||
bool distance_attenuation );
|
||||
|
||||
|
||||
#endif // _SG_PT_LIGHTS_HXX
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
#include <limits.h>
|
||||
#include <string.h> // memcpy()
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include SG_GL_H
|
||||
|
||||
#include "GLBitmaps.h"
|
||||
|
||||
GlBitmap::GlBitmap( GLenum mode, GLint width, GLint height, GLubyte *bitmap )
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include SG_GL_H
|
||||
|
||||
class GlBitmap
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
# include <X11/Xlib.h>
|
||||
#endif
|
||||
#include SG_GL_H
|
||||
#if defined( __MACH__)
|
||||
# include <OpenGL/CGLTypes.h>
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
# include SG_GLX_H
|
||||
#endif
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include "jpgfactory.hxx"
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ void Shader::bind(const float *v,...) {
|
||||
}
|
||||
const float *value = v;
|
||||
va_list args;
|
||||
va_start(args,value);
|
||||
va_start(args,v);
|
||||
for(int i = 0; i < (int)parameters.size(); i++) {
|
||||
if( vertex_target ) {
|
||||
glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value);
|
||||
@@ -549,7 +549,7 @@ void Shader::setParameter(const char *name,const float *value) {
|
||||
void Shader::setParameters(const float *v,...) {
|
||||
const float *value = v;
|
||||
va_list args;
|
||||
va_start(args,value);
|
||||
va_start(args,v);
|
||||
for(int i = 0; i < (int)parameters.size(); i++) {
|
||||
if( vertex_target ) {
|
||||
glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "ssgEntityArray.hxx"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _SSG_ENTITY_ARRAY_HXX
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
@@ -122,6 +122,9 @@ bool SGSerialPort::open_port(const string& device) {
|
||||
|
||||
// cout << "config.c_iflag = " << config.c_iflag << endl;
|
||||
|
||||
// disable LF expanded to CR-LF
|
||||
config.c_oflag &= ~(ONLCR);
|
||||
|
||||
// disable software flow control
|
||||
config.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
|
||||
|
||||
@@ -63,6 +63,11 @@ extern "C" int isinf (double);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__CYGWIN__)
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
@@ -91,8 +96,13 @@ SGSoundMgr::SGSoundMgr() {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, " "+string(alutGetErrorString(error)));
|
||||
working = false;
|
||||
context = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
working = true;
|
||||
context = alcGetCurrentContext();
|
||||
}
|
||||
context = alcGetCurrentContext();
|
||||
#else
|
||||
if ( (dev = alcOpenDevice( NULL )) != NULL
|
||||
&& ( context = alcCreateContext( dev, NULL )) != NULL ) {
|
||||
|
||||
@@ -21,30 +21,28 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/props/condition.hxx>
|
||||
#include <simgear/math/fastmath.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
|
||||
#include "xmlsound.hxx"
|
||||
|
||||
|
||||
#define LOG_ABS(x) (((x) > 1) ? (x) : (((x) < -1) ? -(x) : 0))
|
||||
// static double _snd_lin(double v) { return v; }
|
||||
static double _snd_inv(double v) { return (v == 0) ? 1e99 : 1/v; }
|
||||
static double _snd_abs(double v) { return (v >= 0) ? v : -v; }
|
||||
static double _snd_sqrt(double v) { return (v < 0) ? sqrt(-v) : sqrt(v); }
|
||||
static double _snd_log10(double v) { return fast_log10( LOG_ABS(v) ); }
|
||||
static double _snd_log(double v) { return fast_log( LOG_ABS(v) ); }
|
||||
static double _snd_sqrt(double v) { return sqrt(fabs(v)); }
|
||||
static double _snd_log10(double v) { return log10(fabs(v)); }
|
||||
static double _snd_log(double v) { return log(fabs(v)); }
|
||||
// static double _snd_sqr(double v) { return v*v; }
|
||||
// static double _snd_pow3(double v) { return v*v*v; }
|
||||
|
||||
|
||||
+14
-47
@@ -27,8 +27,12 @@
|
||||
* written for FlightGear, in order to store Timezone control points.
|
||||
*
|
||||
************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include "geocoord.h"
|
||||
#include <plib/sg.h>
|
||||
|
||||
SGGeoCoord::SGGeoCoord(const SGGeoCoord& other)
|
||||
{
|
||||
@@ -36,57 +40,20 @@ SGGeoCoord::SGGeoCoord(const SGGeoCoord& other)
|
||||
lon = other.lon;
|
||||
}
|
||||
|
||||
// double SGGeoCoord::getAngle(const SGGeoCoord& other) const
|
||||
// {
|
||||
// Vector first( getX(), getY(), getZ());
|
||||
// Vector secnd(other.getX(), other.getY(), other.getZ());
|
||||
// double
|
||||
// dot = VecDot(first, secnd),
|
||||
// len1 = first.VecLen(),
|
||||
// len2 = secnd.VecLen(),
|
||||
// len = len1 * len2,
|
||||
// angle = 0;
|
||||
// //printf ("Dot: %f, len1: %f len2: %f\n", dot, len1, len2);
|
||||
// /*Vector pPos = prevPos - Reference->prevPos;
|
||||
// Vector pVel = prevVel - Reference->prevVel;*/
|
||||
|
||||
|
||||
// if ( ( (dot / len) < 1) && (dot / len > -1) && len )
|
||||
// angle = acos(dot / len);
|
||||
// return angle;
|
||||
// }
|
||||
|
||||
// SGGeoCoord* SGGeoCoordContainer::getNearest(const SGGeoCoord& ref) const
|
||||
// {
|
||||
// float angle, maxAngle = 180;
|
||||
|
||||
// SGGeoCoordVectorConstIterator i, nearest;
|
||||
// for (i = data.begin(); i != data.end(); i++)
|
||||
// {
|
||||
// angle = SGD_RADIANS_TO_DEGREES * (*i)->getAngle(ref);
|
||||
// if (angle < maxAngle)
|
||||
// {
|
||||
// maxAngle = angle;
|
||||
// nearest = i;
|
||||
// }
|
||||
// }
|
||||
// return *nearest;
|
||||
// }
|
||||
|
||||
|
||||
SGGeoCoord* SGGeoCoordContainer::getNearest(const SGGeoCoord& ref) const
|
||||
{
|
||||
sgVec3 first, secnd;
|
||||
float dist, maxDist=SG_MAX;
|
||||
sgSetVec3( first, ref.getX(), ref.getY(), ref.getZ());
|
||||
if (data.empty())
|
||||
return 0;
|
||||
|
||||
float maxCosAng = -2;
|
||||
SGVec3f refVec(ref.getX(), ref.getY(), ref.getZ());
|
||||
SGGeoCoordVectorConstIterator i, nearest;
|
||||
for (i = data.begin(); i != data.end(); i++)
|
||||
for (i = data.begin(); i != data.end(); ++i)
|
||||
{
|
||||
sgSetVec3(secnd, (*i)->getX(), (*i)->getY(), (*i)->getZ());
|
||||
dist = sgDistanceSquaredVec3(first, secnd);
|
||||
if (dist < maxDist)
|
||||
float cosAng = dot(refVec, SGVec3f((*i)->getX(), (*i)->getY(), (*i)->getZ()));
|
||||
if (maxCosAng < cosAng)
|
||||
{
|
||||
maxDist = dist;
|
||||
maxCosAng = cosAng;
|
||||
nearest = i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,6 @@
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include STL_IOSTREAM
|
||||
//#include <streambuf> // looks like streambuf does not exist on linux.
|
||||
// But it looks like it isn't used anyways -:)
|
||||
#include <vector>
|
||||
|
||||
SG_USING_NAMESPACE(std);
|
||||
@@ -66,8 +62,6 @@ public:
|
||||
float getZ() const { return sin(SGD_DEGREES_TO_RADIANS*lat); };
|
||||
|
||||
|
||||
//double getAngle(const SGGeoCoord& other) const;
|
||||
virtual void print() {} ;
|
||||
virtual const char * getDescription() {return 0;};
|
||||
};
|
||||
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "About to benchmark SGTimeStamp for 5 seconds. Press ENTER when ready." << endl;
|
||||
int c = cin.get();
|
||||
long nb = 0;
|
||||
SGTimeStamp start, now;
|
||||
start.stamp();
|
||||
do {
|
||||
nb += 1;
|
||||
now.stamp();
|
||||
} while ( ( now - start ) < 5000000 );
|
||||
|
||||
cout << ( nb / 5 ) << " iterations per seconds. Press ENTER to quit." << endl;
|
||||
c = cin.get();
|
||||
}
|
||||
@@ -72,8 +72,8 @@ void SGTimeStamp::stamp() {
|
||||
#if defined( WIN32 ) && !defined(__CYGWIN__)
|
||||
unsigned int t;
|
||||
t = timeGetTime();
|
||||
seconds = 0;
|
||||
usec = t * 1000;
|
||||
seconds = t / 1000;
|
||||
usec = ( t - ( seconds * 1000 ) ) * 1000;
|
||||
#elif defined( HAVE_GETTIMEOFDAY )
|
||||
struct timeval current;
|
||||
struct timezone tz;
|
||||
@@ -105,20 +105,12 @@ void SGTimeStamp::stamp() {
|
||||
|
||||
// increment the time stamp by the number of microseconds (usec)
|
||||
SGTimeStamp operator + (const SGTimeStamp& t, const long& m) {
|
||||
#if defined( WIN32 ) && !defined(__CYGWIN__)
|
||||
return SGTimeStamp( 0, t.usec + m );
|
||||
#else
|
||||
return SGTimeStamp( t.seconds + ( t.usec + m ) / 1000000,
|
||||
( t.usec + m ) % 1000000 );
|
||||
#endif
|
||||
}
|
||||
|
||||
// difference between time stamps in microseconds (usec)
|
||||
long operator - (const SGTimeStamp& a, const SGTimeStamp& b)
|
||||
{
|
||||
#if defined( WIN32 ) && !defined(__CYGWIN__)
|
||||
return a.usec - b.usec;
|
||||
#else
|
||||
return 1000000 * (a.seconds - b.seconds) + (a.usec - b.usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define _TIMEZONE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include <simgear/timing/geocoord.h>
|
||||
|
||||
@@ -84,11 +85,6 @@ public:
|
||||
*/
|
||||
virtual ~SGTimeZone() { };
|
||||
|
||||
/**
|
||||
* Print the descriptor string
|
||||
*/
|
||||
virtual void print() { printf("%s", descriptor.c_str()); }
|
||||
|
||||
/**
|
||||
* Return the descriptor string
|
||||
* @return descriptor string (char array)
|
||||
|
||||
Reference in New Issue
Block a user