Compare commits

...
Author SHA1 Message Date
curt 7c410d36e3 wim van hoydonck:
Updated to World Magnetic Model 2005.
2006-10-28 22:12:48 +00:00
mfranz 98a603a570 - don't need a guarded pointer here
- shorten variable, fix indentation
2006-10-24 20:28:08 +00:00
mfranz 5876052170 allow to switch on/off at runtime a whole imported <model> via <condition>:
<model>
      <path>some/model.xml</path>
      <condition>
          <property>model/switch</property>
      </condition>
  </model>

Of course, one could add "select" animations for all <object-name> in the
<model>, but this is tedious and can hardly be done e.g. for all
objects in all instruments in $FG_ROOT/Aircraft/Instruments-3d/ etc.

The feature will be used in the bo105, so that civilian variants can
have a HSI instrument, where military variants have a TACAN etc.
2006-10-24 19:44:38 +00:00
durk f8303b4623 Compile time fixes needed to build SimGear on recent cygwin versions. 2006-10-22 19:42:17 +00:00
durk 20005a7a22 Make configuration script compatible with "home-built" openal libraries
on cygwin.
2006-10-22 19:41:16 +00:00
mfranz 4f0bfbab21 - // This will come back and remove
- // the current item each time.  Is
- // that OK?

No, it is not OK. This messes up the vector and confuses the iterator.
And it leads to crashes. Better read the vector in reverse order.
2006-10-22 13:08:09 +00:00
curt 811442832e Step #1 towards abandoning the original point lighting scheme in favor of
sprite based lighting.
2006-10-19 03:36:22 +00:00
frohlich 40811311d7 Modified Files:
SimGear.vcproj: Import changes from Olaf
2006-09-30 07:11:16 +00:00
durk 198de211f8 Memory leak fix. 2006-09-30 05:11:25 +00:00
fredb 9f5412fa9d Win32 only : Don't alloc a console when it is not needed 2006-09-27 20:16:32 +00:00
fredb 0dc9de81ae Add a simple program to benchmark SGTimeStamp::stamp() 2006-09-02 11:21:22 +00:00
fredb 5b8f42ce5e Make the SGTimeStamp behave under Windows just like for other environments 2006-08-31 18:26:45 +00:00
fredb 5314274ed6 Use getNodeValue as initially planned 2006-08-28 19:38:23 +00:00
ehofman c831856711 MispPro requires an explicit declaration. 2006-08-28 18:53:36 +00:00
curt 1bade6d796 Frederic Bouvier:
Make line feed behavior consistent between linux/windows.
2006-08-26 14:02:17 +00:00
fredb 629a4a950e Better encapsulation for personality 2006-08-25 19:25:56 +00:00
mfranz aebb1f6ec8 compile (gcc 4.1.0)
("In member function 'T SGPersonalityParameter<T>::shuffle()':
28: error: there are no arguments to 'sg_random' that depend on a template
parameter, so a declaration of 'sg_random' must be available")
2006-08-24 23:03:52 +00:00
fredb 6e42bc55e0 Reorganize personality parameters and add personality to translate, blend and scale animations 2006-08-24 22:46:40 +00:00
frohlich 1235fba7ee Remove duplicate linker line in the resulting Makefile 2006-08-08 05:05:09 +00:00
fredb 7a459db022 Win32 fix 2006-07-30 21:02:36 +00:00
frohlich 607987def5 Remove fastmath funktions like discussed on the list.
Add a new header with forward declarations of the SGMath stuff.
2006-07-30 07:48:06 +00:00
frohlich 397ec62180 Clean up scenery center handling. 2006-07-27 16:34:32 +00:00
durk 9315210fbe Mark's dynamic sun color changes. 2006-07-27 05:15:20 +00:00
curt 5127990a43 Additional functionality for animated point lights (i.e. approach light
rabbits, REIL, VASI/PAPI, etc.)

This allows the calling layer (i.e. FlightGear) better control over the use
of OpenGL point drawing extensions.
2006-07-21 15:45:01 +00:00
curt 40ad2b155a Updated dist content. 2006-07-12 15:08:00 +00:00
mfranz a0412d026c remove the last redundant "delete" check in all of fgfs/sg (except JSBSim) 2006-07-05 09:31:36 +00:00
andy 7d2134c488 The previous update (and, embarassingly, the "nasal 1.0" release I
announced on Freshmeat.net) was broken.  This is the proper
break/continue fix.
2006-07-05 02:52:06 +00:00
andy d894f52b97 Been hacking at Nasal recently:
Fix bug with break/continue inside of a foreach or forindex: Don't pop
the vector/index inside OP_EACH, do it at the end of the loop.

In the process, discovered and fixed a scary corruption issue with
continue; it never really worked right, although simple usage was
likely to get away without crashing.  Both the continue's OP_BREAK and
the cleanup code at the end of a loop would pop the "mark" stack,
leading to an underflow.  Introduced an OP_CONTINUE which adjusts
stack but doesn't change markTop

Re-inline the PUSH macro.  This thing is called all over the place
from the inner loop.  If the problem is intra-expression side effects,
then just use another expression in the macro.

Return an empty vector when requesting zero-length subvec, not nil

Have call() return the call stack in the error vector; see docs on
plausible.org/nasal or ask Andy about this feature.

Default closure()'s level argument to zero, not nil

Add an optional "file name" argument to compile()
2006-07-03 05:13:27 +00:00
mfranz 735f475c24 actually query the <condition> that is already set up in SGShaderAnimation 2006-07-01 20:06:05 +00:00
mfranz 353dd73e24 add knots <-> feet-per-second conversion constants 2006-06-25 11:55:56 +00:00
fredb 49fe06498a Compile again on Win32 platforms 2006-06-17 22:02:32 +00:00
frohlich bc95ec8084 Make at least the header aliasing safe. 2006-06-17 16:04:28 +00:00
frohlich f79906bf16 Make it compile with gcc-3.3.6 2006-06-17 16:04:05 +00:00
fredb b3262fcb80 Compile again on Win32 platforms 2006-06-16 10:03:38 +00:00
mfranz 52b8f924aa add float_to_int() rounding function from Cockpit/hud_opts.hxx. The original
file said "(c) FlightGear Project" and "probably written by Norman Vine".
2006-06-16 09:29:54 +00:00
frohlich 52f57160aa Add dist and distSqr functions 2006-06-15 19:13:24 +00:00
frohlich 6d4f23919c Remove unused extern decls 2006-06-15 19:12:57 +00:00
frohlich 899623f71b Remove deprecated, now unused functions. 2006-06-15 08:52:21 +00:00
frohlich c5d677ac7b Small cleanups to the SGGeo[dc] classes, provide more hooks to use them directly 2006-06-15 08:27:31 +00:00
frohlich c75270a9fc Use function argument in va_start instead of local variable. 2006-06-15 06:14:46 +00:00
frohlich 1588a379eb Remove now unused function 2006-06-11 13:59:59 +00:00
frohlich 72d2075828 Modified Files:
simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx simgear/scene/tgdb/leaf.cxx
	simgear/scene/tgdb/obj.cxx
	Attach userdata to groundtile scenegraph leafs that contains
	a SGMaterial reference to the material of that leaf.
	Add (physical) material properties to the material definitions.
	Plug a memory leak with GlyphSigns.
2006-06-11 13:30:59 +00:00
frohlich e99c682637 Preliminary material lookup hooks - still unoptimized. 2006-06-08 05:54:23 +00:00
mfranz c815f70831 whoops, sorry (Yes, it *was* tested, but then I made another "trivial"
change and ...)
2006-05-24 10:16:09 +00:00
mfranz 0da50eaa79 if we are going to die we better tell all our listeners 2006-05-24 09:37:44 +00:00
mfranz b0af84a549 add optional position argument to SGRoute::add_waypoint(). Default is -1,
which appends the WP like it used to. Valid vector indices insert the WP
at this position.
2006-05-08 11:31:16 +00:00
fredb b9631e8521 Mac fix 2006-05-04 05:58:59 +00:00
fredb f664f7a201 Fix the initial texture path problem. Loaders are setting the one given to ssgLoad as the default one behind our back :-( 2006-04-29 08:09:51 +00:00
fredb f72b3882c3 Redefine the default PLIB loader behavior : don't clear the texture cache after every model load 2006-04-28 18:05:46 +00:00
mfranz ea47a2973c add method to delete any waypoint (last waypoint if n is out of range) 2006-04-28 15:43:13 +00:00
frohlich 04be9ca670 Pigeons remaining fix for the soundmanager crashes. 2006-04-25 18:47:37 +00:00
mfranz 6f0baf6ca9 thanks to Erik's texture map I can now drop empty.rgb altogether and just
specify the same texture in the "foo.lighted" and "foo.unlighted" material
entry. This also allows to drop the state cloning and thereby solves the
most urgent apt_signs.cxx TODO. :-)
2006-04-22 13:41:06 +00:00
ehofman 1f5ec6b8d5 Add a texture cache mechanism. Fortunately this oly seems affective for empty.rgb ... 2006-04-22 09:38:14 +00:00
mfranz a2a91520aa don't allow new command name to overwrite material name 2006-04-20 17:46:40 +00:00
mfranz fd7b5d3de7 - don't use hard-coded emission values for unlighted signs, but load both
states from material.xml (separate <material> entries for now)
- clone state less often: not once per sign element, but once per material
  switch (TODO: clone only once per material)
2006-04-20 16:06:00 +00:00
mfranz 30ea844c43 fix "unknown.rgb" path (the wrong path was the reason why we always only
got plib's lowres red-white chequer-board pattern along with an error
message, and not ours ... which is much prettier, but also bigger.
(Should we downscale it?)
2006-04-20 15:20:40 +00:00
mfranz efac53b121 make headers include headers they depend on, don't rely on the c(xx)
file to do that. (This is a requirement for header precompiling.)
2006-04-17 11:29:01 +00:00
mfranz 73c0ef59c1 rename OBJECT_TAXI_SIGN to OBJECT_SIGN. This isn't about taxi signs any
more, but all sorts of signs. Now is the best time to get rid of a
misleading name.
2006-04-14 14:50:08 +00:00
mfranz 7e65ab2d3b add <condition> support to textranslate & texrotate animation 2006-04-12 20:27:38 +00:00
mfranz fec769f632 set sign orientation such, that when the sign heading=0, one looks straight
on the sign face when looking North
2006-04-12 12:13:03 +00:00
mfranz 90e42642b6 lower signs 2006-04-11 23:04:24 +00:00
mfranz 9d9610a882 add minimalistic backside to signs as a temporary solution 2006-04-11 21:32:15 +00:00
mfranz 1fc81f4b66 re-add hard-coded vertical distance. The coordinates should be surface
points and not add this distance, which depends on the sign housing/hardware,
after all.
2006-04-11 17:34:17 +00:00
mfranz 4f0b1e847c - commands do now have to start with @
- add commands @size, @material, @light
- make "BlackSign" texture default
- make @B, @R, @L, @Y open close their frames automatically (this can be
  avoided by setting the @material manually)
- add number variants for those 4 sign commands: @Y2, @B5, etc (according
  to the spec; defaulting to the respective biggest panel size, i.e. @B = @B3)
(detailed description will be added to $FG_ROOT/Docs/)
2006-04-11 15:57:08 +00:00
mfranz 9567ac32f2 remove obsolete files (on request by Christian Mayer, who has introduced them):
- they are not used anywhere in sg/fgfs
- and are very clearly *not* GPL compatible!
2006-04-10 16:36:52 +00:00
andy 8dd9cfa2a6 Manabu Nishiyama (non-FlightGear Nasal user) discovered an
uninitialized data bug in naHash_cget().  When the hashcode field of
naStr was introduced, I forgot to set it in this function, which
creates a temporary naStr on the stack.
2006-04-10 16:21:17 +00:00
mfranz dbda8ef893 drop xscale member again, and use xsize/ysize instead. (One interface
element less to confuse people.)
2006-04-10 15:32:55 +00:00
mfranz cd143c15d5 rewrite of OBJECT_TAXI_SIGN code. The name is a bit misleading, as this
type can also create runway signs. (/me thinks about changing that ...)
2006-04-09 19:51:00 +00:00
mfranz 509a388ccc support for font textures. They are normal (but rather lenghty) <material>,
but contain <glyph> entries with <name>, <left> and <right>. The latter two
describe where in the texture a letter or symbol begins and where it ends.
(range 0-1). <xscale> defines a horizontal scaling factor.
2006-04-09 19:21:13 +00:00
94 changed files with 1953 additions and 2036 deletions
+1
View File
@@ -2,6 +2,7 @@ EXTRA_DIST = \
acinclude.m4 \
autogen.sh \
DoxygenMain.cxx \
project/VC8 \
README.MSVC \
README.zlib \
projects \
+3 -3
View File
@@ -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
View File
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../AL/include;&quot;../../../zlib-1.2.3&quot;;&quot;../../../Pre-built.2/include&quot;"
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;&quot;../../../zlib-1.2.3&quot;;&quot;../../../Pre-built.2/include&quot;"
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"
>
+6
View File
@@ -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
+3
View File
@@ -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;
+7 -1
View File
@@ -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();
+3
View File
@@ -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>
-1
View File
@@ -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>
+2
View File
@@ -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>
+4
View File
@@ -1,3 +1,7 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <unistd.h>
+73 -61
View File
@@ -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];
}
}
+2 -5
View File
@@ -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)
+31
View File
@@ -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
View File
@@ -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
View File
@@ -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
-6
View File
@@ -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.
-3
View File
@@ -26,7 +26,4 @@
template<typename T>
class SGLimits : public std::numeric_limits<T> {};
typedef SGLimits<float> SGLimitsf;
typedef SGLimits<double> SGLimitsd;
#endif
+5 -2
View File
@@ -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
+52
View File
@@ -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
+6 -6
View File
@@ -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())
-7
View File
@@ -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)
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
-291
View File
@@ -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;
}
-116
View File
@@ -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
-110
View File
@@ -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
-540
View File
@@ -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];
}
//---------------------------------------------------------------------------
+9 -11
View File
@@ -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
View File
@@ -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
-78
View File
@@ -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
-172
View File
@@ -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
View File
@@ -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:
+1 -1
View File
@@ -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 {
+4 -2
View File
@@ -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
View File
@@ -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)
+4 -3
View File
@@ -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
View File
@@ -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;
+3 -3
View File
@@ -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();
+9 -7
View File
@@ -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
View File
@@ -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 );
}
/**
+68 -5
View File
@@ -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
View File
@@ -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
+187 -45
View File
@@ -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();
}
+2
View File
@@ -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 );
};
+2
View File
@@ -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 \
+89 -55
View File
@@ -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)
+31 -24
View File
@@ -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;
-4
View File
@@ -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 )
{
+2
View File
@@ -5,6 +5,8 @@
#ifndef _SG_CUSTOM_TRANSFORM_HXX
#define _SG_CUSTOM_TRANSFORM_HXX 1
#include "plib/ssg.h"
class SGCustomTransform : public ssgBranch
{
public:
+5
View File
@@ -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:
+32 -2
View File
@@ -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);
+2
View File
@@ -10,6 +10,8 @@
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <vector>
#include <set>
-18
View File
@@ -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.
+26 -1
View File
@@ -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 )
{
+4 -2
View File
@@ -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;
+14
View File
@@ -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 );
}
+48
View File
@@ -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
+15
View File
@@ -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
+2
View File
@@ -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; }
+9
View File
@@ -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
-2
View File
@@ -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>
+4
View File
@@ -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>
+1 -2
View File
@@ -102,8 +102,7 @@ SGBbCache::SGBbCache(void) :
}
SGBbCache::~SGBbCache(void) {
if(rt)
delete rt;
delete rt;
freeTextureMemory();
}
+3 -1
View File
@@ -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;
+1
View File
@@ -28,6 +28,7 @@
#define _SG_CLOUD_HXX_
#include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <plib/ssg.h>
+5
View File
@@ -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
View File
@@ -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;
}
+22 -9
View File
@@ -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(); }
};
+3 -4
View File
@@ -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 );
+3 -1
View File
@@ -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,
+299 -67
View File
@@ -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 ) );
+3 -3
View File
@@ -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
+1
View File
@@ -250,6 +250,7 @@ ssgLeaf *sgMakeLeaf( const string& path,
// lookup the state record
leaf->setUserData( new SGMaterialUserData(mat) );
leaf->setState( state );
if ( calc_lights ) {
+1
View File
@@ -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 );
+77 -3
View File
@@ -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;
+8
View File
@@ -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
-4
View File
@@ -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 )
+4
View File
@@ -1,3 +1,7 @@
#include <simgear/compiler.h>
#include SG_GL_H
class GlBitmap
{
public:
+3
View File
@@ -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
-3
View File
@@ -25,9 +25,6 @@
# include <windows.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <plib/ssg.h>
#include "jpgfactory.hxx"
+2
View File
@@ -27,6 +27,8 @@
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <jpeglib.h>
#include <jerror.h>
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -22,7 +22,7 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
# include <simgear_config.h>
#endif
#include "ssgEntityArray.hxx"
+1 -1
View File
@@ -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>
+3
View File
@@ -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);
+11 -1
View File
@@ -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 ) {
+8 -10
View File
@@ -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
View File
@@ -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;
}
}
-6
View File
@@ -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;};
};
+21
View File
@@ -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();
}
+2 -10
View File
@@ -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
}
+1 -5
View File
@@ -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)