Compare commits

...

551 Commits

Author SHA1 Message Date
mfranz
46a32dd3ee coding style fixes 2007-07-22 13:58:26 +00:00
mfranz
ecb4dc57b4 Maik JUSTUS: workaround for broken Doppler effect in OpenAL
mf: this patch is meant to be removed as soon as OpenAL got fixed. (The
    OpenAL developers acknowleged the bug and announced that it'll get
    fixed.) For removal try
    $ cd simgear/sound
    $ cvs diff -rAFTER_OPENAL_DOPPLER_WORKAROUND -rBEFORE_OPENAL_DOPPLER_WORKAROUND|patch
2007-07-22 13:50:24 +00:00
mfranz
89d426470b Maik JUSTUS: Doppler fixes (add option to turn off Doppler for sounds that
shouldn't be affected -- marker beep, ATIS messages, etc.)

mf: this is the first part of the original patch. It is supposed to contain
    fixes that are not caused by OpenAL bugs, and thus aren't meant to be
    reverted later. The second part will contain a temprary workaround for
    OpenAL bugs. Unfortunately, I had to do the split myself as the contributor
    refused to do it.
2007-07-22 13:33:23 +00:00
mfranz
23c7a1b5b7 - close loophole through which one could sneak in illegal property names
containing slashes, colons and all sorts of evil characters. In Nasal
  this could be done via props.globals.getChild("1!@#$//[]{}", 0, 1).setValue(0);
  The cause is that getChild() hands the given name directly over to an
  alternative SGPropertyNode ("convenience") constructor which sets the
  name without any checks.
- unify exception messages: first character is lower case
2007-07-17 14:52:51 +00:00
frohlich
3b21e9434f Modified Files:
simgear/route/route.hxx: Remove unused include.
2007-07-08 08:43:40 +00:00
frohlich
d4a4428e64 Modified Files:
simgear/route/waypoint.hxx simgear/route/waypoint.cxx: Use const
	refs where possible.
2007-07-08 08:43:15 +00:00
mfranz
2dfc057135 replace exit() by throw sg_exception(). Of course, we have to be aware
that interdependencies between sg libs are generally unwelcome, but
sg_exception is a rather basic part, and it's already used by xml, props,
scene, sound and, of course, structure. Since props and xml are core
libs, we can assume that sg_exceptions are available.  (OK'ed by Curt)
2007-07-02 15:42:19 +00:00
mfranz
a25eebef9b add SG_ORIGIN macro that expands to a string __FILE__":"__LINE__
Note that __LINE__ is a number and can't be directly used in string
context, which makes the macro worthwhile. (IMHO :-)
2007-07-02 12:55:10 +00:00
mfranz
741c4ca15a back out last changes (radar patch) 2007-06-29 22:45:37 +00:00
mfranz
0bcdf2e4dc easyxml.cxx: add missing endXML visitor call
testEasyXML.cxx: beef it up
2007-06-29 10:46:52 +00:00
mfranz
cd5a720211 Vivian MEAZZA: add support for aircraft radar signatures 2007-06-24 08:09:07 +00:00
mfranz
5cb04946b0 don't only complain that the volume is larger than 1.0, but say how much
it actually is
2007-06-23 16:48:01 +00:00
mfranz
c8953c6275 Maik JUSTUS: fix/implement directional sound 2007-06-21 21:46:21 +00:00
mfranz
e8dc9c9454 d'oh ... beautify the TRACE message that we actually see! :-} 2007-06-19 18:22:32 +00:00
mfranz
a0c325681f beautify TRACE message 2007-06-19 18:11:06 +00:00
mfranz
8d3bf19422 sooner than planned: fix "scale" animation offsets (1 -> 0) 2007-06-17 21:01:40 +00:00
fredb
4477867ef4 Update MSVC 7.1 projects 2007-06-16 16:14:23 +00:00
fredb
e696c884dc MSVC 7 compilation 2007-06-16 16:13:29 +00:00
mfranz
80bcaa49e6 Nick WARNE: add file name to screenshot info line 2007-06-14 20:20:18 +00:00
mfranz
0096c1bb02 advance tracing messages from SG_INFO to SG_ALERT. If a developer has
demanded tracing, then he shouldn't get these important messages buried
in thousands of lines of meaningless bulk.
2007-06-11 16:09:50 +00:00
mfranz
38b37a068d - allow for (rather unusual) ////// cloud groups
- fix potential use of uninitialized memory: dew
2007-06-09 18:36:56 +00:00
frohlich
0281f31df2 Modified Files:
simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
	simgear/scene/util/SGSceneFeatures.cxx
	simgear/scene/util/SGSceneFeatures.hxx:
	Olaf Flebbe: Make use of SGSceneFeatues for anisotropic filtering,
	clean up.
2007-06-08 06:50:16 +00:00
frohlich
40b182c550 Removed Files:
simgear/scene/tgdb/leaf.cxx: Now obsolete but not yet removed.
2007-06-08 06:40:56 +00:00
frohlich
d1dedc7511 Modified Files:
scene/tgdb/SGOceanTile.cxx: add missing transform for the ocean
	tile.
2007-06-03 18:28:14 +00:00
frohlich
04cd9b3eb6 Modified Files:
simgear/scene/model/model.cxx
	simgear/scene/util/SGSceneFeatures.cxx
	simgear/scene/util/SGSceneFeatures.hxx:
	Make sure textures are shared. Do not rely on a graphics
	context to be available on model loading.
2007-06-03 18:21:04 +00:00
andy
de6003367d Sync with Nasal upstream. Mostly fixes to naContinue(), which
FlightGear doesn't use.  Also includes a performance fix for the
call() builtin that should help Melchior, who was measuring lower
performance for the props.Node() interface than the getprop/setprop
API.
2007-05-30 22:49:41 +00:00
frohlich
a5f42eeddf Modified Files:
projects/VC8/SimGear.vcproj: Olaf FLebbe win32 build system.
2007-05-30 13:16:53 +00:00
frohlich
a8ba041b67 Modified Files:
simgear/scene/model/SGMaterialAnimation.cxx:
	Olaf Flebbe: Use brakets around bitwise operations.
	Greetings from LinuxTag, Berlin ... :)
2007-05-30 13:07:05 +00:00
curt
e700fc6f34 I guess we aren't using explicit destructors here. 2007-05-30 12:34:24 +00:00
curt
af29d3d257 Make an explicit destructor so the compiler doesn't get confused about
non matching exception types with the implicitely defined destructor.
2007-05-29 19:38:17 +00:00
frohlich
487701a143 Modified Files:
simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
Added Files:
	simgear/scene/model/SGRotateTransform.cxx
	simgear/scene/model/SGRotateTransform.hxx
	simgear/scene/model/SGScaleTransform.cxx
	simgear/scene/model/SGScaleTransform.hxx
	simgear/scene/model/SGTranslateTransform.cxx
	simgear/scene/model/SGTranslateTransform.hxx:
	Factor out some useful classes.
2007-05-28 07:13:07 +00:00
frohlich
f32e037c58 Modified Files:
simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx:
	Olaf Flebbe: Improoved texture filtering.
2007-05-28 05:13:03 +00:00
frohlich
8bd903dd96 Modified Files:
SGAtomic.hxx: Also use atomic compiler intrinsics on SGI
2007-05-28 05:06:14 +00:00
frohlich
560c100484 Modified Files:
simgear/bucket/newbucket.cxx simgear/bucket/newbucket.hxx
	simgear/io/decode_binobj.cxx simgear/io/sg_binobj.cxx
	simgear/io/sg_binobj.hxx simgear/math/SGVec2.hxx
	simgear/math/SGVec3.hxx simgear/math/SGVec4.hxx
	simgear/scene/material/mat.hxx
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx
	simgear/scene/model/Makefile.am simgear/scene/tgdb/Makefile.am
	simgear/scene/tgdb/obj.cxx simgear/scene/tgdb/obj.hxx
	simgear/scene/tgdb/pt_lights.cxx
	simgear/scene/tgdb/pt_lights.hxx
	simgear/scene/util/Makefile.am
	simgear/scene/util/SGNodeMasks.hxx
	simgear/scene/util/SGTextureStateAttributeVisitor.cxx
Added Files:
	simgear/scene/model/SGOffsetTransform.cxx
	simgear/scene/model/SGOffsetTransform.hxx
	simgear/scene/tgdb/SGDirectionalLightBin.hxx
	simgear/scene/tgdb/SGLightBin.hxx
	simgear/scene/tgdb/SGOceanTile.cxx
	simgear/scene/tgdb/SGOceanTile.hxx
	simgear/scene/tgdb/SGTexturedTriangleBin.hxx
	simgear/scene/tgdb/SGTriangleBin.hxx
	simgear/scene/tgdb/SGVasiDrawable.cxx
	simgear/scene/tgdb/SGVasiDrawable.hxx
	simgear/scene/tgdb/SGVertexArrayBin.hxx
	simgear/scene/util/SGEnlargeBoundingBox.cxx
	simgear/scene/util/SGEnlargeBoundingBox.hxx
	simgear/scene/util/SGSceneFeatures.cxx
	simgear/scene/util/SGSceneFeatures.hxx
Removed Files:
	simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/vasi.hxx:
	Reorganize tile loaders.
	Build bigger leafs for the tiles.
	Move runway light colors into materials.xml.
	Split out classes that might be useful at other places.
	Avoid static storage on binobject loading.
2007-05-28 05:00:28 +00:00
andy
52444d177b GCC on ppc linux uses a different architecture symbol than the same compiler on OS X 2007-05-25 15:49:10 +00:00
frohlich
b4f7ff29ef Modified Files:
SGVec3.hxx: Fix a problem in perpendicular triangle computation.
	Solves problem with invalid triangles in ground picking ...
2007-05-18 07:29:37 +00:00
frohlich
f7c6a5bfa2 Modified Files:
SGVec2.hxx SGVec3.hxx SGVec4.hxx point3d.hxx: Provide ordering
	relations for use with std::less in tree bases std:: containers.
2007-05-18 04:46:11 +00:00
curt
6fe14f7a6b Fix a compiler warning. 2007-05-16 16:08:17 +00:00
curt
786e5addd8 Fix various compiler warnings. 2007-05-16 16:07:03 +00:00
mfranz
2e9a15f523 Tim Moore 2007-05-15 22:28:08 +00:00
mfranz
bb0d2ddc53 add Mathias and Maik (to make it look less selfish that I add myself :-)
I'm sure I forgot a lot of people, but it's a start.
2007-05-15 22:02:06 +00:00
mfranz
702fb014a5 s/resistence/resistance/ 2007-05-13 11:53:06 +00:00
frohlich
834eab9457 Modified Files:
simgear/bucket/newbucket.hxx simgear/scene/material/mat.cxx
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx
	simgear/scene/model/location.cxx
	simgear/scene/tgdb/apt_signs.cxx simgear/scene/tgdb/leaf.cxx
	simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
	simgear/scene/tgdb/obj.hxx
	simgear/scene/util/SGUpdateVisitor.hxx: Reorganize scenegraph to
	simplify top level structure.
2007-05-08 06:11:15 +00:00
mfranz
a85da04601 Add method to return the number of attached listeners. Listeners have become
a much more important feature than they were two years or something ago, and
it's helpful for debugging and exploration to get this important node property
shown in property tree dumps or in the property browser (verbose mode).
2007-05-07 14:03:44 +00:00
mfranz
414f1c27e4 - fix bug where a property tree saved with writeProperties() and read back
in with readProperties() would not look the same, because element indices
  of '0' were even dropped when a node has a "secret" value *and* children

- introduce "omit-node" modifier attribute for the "include" attribute.
  This inserts the given file in place of the including node, while the
  node is dropped. This is desirable for multiple includes (which can't
  be done by multiply using the "include" attribute, as this isn't valid
  XML spec syntax)
2007-05-06 17:33:15 +00:00
mfranz
c76e2eb900 better warning text for <global> in material animations 2007-05-05 11:16:35 +00:00
frohlich
c523e15302 Modified Files:
SGMaterialAnimation.cxx SGMaterialAnimation.hxx:
	Tim Moore: overhaul the material animation.
2007-05-05 09:15:18 +00:00
frohlich
2dc8de295d Modified Files:
simgear/scene/model/animation.hxx
	simgear/scene/model/shadanim.cxx: Tim Moore: the crom shader.
2007-05-03 19:46:13 +00:00
andy
d645fd6327 Empty vectors work much better as the result of sorting an empty array
than nil does...
2007-05-02 22:29:35 +00:00
andy
219a7f3a07 Fix crash when sorting newly-allocated empty vectors 2007-05-02 22:24:45 +00:00
mfranz
d95e3e0055 don't rely on a compressed scanline being properly closed
(GIMP apparently generates corrupted files)
2007-04-28 23:13:13 +00:00
mfranz
2cc31ff425 SGTexture::read_rgb(a)_texture:
- support greyscale and greyscale/alpha format
- cleanup & make it faster
2007-04-28 12:30:38 +00:00
frohlich
8258fd7d9f Modified Files:
projects/VC8/SimGear.vcproj: Olaf Flebbe: Updates to the win32
	build system.
2007-04-21 12:24:43 +00:00
frohlich
784cca2233 Modified Files:
simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx:
	Olaf Flebbe: make anisotroüpic filtering configurable.
2007-04-21 12:13:16 +00:00
andy
436539a700 Melchior found a bug with negative values in default function arguments 2007-04-06 20:35:38 +00:00
andy
dcb3da9f28 sync with Nasal CVS (added a sort() builtin) 2007-04-06 14:52:06 +00:00
mfranz
a354c841f1 Csaba HALASZ:
- fix bug that messed up leg distances after inserting and deleting waypoints
  not at the end of the route
- move add_waypoint() and delete_waypoint from hxx to cxx
- beef up routetest
2007-04-06 09:54:35 +00:00
fredb
3824f064cd Update MSVC 7.1 projects 2007-04-03 11:35:19 +00:00
fredb
cba6db752b Avoid potential memory leak problems when exceptions are thrown by using reference objects 2007-04-03 11:25:07 +00:00
andy
a458e26581 Fix typo in _M_IX86 2007-04-02 21:32:41 +00:00
andy
9d68727a84 Rewrite substr() to properly clamp its argument ranges and handle negative start arguments as offset-from-end values 2007-04-02 18:28:38 +00:00
andy
38b9a874e0 Add missing free functions for win32 2007-04-02 17:34:47 +00:00
andy
7a680fb9f2 Use __FUNCTION__, which works on gcc and MSVC 7/8, instead of
__func__, which while standardized works only with gcc.  I'll wait for
bug reports from VC6 before bothering with fallback code...
2007-04-02 16:14:54 +00:00
andy
a5f9262adb Melchior points out that NaN/Inf behavior is not platform-independent.
So toss a runtime error ("floating point error") when any of the math
library functions produce a non-finite value.  Note that these are not
the only locations that can do that (simply dividing by zero will
produce an Inf), but it's still proper behavior.
2007-03-30 16:42:22 +00:00
andy
b05e32fa8c Sync with Nasal CVS (soon to become Nasal 1.1). Notable new features:
Nasal now supports calls to "subcontexts" and errors can be thrown
across them, leading to complete stack traces when call() is used,
instead of the truncated ones we now see.

Vectors can now be concatenated using the ~ operator that used to work
only for strings.

Better runtime error messages in general due to a fancier
naRuntimeError() implementation

A big data size shrink on 64 bit systems; the size of a naRef dropped
by a factor of two.

"Braceless code blocks" have been added to the parser, so you can
write expressions like "if(a) b();" just like in C.  Note that there's
still a parser bug in there that fails when you nest a braced block
within a braceless one.

Character constants that appear in Nasal source code can now be
literal multibyte UTF8 characters (this was always supported for
string literals, but character constants were forced to be a single
byte).

New modules: "bits", "thread", "utf8" and (gulp...) "io".  The bits
library might be useful to FlightGear, the utf8 one probably not as
Plib does not support wide character text rendering.  The thread
library will work fine for spawning threads to do Nasal stuff, but
obviously contact with the rest of FlightGear must be
hand-synchronized as FlightGear isn't threadsafe.  The io library is
no doubt the most useful, as it exposes all the basic stdio.h
facilities; it's also frighteningly dangerous when combined with
networked code...
2007-03-29 18:50:12 +00:00
mfranz
53d8cff835 Csaba HALASZ: when a path_cache ceases to exist, unregister from all nodes
that had been told that this node is linking to them

mf: remove old erase-by-key methods; they are now unused and always were
    problematic, so they won't be used in the future either
2007-02-17 10:50:49 +00:00
mfranz
00fe97ff88 - don't leak node in both hash_table:🪣:erase()
- remove bad code from hash_table:🪣:erase(const char *) that was
  introduced with the last patch. (This function isn't used anywhere and
  is scheduled for removal. Leaving it in for now as a reference.)
- remove leaves first in remove_from_path_caches()

- cosmetics: indentation, one trailing space, variable name change, comment
  (Sorrry for mixing that with actual code, but I think it's easy to see.)
2007-02-16 15:32:21 +00:00
andy
607511fd64 Don't crash when destroying a SGBinding object if the property node it
was loaded from lacks a parent.  Patch from ndim on IRC
2007-02-14 23:14:00 +00:00
mfranz
8663c265d8 Maik JUSTUS:
"""
- make every node maintain list of properties that link to it
- add functions to erase node by address from hash bucket/entry in their
  path caches, so that all references can be removed
- if a node is removed, it (and all children, grandchildren, ...) calls
  all linked properties to remove them from their path-cache


This fixes problems with the aerotow over multiplayer and maybe some
other problems, where nodes are queried by name.
"""
2007-02-11 11:05:23 +00:00
andy
6c5d35d6ce "bias" argument to texture animations by Ron Jensen 2007-02-07 19:21:24 +00:00
mfranz
95532cb318 fix error message 2007-02-05 21:41:40 +00:00
frohlich
4d91bc5908 Modified Files:
ephemeris.cxx ephemeris.hxx stardata.cxx:
	one must not do changes just before checkin,
	one most not do changes just before checkin,
	[ last message repeated 100 times ]
2007-02-02 18:16:42 +00:00
frohlich
b13900402d Modified Files:
ephemeris.cxx ephemeris.hxx stardata.cxx stardata.hxx: Throw out sg.h
2007-02-02 18:09:27 +00:00
frohlich
1bb6c03bd0 Modified Files:
simgear/scene/util/SGNodeMasks.hxx
	simgear/scene/model/animation.cxx:
	More finegrained cull masks
2007-02-02 07:00:54 +00:00
frohlich
1445949e31 Modified Files:
projects/VC8/SimGear.vcproj: Olaf Flebbe: renenable static build
2007-01-31 21:40:59 +00:00
frohlich
360d3834ca Modified Files:
SGIntersect.hxx SGVec3.hxx SGVec4.hxx: Add convinience methods
2007-01-30 20:12:15 +00:00
fredb
aacdcad529 restore 'double checked locking' 2007-01-29 08:19:13 +00:00
frohlich
ad9341835f Modified Files:
model.cxx: Better texture sharing, fix problem with rotation order
2007-01-28 20:04:56 +00:00
frohlich
b028adb6af Modified Files:
simgear/structure/SGAtomic.cxx: Plug memory leak originating from
	wrong atomic fallback operations.
2007-01-28 20:03:43 +00:00
fredb
39f683b272 Ensure a reference on the cube map texture is always held 2007-01-26 20:30:02 +00:00
ehofman
a6c46c89eb *** empty log message *** 2007-01-23 10:07:36 +00:00
fredb
d534cf6f02 Better fix for the constant scale factor problem 2007-01-21 11:15:36 +00:00
fredb
dd4326f7c4 Support constant scaling factor 2007-01-21 10:33:34 +00:00
fredb
40aecd688e Don't segfault when dir is empty 2007-01-16 21:34:18 +00:00
frohlich
63730a6e2c Modified Files:
animation.cxx: Add a visible configuration option to the pick
	animation.
2007-01-15 19:01:20 +00:00
frohlich
4d4d26aef8 Modified Files:
projects/VC8/SimGear.vcproj: Olaf Flebbe, MSVC8 buildsystem changes.
2007-01-15 17:32:17 +00:00
mfranz
de6b32d8c6 writePropeties(): create dir if necessary 2007-01-12 21:24:50 +00:00
fredb
a0af7f0524 Update MSVC 7.1 project file and fix win32 compilation 2007-01-09 21:58:04 +00:00
frohlich
c043bd3422 Modified Files:
SGSceneUserData.hxx SGSceneUserData.cxx: Remove default argument
2007-01-07 12:25:32 +00:00
frohlich
18ae1d6940 Modified Files:
animation.cxx: Change the pick animation to better handle different
	mouse buttons.
2007-01-07 11:53:21 +00:00
frohlich
d6f64f9773 Modified Files:
SGSceneUserData.hxx SGPickCallback.hxx Makefile.am
Added Files:
	SGSceneUserData.cxx: Cleanup and replace the pick callback with
	such a list.
2007-01-07 11:52:19 +00:00
frohlich
db99a4cb90 Modified Files:
animation.cxx: Add a button argument to that animation.
	The default is to accept any mouse button.
2007-01-07 08:34:03 +00:00
fredb
108689661f Add a prototype simgear_config.h for MSVC 7.1 and a rule to build it. 2007-01-06 17:01:58 +00:00
fredb
d3e00dba8e Add a prototype simgear_config.h for MSVC 7.1 and a rule to build it.
At Olaf requests, add MSVC 8 specific symbols to remove pedantic warnings
2007-01-06 16:52:50 +00:00
fredb
fcd33e5035 Remove redundant directory ( projects as a whole is already there ) 2007-01-06 16:47:57 +00:00
frohlich
af9082cd9f Modified Files:
moon.cxx: The moo's state like it was with plib
2007-01-06 15:08:40 +00:00
fredb
6a0bb18fca Refresh MSVC6 project file 2007-01-06 14:45:21 +00:00
fredb
8aa8d87781 Fix a typo 2007-01-06 14:44:54 +00:00
fredb
4998af8d7a Add SGBinding.[ch]xx to the MSVC 7.1 project 2007-01-04 22:24:23 +00:00
fredb
c6aa95f3f3 std::find is defined in <algorithm> 2007-01-04 22:23:40 +00:00
frohlich
481be29366 Modified Files:
Makefile.am animation.cxx animation.hxx: Add animation to execute
	a command on scenery pick
2007-01-04 12:55:16 +00:00
frohlich
3617b6ad8c Modified Files:
Makefile.am SGNodeMasks.hxx
Added Files:
	SGPickCallback.hxx SGSceneUserData.hxx: Preparations for generic
	scenery picking.
2007-01-04 12:52:50 +00:00
frohlich
3fb8e19a38 Modified Files:
condition.hxx: Also derive from SGReferenced
2007-01-04 12:51:13 +00:00
frohlich
2ea2f1b4f2 Modified Files:
Makefile.am commands.cxx commands.hxx
Added Files:
	SGBinding.cxx SGBinding.hxx: Move FGBinding to SGBinding
2007-01-04 12:47:12 +00:00
frohlich
26cb8ec4f1 Modified Files:
SGIntersect.hxx: Make it compile with win32
2006-12-28 13:25:14 +00:00
frohlich
7fe56bea86 Modified Files:
obj.cxx: Some kind of polygon offset for GL_POINTS.
2006-12-27 10:33:37 +00:00
frohlich
11b16b8a86 Modified Files:
Makefile.am SGReferenced.hxx
Added Files:
	SGAtomic.cxx SGAtomic.hxx:
	Make the reference counts thread safe.
2006-12-27 10:07:19 +00:00
frohlich
de020ee695 Modified Files:
Makefile.am SGMathTest.cxx SGQuat.hxx SGVec3.hxx
Added Files:
	SGBox.hxx SGGeometry.hxx SGGeometryFwd.hxx SGGeometryTest.cxx
	SGIntersect.hxx SGLineSegment.hxx SGPlane.hxx SGRay.hxx
	SGSphere.hxx SGTriangle.hxx:
	Small updates to the vector code, new geometry and collision
	classes for use with a bv tree to speed up collission tests.
	Also included is a rought unit test for the collissions.
2006-12-27 09:23:39 +00:00
ehofman
3b83487611 Wether you like it or not, MispPro needs these libraries referenced 2006-12-23 12:15:05 +00:00
fredb
09bab4f162 memcpy needs #include <string.h> 2006-12-17 17:52:15 +00:00
fredb
49fcc799ca Port jpgfactory to OSG 2006-12-16 17:29:16 +00:00
fredb
10bc803775 Project files for MSVC 7.1 aka .NET 2003 2006-12-16 13:12:48 +00:00
frohlich
4f40770fc6 Modified Files:
simgear/math/SGVec3.hxx: fix spelling
2006-12-14 05:24:16 +00:00
frohlich
a4495c6ef1 Modified Files:
simgear/scene/sky/bbcache.cxx simgear/scene/sky/bbcache.hxx
	simgear/scene/sky/cloudfield.cxx
2006-12-08 12:22:10 +00:00
frohlich
67d837c4ec Modified Files:
SGVec3.hxx: Generate any perpandicular vector to a given one.
2006-12-08 12:17:30 +00:00
frohlich
138825af6d Modified Files:
point3d.hxx: Add explicit conversion functions to SGVec*
2006-12-08 12:16:56 +00:00
frohlich
c093841336 Modified Files:
simgear/scene/model/animation.cxx: Fix a problem of muliple
	texturre transform not finding the correct configuration.
2006-12-05 06:14:41 +00:00
frohlich
2df1da4226 Return void instead of bool. 2006-12-05 05:43:13 +00:00
frohlich
2792d60e2d Modified Files:
simgear/screen/extensions.hxx: Make it compile on macos
2006-12-03 17:44:27 +00:00
frohlich
656a3ace07 Modified Files:
simgear/scene/material/mat.cxx: Put solid scenery into the
	opaque render bin
2006-12-03 17:27:46 +00:00
frohlich
aec8e88c14 Modified Files:
simgear/scene/util/SGNodeMasks.hxx: Add pickable bit
2006-12-03 17:02:40 +00:00
frohlich
bdd5ca140d Modified Files:
simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
	simgear/scene/model/model.cxx
	simgear/scene/model/persparam.cxx
	simgear/scene/model/persparam.hxx
	simgear/scene/model/shadanim.cxx
Added Files:
	simgear/scene/model/SGMaterialAnimation.cxx
	simgear/scene/model/SGMaterialAnimation.hxx
	Big animation overhaul. Improoves animation correctness.
2006-12-03 16:57:20 +00:00
frohlich
8b3b0def03 Modified Files:
SGUpdateVisitor.hxx: Include light information.
2006-12-03 16:46:23 +00:00
frohlich
6440ece177 Modified Files:
SGMisc.hxx: Add clip and periodic normalize functions.
2006-12-02 15:59:23 +00:00
frohlich
bd3518637c Modified Files:
SGVec2.hxx SGVec3.hxx SGVec4.hxx: Add inf norm function
2006-12-02 15:57:55 +00:00
frohlich
aef2a1c484 Modified Files:
interpolater.cxx interpolater.hxx: Enable reading tables directly
	from our dom like tree.
2006-12-02 15:56:55 +00:00
frohlich
a4b28e5737 Modified Files:
simgear/scene/sky/oursun.cxx: Fix the 'sun has wrong size' bug.
	Thanks to Mark Akermann.
2006-11-27 17:11:35 +00:00
frohlich
a3bc2eb836 Modified Files:
simgear/math/interpolater.cxx simgear/math/interpolater.hxx
	simgear/props/condition.cxx simgear/props/condition.hxx
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx: Optimize interpolation table
	lookup by using a std::map.
2006-11-21 18:44:54 +00:00
frohlich
3059da5805 Modified Files:
SGVec2.hxx SGVec3.hxx SGVec4.hxx: Implement min/max for vectors
2006-11-21 18:39:57 +00:00
frohlich
18d5a492c8 Modified Files:
model.cxx: Tweak model optimizations
2006-11-20 18:19:02 +00:00
frohlich
160b0ea7d9 Modified Files:
placementtrans.cxx placementtrans.hxx: Make use of that view
        information in the update visitor
2006-11-20 18:17:56 +00:00
frohlich
4dd1267bea Modified Files:
SGUpdateVisitor.hxx: Store some view imformation in the
	update visitor.
2006-11-20 18:15:34 +00:00
fredb
b5c4328682 Mac fix from Ima Sudonim 2006-11-18 18:58:51 +00:00
frohlich
571fc69ef4 Modified Files:
VC8/SimGear.vcproj: Import buildsystem from Olaf Flebbe
2006-11-14 21:15:20 +00:00
frohlich
f51595cfc9 Modified Files:
animation.hxx animation.cxx: Improove material/texture/blend animation
2006-11-14 21:09:44 +00:00
frohlich
d54aea0036 Modified Files:
animation.cxx animation.hxx: Fix crash on A-10 load
2006-11-12 10:32:42 +00:00
frohlich
51bb2974bc Modified Files:
model.cxx: Leave it to osg when to do mipmapping.
2006-11-12 07:28:59 +00:00
frohlich
7a859061fd Modified Files:
model.cxx: Reset the database path past the whole model is loaded
2006-11-12 07:23:42 +00:00
frohlich
cefa9fcd75 Modified Files:
SGQuat.hxx: Make const method const
2006-11-12 07:22:44 +00:00
frohlich
d3bacd0b73 Modified Files:
simgear/scene/material/mat.cxx
	simgear/scene/material/matlib.cxx simgear/scene/sky/cloud.cxx
	simgear/scene/sky/dome.cxx simgear/scene/sky/moon.cxx
	simgear/scene/sky/oursun.cxx simgear/scene/sky/sphere.cxx
	simgear/scene/sky/stars.cxx simgear/scene/tgdb/apt_signs.cxx
	simgear/scene/tgdb/leaf.cxx simgear/scene/tgdb/leaf.hxx
	simgear/scene/tgdb/obj.cxx simgear/scene/tgdb/pt_lights.cxx
	simgear/scene/util/SGDebugDrawCallback.hxx
	simgear/screen/Makefile.am: Use color arrays for every geode.
	Just use osg::Material instead of osg::Material and the associated
	mode.
2006-11-10 05:30:37 +00:00
frohlich
b94a98fc90 Modified Files:
scene/model/model.cxx: Next step in direction liveries
2006-11-09 05:42:06 +00:00
fredb
e0b2687231 copysign is already in compiler.h 2006-11-07 21:31:17 +00:00
frohlich
cc6179a4dd Modified Files:
simgear/screen/extensions.cxx simgear/screen/extensions.hxx: Avoid
	the assumption that with glx-1.4 glXGetProcAddress is available -
	use dlsym to get that function.
2006-11-07 17:49:36 +00:00
fredb
e947bac4a3 This class is for plib only 2006-11-07 07:22:48 +00:00
frohlich
11ecbb6ca7 Modified Files:
mat.cxx: Fix dark scenery problem.
2006-11-07 06:40:35 +00:00
frohlich
322789cd4c Modified Files:
simgear/Makefile.am: Make 'make distclean' work
2006-11-07 06:02:47 +00:00
frohlich
f28464dba0 Modified Files:
projects/VC8/SimGear.vcproj: Olaf Flebbe: updated project files
2006-11-07 05:55:46 +00:00
frohlich
8f6456b1f8 Modified Files:
simgear/scene/util/SGUpdateVisitor.hxx: Only traverse active
	children.
2006-11-07 05:47:00 +00:00
frohlich
1f32786c82 Modified Files:
simgear/scene/util/SGDebugDrawCallback.hxx
	simgear/math/SGQuat.hxx: Olaf Flebbe: Make it compile on some more
	win32 variants.
2006-11-07 05:46:25 +00:00
fredb
829c729ee9 Don't try to load textures when no name is given 2006-11-06 21:59:02 +00:00
fredb
5d3aacb892 Attempt to fix the APIENTRY problem. It looks like a problem in OSG, or a conflict between OSG and plib/pui 2006-11-03 18:08:46 +00:00
fredb
741e9c5ed5 For some reason I don't know yet, the APIENTRY stuff in osg/GL is broken for some files. Include the real windows.h until we find why. 2006-11-03 10:04:58 +00:00
fredb
1408c1b623 add copysign definition for MSVC 2006-11-03 09:57:02 +00:00
fredb
c256f8d09e Win32 compilation fix 2006-11-02 17:40:54 +00:00
frohlich
55c018c525 Modified Files:
SGMath.hxx: Attempt to help IRIX builds
2006-11-02 13:37:23 +00:00
frohlich
3fa94b5143 Modified Files:
projects/VC8/SimGear.sln projects/VC8/SimGear.vcproj: Import Olafs
	project files
2006-11-02 06:15:14 +00:00
frohlich
5127e2f89c Modified Files:
Makefile.am SGMath.hxx SGMathFwd.hxx SGMatrix.hxx SGQuat.hxx
Added Files:
	SGVec2.hxx
	Improove the matrix functions. Improove the quaterion functions.
	Add the 2d vector.
2006-11-01 21:25:21 +00:00
mfranz
3175fa3aca + .deps/ 2006-11-01 21:24:24 +00:00
frohlich
5614174b39 Modified Files:
simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
	simgear/scene/model/modellib.cxx
	simgear/scene/model/modellib.hxx
Removed Files:
	simgear/scene/model/personality.cxx
	simgear/scene/model/personality.hxx:
	Updates to the animation system.
	Personality can be implemented easier now
2006-10-31 06:26:50 +00:00
frohlich
39fc52fe0a Modified Files:
Makefile.am SGStateAttributeVisitor.hxx
 	SGTextureStateAttributeVisitor.hxx
Added Files:
	SGStateAttributeVisitor.cxx SGTextureStateAttributeVisitor.cxx:
	Move implementation into cxx files
2006-10-31 06:14:38 +00:00
frohlich
81188705b1 Modified Files:
simgear/math/SGQuat.hxx: Initialize with zero not with null pointer
2006-10-31 05:37:45 +00:00
frohlich
63c4873d8a Modified Files:
simgear/screen/extensions.cxx simgear/screen/extensions.hxx:
	use glXGetProcAddress if approriate
2006-10-31 05:36:50 +00:00
frohlich
1a85dcd890 Modified Files:
simgear/timing/timestamp.hxx: Remove reimplemented default
	implementations
2006-10-31 05:33:48 +00:00
frohlich
27470fc504 Modified Files:
configure.ac: Add a configure flag for osg
2006-10-30 19:56:09 +00:00
mfranz
65d18445d3 Makefile(.in) 2006-10-29 20:08:27 +00:00
frohlich
84dd54b33a Modified Files:
configure.ac simgear/environment/visual_enviro.cxx
	simgear/ephemeris/ephemeris.cxx
	simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
	simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
	simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
	simgear/math/SGVec4.hxx simgear/scene/Makefile.am
 	simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx
	simgear/scene/material/matmodel.cxx
	simgear/scene/material/matmodel.hxx
	simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
	simgear/scene/model/custtrans.hxx
	simgear/scene/model/model.cxx simgear/scene/model/model.hxx
	simgear/scene/model/modellib.cxx
	simgear/scene/model/modellib.hxx
	simgear/scene/model/personality.cxx
	simgear/scene/model/personality.hxx
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
	simgear/scene/model/placementtrans.cxx
	simgear/scene/model/placementtrans.hxx
	simgear/scene/model/shadanim.cxx
	simgear/scene/model/shadowvolume.hxx
	simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
	simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
	simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
	simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
	simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
	simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
	simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
	simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
	simgear/scene/tgdb/apt_signs.cxx
	simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
	simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
	simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
	simgear/scene/tgdb/pt_lights.hxx
	simgear/scene/tgdb/userdata.cxx
	simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
	simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
	simgear/structure/Makefile.am simgear/threads/SGThread.hxx
Added Files:
	simgear/scene/util/Makefile.am
	simgear/scene/util/SGDebugDrawCallback.hxx
	simgear/scene/util/SGNodeMasks.hxx
	simgear/scene/util/SGStateAttributeVisitor.hxx
	simgear/scene/util/SGTextureStateAttributeVisitor.hxx
	simgear/scene/util/SGUpdateVisitor.hxx
Removed Files:
	simgear/screen/ssgEntityArray.cxx
	simgear/screen/ssgEntityArray.hxx
	simgear/structure/ssgSharedPtr.hxx
	Big BLOB on the way to OSG.
2006-10-29 19:27:08 +00:00
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
curt
76c6482495 v0.3.10 changes. 2006-04-05 18:42:45 +00:00
mfranz
010a44f831 protect ssg pointers to avoid occasional crashes (of course it would be
nicer if the Occluder would always get removed before its model branch,
but that's not easily enforcable)
2006-03-30 14:13:22 +00:00
curt
e6b0d644d4 v0.3.10-pre3 updates. 2006-03-27 18:48:36 +00:00
curt
02dc68c899 Olaf Flebbe:
Unfortunatly the original SimGear Project I submitted contained local
changes which I didn't intend to submit. Please use this file instead...
2006-03-27 16:32:15 +00:00
mfranz
11ac97cd09 If the author of this message isn't alerted enough to *fix* this, then I'm
sure the users won't do that either. This is regularly triggerd and leads
to meaningless error reports.
2006-03-26 08:22:26 +00:00
mfranz
61f6565321 more guarded pointers (we are still getting spurious crashes on exit because
of that)
2006-03-24 23:24:20 +00:00
curt
55d951f211 Initial revision. 2006-03-24 19:06:05 +00:00
mfranz
143ce6fcd5 remove so that complete dir can be dropped 2006-03-23 22:05:22 +00:00
curt
e264c6ad2e Updates to remove unneeded and old version of zlib source. 2006-03-23 21:59:59 +00:00
curt
036b6785f1 Remove old depricated files. There is a much newer version of zlib
available and just about every unix-based platform already comes with this.
2006-03-23 21:52:03 +00:00
curt
caf5cc90ae v0.3.10-pre2 updates. 2006-03-23 16:37:35 +00:00
mfranz
b05e98b1b6 Vassilii KHACHATUROV: rain fix, cleanup, read formerly hard-coded values
from provided node

"* minor redundant gl call in DrawCone2 optimized away (twice per frame)
* corrected the glRotatef() order in drawRain even further (a less
obvious mistake than before, which is noticed by looking skywards and wiggling
the mouse in the view direction change mode)
* all the "magic numbers" used in the rain rendering code have been
provided a default (based on the old hardcoded value) in a form of a
define, and a meaningfully named static member in SGEnviro"
2006-03-23 15:39:00 +00:00
mfranz
31d0779377 Vassilii KHACHATUROV: fix typos, add/fix comments, change variable names 2006-03-22 16:02:55 +00:00
andy
6b056e915e Oops, implement the previously-mentioned fix without breaking support
for omitting a length argument to mean "the rest of the vector".
2006-03-21 23:12:30 +00:00
andy
9d6c0dc580 The original code (rather oddly) interprets a length of zero in
subvec() to mean "the whole vector".  Melchior showed a use case
(removal of the first element from a vector) where getting a
zero-length subvector is actually desired.  And since I can't come up
with a good reason for why the "feature" was there in the first place,
out it goes...
2006-03-21 22:22:47 +00:00
andy
6e973e07f4 Melchior discovered that cmp() was just wrong, failing to actually
inspect the string pointers.  It also failed to properly sort strings
where one is a prefix of the other.  It looks to me like I just never
finished this, and it ended up in CVS because it just happened to
compile...
2006-03-21 21:57:00 +00:00
curt
c8098b9eac Updates for v0.3.10-pre1. 2006-03-20 19:22:20 +00:00
mfranz
ed20ce388a - better error message when submodel loading failed
- use alignmainmodel node in callback (not used anywhere yet)
2006-03-17 19:01:52 +00:00
andy
33e01e431d The handle gets nulled out if the user has closed the file; don't pass that
null to fclose() in a garbage collection destructor too...
2006-03-16 18:01:56 +00:00
andy
7d631e4959 Fix broken checkin in iolib.c. Also add the 'bits' library, which has a buf()
function needed to make convenient use of io.read().
2006-03-15 19:42:37 +00:00
andy
29eb566448 Melchior found the first bug -- report EOF as nil in readln(). 2006-03-15 19:35:30 +00:00
andy
a770d2a972 Add the Nasal I/O library so Melchior can play with it. Not enabled currently (see NasalSys.cxx in the flightgear CVS) 2006-03-15 18:09:50 +00:00
mfranz
688cffb031 --warnings 2006-03-14 15:55:24 +00:00
mfranz
2cccc26541 --warnings 2006-03-14 15:49:29 +00:00
mfranz
f96f083bb5 close zone.tab file after having read all entries 2006-03-14 12:58:28 +00:00
mfranz
2e078aff7d prevent animations from losing nodes, because other processes removed them
(We are currently getting a lot of aborts in the condition code when
running MP. I don't expect this to fix it, but a bug is a bug.)

(reviewed by Fred, who also fixed *my* bugs :-)
2006-03-14 10:38:06 +00:00
mfranz
bd1f192dc4 Better use a node that is very clearly not used by other services
(e.g. animations). The data class doesn't mind.
2006-03-12 18:56:48 +00:00
mfranz
b62f241051 activate model load/unload callback again. It turned out *not* to be the
cause for the MP crashes -- the same crashes did still occur without it.
2006-03-12 10:09:34 +00:00
ehofman
95d1ac354e Mac OS X fixes from Ima Sudonim. 2006-03-11 22:20:19 +00:00
mfranz
54728f5d57 commenting out Nasal in scenery models for now. This could be responsible
for an MP/AI crash. Still investigating.
2006-03-10 22:58:24 +00:00
mfranz
d9356b0f86 warning-- 2006-03-09 16:17:35 +00:00
ehofman
6b68d9d90b Alexander Powell:
Add MAC OS X Render Texture support:

Most texture modes seem to work on my Powerbook, but I don't have a wide array
of machines to test it on otherwise.

If you have problems, please let me know and I'll see if I can help track down
the source of the bug.  I'd love to keep working on it if time permits (I use
RenderTexture in a few other projects), so I'll keep you informed if there are
any changes that I make for the better.
2006-03-09 09:54:43 +00:00
mfranz
359a8c4a81 model.[ch]xx:
add abstract class SGModelData. If a pointer to such a class is handed over
  to sgLoad3DModel, then its modelLoaded() method is called with path, property
  node and branch. And then it's added to the scene graph so that it's
  destroyed when the model branch is removed from the graph.

modellib.[ch]xx:
  only cache objects when asked to. This is the case for OBJECT_SHARED
  and random objects (like before), but no longer for OBJECT_STATIC.
  These are now removed from the graph when they are "out of sight". This
  prevents accumulation of static models, and makes destroying model data
  possible (e.g. removing Nasal modules)

matmodel.cxx:
  set cache flag for random objects (same behavior as before)
2006-03-09 09:03:57 +00:00
mfranz
dcb95d131b - new FSF addresses
- coplied license headers from h(xx) files to respective c(xx) files
- removed trailing spaces
- fixe $Id$
- fixed typos
2006-03-08 18:16:08 +00:00
david
f4e37ba7c0 Ignore generated binaries. 2006-03-04 13:27:11 +00:00
ehofman
1cbceec0e1 Mathias Frhlich:
zero out all parent pointers, else they might be dangling.
2006-03-04 12:46:29 +00:00
ehofman
5b3c5407a1 Mathias Frhlich:
I have some bugfixes which will avoid fg just crashing if the sound device
could not be opened.
2006-03-03 15:11:35 +00:00
fredb
27a120c7c3 Wrong config file name 2006-02-26 11:02:21 +00:00
andy
375f3e8bc1 Fix from Melchior: Set static values at every condition change, not only initially. 2006-02-22 20:50:35 +00:00
fredb
a75b4af374 Melchior FRANZ:
- don't unlock an already unlocked mutex (Someone wanted to be on
  the safe side with this, but the result is undefined and makes
  pthread_mutex_destroy fail. Reference: manpage for
  pthread_mutexattr_gettype/The Open Group[1]: "Attempting to
  unlock a mutex of this type which is not locked results in
  undefined behaviour.")

- re-enabled all subsystem destructors again (this has been disabled
  because fgfs hung on exit, due to the mutex destroy failure from
  above.)


Reference:
  http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_mutexattr_gettype.html
2006-02-21 12:59:31 +00:00
ehofman
b2a4cd488d Back out the previous patch. 2006-02-21 10:47:20 +00:00
ehofman
1d8d203e9e Declare specified functions, otherwise MIPSpro bails out. 2006-02-21 09:48:33 +00:00
ehofman
4e7fe460a5 Melchior FRANZ:
- new FSF address
- removed a few hundred trailing spaces
- fixed a few $Id$ lines
- copied two license headers from *.hxx files to their respective
  *.cxx counterparts
- added two test aps to .cvsignore
- don't unlock an already unlocked mutex (Someone wanted to be on
  the safe side with this, but the result is undefined and makes
  pthread_mutex_destroy fail. Reference: manpage for
  pthread_mutexattr_gettype/The Open Group[1]: "Attempting to
  unlock a mutex of this type which is not locked results in
  undefined behaviour.")
- re-enabled all subsystem destructors again (this has been disabled
  because fgfs hung on exit, due to the mutex destroy failure)
2006-02-21 09:40:12 +00:00
ehofman
9be14a63b1 Mathias Froehlich: Add license information. 2006-02-20 15:12:13 +00:00
ehofman
afd3c76088 Mathias Frhlich:
This patch makes use of the vectors now available in simgear with that past
patch. And using that it simplyfies the carrier code somehow.

- Small additional factory's to the quaternion code are done in the simgear
  part. Also more explicit unit names in the factory functions.
- The flightgear part makes use of them and simplyfies some computations
  especially in the carrier code.
- The data part fixes the coordinate frames I used for the park positions in
  the carrier to match the usual ones. I believed that I had done so, but it
  was definitly different. Also there are more parking positions avaliable now.
2006-02-19 17:22:17 +00:00
ehofman
6b697506c3 Melchior FRANZ:
- change SG back to FG (this was accidently changed in three wrong
  places when I prepared the file for SG)
- correct length for the proxy id detection
- set (guessed) deposit depth < 1mm correctly
- set deposit type string
- formatting
2006-02-19 17:13:37 +00:00
fredb
3eba296157 Missing defines 2006-02-18 16:19:54 +00:00
fredb
1b51de08f5 Add missing include files needed by the new math code under windows 2006-02-18 13:24:24 +00:00
fredb
3e37f3fa54 Fix Code generation option for debug build 2006-02-18 12:04:37 +00:00
fredb
a18679e95d Remove compiler warnings 2006-02-17 21:57:13 +00:00
curt
0154f81e33 Clean up some compiler warnings. 2006-02-17 15:13:42 +00:00
ehofman
366931952b Remove unused files. 2006-02-17 09:59:27 +00:00
ehofman
606fc352aa Melchior FRANZ:
This patch fixes the sound of 737, Concorde and others, if fgfs
was compiled with newer gcc versions (e.g. gcc 4.0.2). These compilers
implement the c++ standard more strictly, and thus don't guarantee
that c-style casted pointers to different data types really point
to the same address. This is only guaranteed for union members.
2006-02-17 09:23:40 +00:00
ehofman
75f817b39c Mathias Frhlich:
The patch adds a vector lib I have put together during the last time,
it is just handy and interfaces well with s(s)g*. Together with some small
modifications this will later also interface well with OpenSceneGraphs
vectors/matrices. Using this vector kernel is targeted to have a handy
matrix/vector lib available and to provide a scenegraph independent vector
type for use with a small scenegraph wrapper aimed for a smooth transition to
openscenegraph.

That vector code also includes an improoved geodetic conversion routine I
have found some time ago published in the 'journal of geodesy' which avoids
iterative computations for that purpose.

Also the geodetic position class is more typesafe and unitsafe than the
Point3D currently is.

That part is relatively old and in use in my local trees for several months
now.
2006-02-17 09:22:04 +00:00
ehofman
0bc49bf244 Olaf Flebbe:
This patch makesFlightGear at least compile on MSVC. I hope I have removed
reference of my other local changes. DSP and DSW files are included for
reference. They have been reconstructed with am2dsp.pl. I had to introduce a
change to am2dsp because of the need of filenames with embedded spaces. (Yuck)

The major direction is to remove clutter like the _USE_MATH_DEFINES and
have it on the compiler command line sice there is no central include
file. You will have to put it on the command line for your locale
Project files, if it not there, already. I added the
_CRT_SECURE_NO_DEPRECATE define for 2005, since it does no harm to other
VC version.

Third Party Libs like plib, OpenALSDK, freeglut, pthreads-win32, zlib
are unpacked as is side by side. Only change put the includes of OpenAL
into include/AL rather directly into include.
2006-02-17 08:58:56 +00:00
fredb
930a84b459 Outputing 6 digits is not enough for a double 2006-02-07 20:50:35 +00:00
ehofman
21c89e8163 Vassilii Khachaturov:
Fix the current buggy rain orientation behaviour for the views attached to the
aircraft (while still inheriting bugs with the views attached to anything else).
2006-02-02 09:56:48 +00:00
ehofman
b3770cd26c Expose the sun halo texture handle. 2006-01-31 15:14:02 +00:00
ehofman
0cd4d44bd3 Expose GL_COORD_REPLACE 2006-01-31 15:13:12 +00:00
ehofman
af15e73e64 create an absolute value before calling log or log10, this adds support for sound on negative numbers (thrust reverse for example). 2006-01-30 20:30:56 +00:00
ehofman
33f176b8f9 Melchior FRANZ:
add optional arg to SGPropertyNode::addChangeListener that triggers
the listener function call initially. This is useful for cases where
a freshly installed listener wants to treat the current property
value as changed from 'unknown' to the actual value right away.

Examples can be found in the Nasal incarnation setlistener(),
where we have for example this (in $FG_ROOT/Nasal/gui.nas):

  INIT = func {
      ...
      setlistener("/sim/rendering/fps-display", fpsDisplay);
      if (getprop("/sim/rendering/fps-display")) {
          fgcommand("dialog-show", props.Node.new({"dialog-name": "fps"}));
      }
  }


That is: we first attach a listener that cares for changes to the FPS
display switch, but then we have to manually open the dialog initially.
That's a duplication of code and could be as simple as this
(INIT part only):

  INIT = func {
      ...
      setlistener("/sim/rendering/fps-display", fpsDisplay, 1);
  }

That is: the optional third arg makes fpsDisplay be called initially,
and then again with every write action. My first solution was in the
Nasal code only, but Andy (rightfully) says that this should rather
be in sg.
2006-01-30 10:56:34 +00:00
ehofman
42f21972fd On a second thought, disable smooth shaded lines for all segments of the lightning. 2006-01-27 15:27:43 +00:00
ehofman
2d79e54c46 Disable smooth lines for certain lightning segments. 2006-01-27 15:18:45 +00:00
ehofman
224408b0e8 Add support for point sprites. 2006-01-26 09:15:42 +00:00
fredb
610e447d7c The sample is now managed by a SGSharedPtr and shouldn't be deleted explicitely 2006-01-24 21:49:56 +00:00
ehofman
c2c0e19305 Mathias Frhlich:
Incorporating the shared ptr code:
- All scenegraph references from SimGear
- SGMaterial which already had a reference counter uses now that common
  infrastructure.
- SGMatModel is now counted.
- SGSoundSample from SimGear
- And the corresponding change for the sound samples in flightgear which fixes
  a latent crash if FGBeacon would evern be deleted.
2006-01-24 14:44:35 +00:00
ehofman
e8c4b0d57c Mathias Frhlich:
Use the new automatic reference counter instead of doing
that ourselfes.
2006-01-12 13:47:04 +00:00
fredb
36e7684d9a MSVC vsnprintf ( in fact _vsnprinft ) returns -1 when the buffer is too short 2006-01-10 20:25:46 +00:00
fredb
795c079af0 Use the new SGPath::create_dir function
Ensure no triangles array could have more than 32767 vertices, a PLIB limit.
2006-01-07 13:21:36 +00:00
curt
94e1d3f0fc John Ellson:
This patch fixes this SimGear compile error on x86_64 Fedora Development with gcc-4.1:

placement.hxx:49: error: extra qualification ‘SGModelPlacement::’ on member ‘init’
2006-01-04 16:44:08 +00:00
ehofman
1df002de81 MinGW fixes. 2006-01-04 09:08:35 +00:00
ehofman
b7115659b3 Make the sgi code the default to prevent future problems. 2006-01-03 17:40:49 +00:00
ehofman
258ec6b89a Save some memory. 2006-01-03 17:34:00 +00:00
ehofman
d1ecdfc510 Fix the persisent IRIX bug. 2006-01-02 13:32:16 +00:00
ehofman
a807e66d4a prevent confusion by not using a standard name. 2006-01-02 10:04:10 +00:00
ehofman
8f9921d00c Mathias Frhlich:
Add the basic infrastructure for a reference counter class.
Adding it now (without using it) enables Mathias and others to
prepare some memory reduction code.
2005-12-29 12:00:29 +00:00
ehofman
99bc4e9a87 Vassilii Khachaturov:
clean up some build warnings caught with gcc-4.0.
2005-12-19 12:52:02 +00:00
ehofman
9289cfdde9 Frederic Bouvier:
Fix a problem where the directory being created is made relative when in fact
it's absolute. It also tightens things a bit on the Windows side.

Erik:

Make the section that splits up the directory in a lists of parent directories
a standalone function.
2005-12-19 10:22:27 +00:00
ehofman
bedbe3caad Frederic: this patch to sg_path.cxx will filter out false alarms when directory already exists. 2005-12-18 09:37:37 +00:00
ehofman
2e329426ab Frederic Bouvier:
The create_dir was totally broken. No function was used at the right place
except mkdir. This patch now create directories without segfaulting.


Erik:

This was my bad, I've been using a really slow computer for the last ten months
and recompiling SimGear with a change to the properties code takes ages, so
once in a while I apply something not entirely tested. This is one really bad
example which shouldn't have happened. Thanks to Frederic for fixing it.
2005-12-17 22:12:53 +00:00
ehofman
4c68d03457 Add the subdir to the path before trying to create it, instead of afterwards. 2005-12-17 15:41:48 +00:00
ehofman
0911fa4fa2 MSVC fixes. 2005-12-17 15:32:43 +00:00
ehofman
c5737c5f74 Try to detect the proper type for mode_t 2005-12-17 15:15:09 +00:00
ehofman
106198fa20 Stefan Seifert: Add the posibility to specify a userarchive attribute which could be used to save user prefferences at program exit. 2005-12-17 15:11:37 +00:00
ehofman
4eb74a3c93 Add a function to create aa new directory 2005-12-17 15:06:56 +00:00
ehofman
3f0bcc9568 Mathias Frhlich:
Detect whether we support pubuffers at runtime using the GLX extension string.


Erik:

Add support to compile TestRenderTexture if GLUT is installed.
2005-12-14 10:28:16 +00:00
ehofman
f0c35fde6d MacOs X fix. 2005-12-11 13:41:57 +00:00
ehofman
8357eeb762 Vassilii Khachaturov:
* in some cases more specific sg exception types were used in place
  of the more generic one, e.g., sg_io_exception instead of sg_exception
  when the context of the error was an IO error
* in some cases, the error message was made more specific
* minor style fix for exception rethrowing --- using throw; whenever
  a re-throw is made; sometimes optimizing away the exception symbol name
  in the catch handler at all
* more specific catch handlers added in some places -- e.g.,
  an sg_io_exception caught ahead of sg_exception
2005-12-11 13:35:05 +00:00
ehofman
61da54d6ca add swap_test to .cvsignore 2005-12-11 13:26:30 +00:00
ehofman
efea47833d Add a proper return statement for MSVC. 2005-12-11 12:51:51 +00:00
ehofman
24ea08b6d3 Vassilii: help those
using the Doxygen docs.
2005-12-06 18:45:14 +00:00
ehofman
2808b334ed Mathias: silence some valgrind warnings so that you can concentrate better on the real problems. 2005-12-06 18:29:28 +00:00
ehofman
96159cf739 How did this end up there?? 2005-11-27 09:48:51 +00:00
ehofman
577dfa4f54 Initialize glut before using it. 2005-11-27 09:46:58 +00:00
ehofman
66075d620e More WIN32 fixes. 2005-11-23 09:28:02 +00:00
ehofman
60f1d21914 Oops, WIN32 typo fix. 2005-11-22 18:42:16 +00:00
ehofman
b108621a59 * Use SimGear's logging facility isntead of printf's.
* Hopefuly fix a nasty (mostly ATI related) bug.
2005-11-22 18:03:26 +00:00
curt
4a4e703f16 Changes for v0.3.9 (final). 2005-11-17 20:54:06 +00:00
curt
61984730ac Add a small accessor function to expose local timezone offset. 2005-11-17 15:30:07 +00:00
curt
f196d3bab8 Fix a small spelling mistake. 2005-11-15 21:43:34 +00:00
ehofman
7da45cb49e Revert to the original (0.9.8) version, it causes more problems than it solves (did actually solve any?) 2005-11-14 18:25:17 +00:00
ehofman
e994305da6 Put in public domain, Curtis wants it (because net_fdm.hxx depends on it) and I created the other functions. 2005-11-13 09:42:38 +00:00
ehofman
2af37b484e Let the application free the buffer data. 2005-11-12 12:22:23 +00:00
ehofman
faf41f7d96 Prevent a possible memory leak. 2005-11-12 12:17:04 +00:00
ehofman
7629e29397 add a missing character. 2005-11-12 10:55:22 +00:00
ehofman
1cff7fcfea Make a clear separation between loading a sound file into main memroy and sending it to the driver. This prevents data to be loaded into the main memory (or onto the soundcard's memory) when it's not needed. 2005-11-12 10:26:21 +00:00
ehofman
694cf6e958 Expose some internals. 2005-11-11 13:19:58 +00:00
curt
0e12fbb2a0 v0.3.9-pre3 updates. 2005-11-11 00:44:59 +00:00
ehofman
450ad45882 MSVC fix. 2005-11-10 09:57:58 +00:00
ehofman
d674e50591 gcc 4.0 fix. 2005-11-10 09:55:57 +00:00
andy
61f2f4b761 Architectural fix allowing the "tip" popups (FOV, view name, etc...)
to pop themselves down while the simulator is paused.

The problem was with the "real time" queue in the event manager,
causing the third argument of Nasal's settimer() (a flag for "sim
time") to be ignored.  Inverts the default sense of the argument, as
there are lots of uses of settimer() in the current code, almost none
of which want to use real time.

Note this fix introduces a header file incompatibility in SimGear --
be sure to update.
2005-11-09 20:34:14 +00:00
curt
baa2f49b14 v0.9.9-pre2 changes. 2005-11-09 18:47:40 +00:00
curt
8c0bd234d8 v0.9.9-pre2 changes (just the version number!) 2005-11-09 18:41:49 +00:00
curt
c4fd41562f Spelling fixes and other small corrections. 2005-11-05 20:32:45 +00:00
curt
a1d1b4e49f Some pre-release updates. 2005-11-05 19:30:52 +00:00
curt
96fb7a45f7 Add a code comment for future thought. 2005-11-05 18:47:29 +00:00
ehofman
d5eedd2c65 Move Curt's ssgEntityArray experiment over to SimGear. 2005-11-01 09:45:10 +00:00
ehofman
fe4f907099 Remove some unused code. 2005-10-30 15:02:58 +00:00
ehofman
1b45eaf3de Mathias Frhlich:
I guess the most important memory leaks are plugged now.
Just by inspection: An other memory leak in Simgear.
2005-10-27 08:21:58 +00:00
ehofman
cfbc0a1579 MSVC fix. 2005-10-27 08:21:00 +00:00
ehofman
db1b99d8dd Back out the shared mutex code since it only works when the mutex is in shared
memory[1], something we don't support anyhow.
This also fixes a FreeBSD compile problem.

[1] http://hypermail.linklord.com/new-httpd.old/2002/Jan/0557.html
2005-10-26 11:19:58 +00:00
ehofman
65a880e9fa Oops, ALUT 1.0 requires a little more work than expected. 2005-10-25 18:05:23 +00:00
ehofman
37b4005d3e Alex Romosan:
* Use "const string&" rather than "string" in function calls when appropriate.
* Use "const Point3D&" instead of "Pint3D" in function calls when appropriate.
* Improved course calculation in calc_gc_course_dist()
* Safer thread handling code.

Vassilii Khachaturov:

Dont use "const Point3D&" for return types unless you're absolutely sure.

Erik Hofman:

* Use SGD_(2)PI(_[24]) as defined in simgear/constants.h rather than
  calculating it by hand every time.
2005-10-25 13:48:58 +00:00
ehofman
70faa252e7 Prepare for ALUT version 1.0 2005-10-25 13:06:25 +00:00
ehofman
3620be8dbc Cosmetic updates. 2005-10-23 14:04:42 +00:00
ehofman
21c64dd60f Slightly update the seasonal texture support code. 2005-10-23 13:47:46 +00:00
ehofman
fb69d790ce Add support for seasons. 2005-10-23 13:31:13 +00:00
ehofman
debd066edd Melchior FRANZ:
The attached patch makes remove_child() available as removeChild(pos, keep).
That's consistent with getChild. Only renamed remove_child to removeChild and
added a check for validity of the pos argument.

removeChildren() will be used in input.cxx, and a lot in the upcoming
dynamic new_gui dialogs, which are aiming at replacing the hard-coded
dialogs. I'll discuss them on the list once the infrastructure is
in place. (The <hide> gui property was one part of it.)
2005-10-23 11:55:48 +00:00
ehofman
f58d81b1e9 Harald JOHSEN: the sky color now fades to black with altitude 2005-10-23 11:46:41 +00:00
ehofman
8d507f161b Remove some dead code. 2005-10-22 11:07:00 +00:00
ehofman
b015f7c801 Harald JOHNSEN:
I have corrected a few bugs with the owner draw gauge, weather radar code and heat-haze effect.

- shadanim.cxx :
  the heat/haze effect was showing artifacts when using a screen resolution >
  1024 pixels.
2005-10-16 17:23:59 +00:00
ehofman
80abe952ba Ima Sudonim remembered me there is still one problem for gcc Vs. 3.4 or later under Cygwin. This fixes it. 2005-10-15 14:59:02 +00:00
andy
c12162407c Fix memory leak discovered by Mathias Froehlich 2005-10-14 16:42:32 +00:00
ehofman
7f5c3b223a Mathias Frhlich:
This one, removes some virtual qualifiers at a private member class of
SGPropertyNode. These virtual qualifiers are really useless and stop the
compiler from inlineing these functions. I gain a single frame with my
favourite aircraft per second!
2005-10-14 16:27:06 +00:00
ehofman
2f3e4ebf39 Mathias Frhlich:
I have done a valgrind run in flightgear. Just start it up and close it at the
fist change I had about half an hour later.

property-leak.diff:
   A leak in the property system which I could even notice in top.

texture-leak.diff:
    minor one, but fixed is fixed ...
2005-10-14 16:21:57 +00:00
curt
2c14f8587e Use an unsigned vs. signed short to double our element capacity for higher
resolution scenery.
2005-10-12 16:43:26 +00:00
ehofman
42224052e2 Martin Spott:
make GCC on Solaris8 happy.
2005-10-12 08:59:39 +00:00
curt
a8dd5aa0fc Fix a small typo. 2005-10-11 18:56:45 +00:00
ehofman
f3d0a9bc3f David Luff:
The following patch needs to be applied to fix the errors that Georg
Vollnhals was getting whilst attempting to compile SimGear with gcc-3.4.x
2005-10-09 09:37:35 +00:00
ehofman
d629b9e36a Harald JOHNSEN:
- shadanim.cxx, animation.hxx :
  new chrome (sphere mapping) shading ;
  disabled the loading of the fresnel VP until it is fixed ;
2005-10-08 11:52:48 +00:00
ehofman
4d54ba2200 Another Solaris fix. 2005-10-06 14:39:12 +00:00
ehofman
0035ef9194 Martin Spott: Use standardized Sun directive. 2005-10-06 11:06:27 +00:00
ehofman
fcb20296d7 MSYS fix. 2005-10-06 09:45:36 +00:00
ehofman
6bb9080017 MSVC fixes. Frederic: MSVC has no ssize_t type 2005-10-06 08:25:14 +00:00
ehofman
bbde16dc08 Remove a leftover. 2005-10-04 11:49:24 +00:00
ehofman
ac9716f193 Cygwin fixes(?), it's a good idea to do it this way anyhow. 2005-10-01 11:41:59 +00:00
ehofman
8a2bc1c21b Cygwin fixes. 2005-09-29 12:05:22 +00:00
ehofman
942b474ad7 Fix an oops. 2005-09-28 08:03:44 +00:00
ehofman
f3ef9b671f Back out a patch from Sept. 25th. Setting the *factor* to 0.0 by default isn't generally a good idea. 2005-09-28 08:00:33 +00:00
curt
3538631e8e Make some adjustment to low level serial port configuration flags for unix. 2005-09-26 21:01:17 +00:00
ehofman
1577ab04e1 Vivian Meazza:
Correct the bug in the translate animation where the offset was part of the
multiplication. It now behaves like all other animations:
out = (prop * factor) + offset

I feel strongly that the existing is wrong and must be corrected - it is non-op
if the offset is zero as I have found to my cost! It is just a typo I expect.

The diff also provides non-op default values for the scale animation.

I've also included Harald's latest eye-candy animation which allows us to
have a very smart heat-haze for exhausts. They have been tested by me and
others on Linux and Cygwin. You might like to upload these - I have a
revised Hunter ready to go as soon as they are uploaded.
2005-09-25 07:44:50 +00:00
curt
7f2dfaa5b4 Add eof() support to SGIOChannel/SGFile. 2005-09-24 12:28:14 +00:00
curt
fd126746f7 Add an eof() method to SGFile. 2005-09-23 20:13:43 +00:00
ehofman
63f7e9feb0 AMD64 and sgi fixes. 2005-09-23 12:30:25 +00:00
ehofman
5eb380e103 Platform compatibility fix. 2005-09-22 13:43:09 +00:00
ehofman
832e821919 Add some linefeeds. 2005-09-22 09:15:10 +00:00
ehofman
197e3f144d Create our own stdint.h(xx) implementation and use it where needed. 2005-09-22 09:11:27 +00:00
ehofman
056b5b41e2 Prepare for Openal 1.1 and a separate alut library 2005-09-21 09:22:51 +00:00
andy
15d40fd64a Oops, Frederic caught an inline declaration that had snuck into the code. 2005-09-20 21:38:08 +00:00
andy
979d3da69c Sneak a Nasal update in before the next release. This version
*appears* to work correctly on all systems to which I have access
(i386 linux/win32, x86_64 linux, powerpc OS X, Sparc Solaris 10), but
not all systems are capable of running fgfs.  Beyond that, multiple
threading bugs were fixed, and the naCall() API changed slightly to
support named function arguments.

NOTE: this introduces a change in the external API, and therefore this
change *must* be compiled against current FlightGear code.
2005-09-20 21:09:34 +00:00
ehofman
72984cc4a8 Don't refference simgear_config.h because this header gets installed :-( 2005-09-18 21:05:04 +00:00
ehofman
0a7a815124 int64_t is in stdint.h by default. 2005-09-18 09:21:54 +00:00
ehofman
1ce68a49c6 MSVC fix. 2005-09-18 09:19:07 +00:00
ehofman
b1b6abf285 Use inttypes.h specified types. This is the standard and fixes some 64-bit problems. 2005-09-15 17:06:31 +00:00
ehofman
9dfd6970f1 Better XML error catching, proposed by Richard Harrison. 2005-09-15 16:54:27 +00:00
ehofman
3583c13339 Vivian Meazza:
After much trial and tribulation, Harald came up with a fix for the bug
which has been plaguing Cygwin for a couple of weeks now.

It's only a couple of lines. I've tested it exhaustively, and it seems to
cure the problem of Cygwin failing to start.
2005-09-05 13:30:38 +00:00
ehofman
00ab198c9f Mathias Frhlich:
There was a patch from Manuel Masing a few months ago which cleaned up
SGLocation's way depending on input values. That means that with that patch
SGLocation does no longer have calls with unneeded input arguments.
I took his patch and integrated that into flightgear and made maximum use of
that changes.
2005-09-05 13:23:55 +00:00
ehofman
669d9a89ca Mathias Frhlich:
just a few split out patches from my zoo of local work ...

The patch to simgear-glxproc.diff changes dlopen to not open a specific library.
If it is used with a NULL argument, we just get a handle to the current running
binary including all loaded libraries. This has the advantage that we do not
rely on the name of libGL on the specific platform.
Also a user can link with his own different named libGL or with a static libGL.a

Then the render texture again ...

glxQueryVersion turns out to return the  minimum of the client libraries glx
version and the servers glx version. *All* Xorg servers return 1.2 here.
So we never get the glxPBuffer functions  which are the only ones working with
ati's drivers ...
Reverted back to checking the required functions and just use them if they are
there. Still prefering the glx standard variants since they work on ati's
drivers ...
2005-09-05 09:02:56 +00:00
ehofman
9c54603726 Add some more defines as specified in FlightGear/src/Network/net_fdm_mini.hxx 2005-09-05 08:22:30 +00:00
ehofman
dc09a50472 Mac OS X fixes from Markus Morawitz
stdint.h replacement defines for Windows and Sun from Frederic et all.
2005-09-05 08:17:37 +00:00
ehofman
68eb7031e2 Harald JOHNSEN:
- model.cxx :
  load the 2.5D panels before the animations so that the panels can be used in
  animations his solve the problem of 2.5D panels visible outside of the
  aircraft (one can add a null animation to put the panel at the top of the
  aircraft graph so it is drawn first) and this adds the possibility to have
  billboarded/popup panels.

- newcloud.cxx :
  removed 'this' pointer cast for amd64 compiler.
2005-08-22 17:44:35 +00:00
ehofman
19623cac21 Cygwin fix. 2005-08-10 08:04:39 +00:00
ehofman
4ca25ca533 Harald JOHNSEN:
added a cull test on fields
2005-07-31 08:56:27 +00:00
ehofman
178c49a430 Fix a problem with systems that don't define GLXPbufferSGIX or GLXFBConfigSGIX 2005-07-31 08:46:37 +00:00
ehofman
32e2cd9f06 Harald JOHNSEN:
This is the low level shader class for Simgear.
It's the code from Roman Grigoriev with a few adaptations.
2005-07-31 07:59:08 +00:00
ehofman
7aa514d9ba MacOS-X fixes. 2005-07-27 08:02:11 +00:00
andy
7c2575d723 Josh discovered a bug parsing negative numbers with leading zeros
("-0.3") which also affected ones of the form "-.3".  This got
introduced a few months back, I'm not sure how it went undetected for
so long...
2005-07-21 23:03:26 +00:00
ehofman
f93ea20d5e Harald JOHSEN:
Changes
=======

- shadowvolume.cxx, renderer.cxx :
  - reduced the polygon offset a bit to eliminate some artifact ;
  - changed again the cleanup code for objects inside a tile because it could crash on rare occasion ;
  - the culling of shadow casters has been rewritten to traverse the scene graph, it should be
    a bit faster when there is a lot of objects ;
  - the range selector was not correctly handled, sometimes the wrong LOD was casting shadows.
  - added the option to display aircraft's transparent objects after the shadows, this will
    reduce the problem of shadows being hidden by the transparent object (propeller disk,
    rotor, etc). A side effect is that aircraft's transparent objects won't receive shadows
    anymore. This is usually a good thing except when the aircraft use a 'transparent'
    texture where it should not. A transparent texture in the plib context is a texture
    with an alpha channel or a material with alpha <= 0.99.

- model.cxx, animation.cxx, shadowvolume.cxx :
  - added an optional <condition> under the <noshadow> animation

- tower.cxx
  - correct a rare bug where all occurences of the aircraft are not deleted from the
  departure list causing a crash in FGTower::CheckDepartureList function.
2005-07-18 16:57:20 +00:00
ehofman
73cb6ff00d Adjustments to better support GLX1.3 and ATI drivers. 2005-07-13 12:00:30 +00:00
ehofman
72267fa60b Harald JOHNSEN:
Melchior has found another bug, I tried to skip some computation for a few
frames but that introduced some bad rendering bug with the aircraft moving
parts.
I corrected that and reduced a bit the cpu usage for ground objects.
2005-07-06 08:44:25 +00:00
ehofman
6b6a27e849 Another update, the previous one could crash if you leave the surrounding tiles (try Set aircraft in air and choose a distant airport). 2005-07-05 18:53:16 +00:00
ehofman
daea10121c Somehow gcc allows function overriding but MIPSpro doesn't. Fix this. 2005-07-05 18:00:58 +00:00
ehofman
999a1e514b Harald JOHNSEN:
- shadow volume vertex are now shared, using DrawElements instead of repeated
  calls to glVertex, this can improve performance on some systems.
- added a rendering path that use the alpha channel instead of the stencill
  buffer.
- releasing memory when tiles objects are destroyed
- objects sub parts will not cast shadows if their name begins with "noshadow"
  or if they are in a <noshadow> animation

- bbcache.cxx :
   don't ask for a 32 bits context when the primary context is only 16 bits

- RenderTexture.cpp :
   corrected a crash when asking for a second rendering context
   on win32 and extensions not being supported

- model.cxx, animation.cxx :
   added a <noshadow> animation, added an animation type needed by the shadow
   code.
2005-07-05 17:08:27 +00:00
ehofman
be30960366 Make sure it works with the lates version of OpenAL. 2005-07-04 09:20:11 +00:00
ehofman
38e5084018 Restore the old behavior. Additions are likely. 2005-06-30 19:10:18 +00:00
ehofman
fdd9bb1af6 Melchior FRANZ:
- check for isTied() and refcount has to be made *before* we go into
  recursion, so as to pertain subtrees of refcounted nodes, even if there
  are no refcounted/tied nodes *in* this tree
- return value inverted, because it's more logical to say
  removeChildren() == true --> everything removed;  false --> failed
- further cleanup
2005-06-29 09:41:07 +00:00
ehofman
81546820ab Frederic: Also copy the attributes over to the new tree. 2005-06-28 11:19:41 +00:00
ehofman
84e87f0e8a Due to a misunderstanding of what removeChild() actually does, some used it to detach a subtree from the main tree. The previous patch broke that behaviour so a new function call detchChild() is now added. 2005-06-28 11:19:09 +00:00
ehofman
901592a88e fix return value 2005-06-27 17:48:13 +00:00
ehofman
24f908d9be Melchior FRANZ:
- introduce removeChildren() and removeChildren(name)  to remove all children
  or all with a given name
- let removeChild() and removeChildren() also remove child trees, and let them
  return a "dirty" boolean that indicates if one or more subnodes had to be
  kept because of refcounting (removeChild returned a SGPropertyNode_ptr before)
- make alias/unalias increase/decrease the refcounter
- don't remove refcounted or tied nodes

This patch makes the SGPropertyNode_ptr actually useful. Until today, they did
proper refcounting (except for aliases), but no other part did check this counter.

But SGPropertyNode_ptr aren't only useful for the first time, they are now
highly recommended for every place that relies on a node address, and wants
to "lock" it (so that removeChild(ren) will never try to remove them). This
is not guaranteed for SGPropertyNode* (and never was). Of course, that's not
an imminent problem, as only four places currently use removeChild(ren) and
these are careful to only remove their own data.
2005-06-27 13:49:28 +00:00
ehofman
f62ff0ad66 Harald JOHNSEN:
Changes
=======

New volumetric shadows for FlightGear.

There is now two new checkboxes in the rendering dialog to enable/disable shadows
for the user aircraft and for static scenery objects (ie those defined in the .stg files).
AI and random objects are not handled for the moment.


known bugs
==========
- ghost objects
2005-06-26 17:16:45 +00:00
ehofman
8e0ecbeb8f Remove the 'old' 3D clouds code. 2005-06-25 11:22:06 +00:00
ehofman
095367f760 Melchior: Make the (lack of) axis or center location definitions more consistent. 2005-06-12 11:23:28 +00:00
ehofman
5d34eb12e0 Melchior FRANZ:
This is the more elegant solution that Andy had proposed in a response
to my RFC on Nasal initialization code in joystick configuration files.
As Nasal is initialized last (for good reason), subsystem can currently
not use it for initializing. postinit() is called on all subsystems
after all have been initialized.
2005-06-11 08:39:26 +00:00
ehofman
d4e760efe1 fix a coredump situation, discovered by Melchior. 2005-06-08 14:07:53 +00:00
ehofman
75ab8e697b Harald JOHSEN:
Changes
=======

- changed the rotation of sprites, they don't rotate strangely when we
  approach them now
- corrected the strange movement of clouds when banking quickly
- it no more rain above cloud layers
- add a radar echo container used by the weather radar instrument
2005-05-30 09:04:57 +00:00
andy
f4b05d46ed Fix two crash conditions Ampere found. These are just temporary
patches; my private version has rewritten both of these functions
(ironically fixing these bugs in the process) to handle negative
offsets meaning "from the end".
2005-05-29 16:13:48 +00:00
ehofman
04c5f2c36a Melchior FRANZ:
Turn the material animation's <transparency> property into a group, with
members <alpha-prop>/<alpha>, <offset-prop>/<offset>, <factor-prop>/<factor>,
<min>, and <max>. The "material" animation can now fully replace "blend" and
"alpha-test" (--> <threshold>) animations, with enhanced possibilities:
The "material" animation can be used for one or more explicit objects (like
"blend"), but also for all objects that share one material (<global>), which
avoids problems with objects being forced together into one tree. Also, an
object doesn't have to be semitransparent or textured with a semitransparent
texture to make blending work. Unlike the "blend" animation, the "material"
animation also makes fully opaque and untextured objects transparent. (This
fixes the bo105's formerly semi-transparent rotor.)

Erik:
The blend animation and alpha-test animation are depreciated as of now.
2005-05-24 08:13:09 +00:00
ehofman
db50f95482 Melchior FRANZ:
Currently, the material animation sets glColorMaterial(GL_AMBIENT_AND_DIFFUSE)
for all material properties. This breaks emission-only (e.g. cockpit lighting
for the p51d) or specular-only animation. ==> set glColorMaterial only where
it is really required.
2005-05-23 16:35:00 +00:00
ehofman
0e52a08a47 MSVC fix. 2005-05-22 09:18:56 +00:00
ehofman
7b5d49ef60 Harald JOHSNEN:
Changes
=======

- correct the transparency probleme when old 3d clouds were enabled
 (rendering context with an alpha channel)
- changed rain cone orientation, it can now be viewed from helicopter or chase
  view (still not tower view)
- clouds are a bit more yellow/red at dawn/dusk
- weather data is now correctly propagated to the interpolator, this correct
  visibility, wind, etc
- the 'metar' weather scenario now immedialty reuse the real metar data
- real metar no more overwrite custom weather scenario
2005-05-22 08:09:08 +00:00
ehofman
430ba60b33 MSVC fix. 2005-05-22 07:35:39 +00:00
ehofman
3af1f3bc63 Make removeChild() work (again?) 2005-05-17 09:56:08 +00:00
ehofman
bdcb94af81 gcc fix. 2005-05-15 09:34:04 +00:00
ehofman
2ea9e723c2 Harald JOHNSEN:
This is another update for the cloud code, a lot of lines but this time I have started to add the doxygen doc.

Misc
====

- corrected a bug when RTT is not available, the current rendering context was
  altered
- if RTT is not available then 3d clouds are not drawn at all
- impostors lighting is now recomputed when the sun changes position
- distant objects are no more seen in front of clouds
- blending of distant clouds is a bit better now
- litle optimization of code (uses a less cpu time)
- use layer wind speed and direction (no more hardcoded wind)
- fov is no more hardcoded

Changes
=======

- clouds (cu only) are dissipating/reforming (experimental)
- compute a turbulence factor that depends on surrounding clouds and type of
  clouds (experimental)
- clouds shapes are defined in cloudlayers.xml
- type of clouds present in a layer is also defined in cloudlayers.xml
- cloud layers are generated from metar and other misc. data (in progress)
- added a rain effect around the viewer (enabled in the rendering dialog and
  when the metar property says so)
- added a lightning effect (enabled in the rendering dialog) : cb clouds spawn
  new lightnings
- added a dialog to select from different weather source : metar/property,
  a 'fair weather' environment and a 'thunderstorm' environment.
2005-05-15 09:27:00 +00:00
ehofman
e19091d809 Melchior: Only change types when explicitly requested. 2005-05-09 16:18:41 +00:00
ehofman
64ab59c0e0 Melchior FRANZ:
Vivian pointed out that a redefined Ctrl-U key binding didn't work
correctly. I found out that this is, because the definition in
$FG_ROOT/keyboard.xml sets <value type="bool"> for binding[1],
and ... [better sit down first!] ... and assigning <value type="double">
in a *-set.xml file doesn't *really* set "double" as new type!

Instead, the boolean is kept, and a double sqeezed into it. In other
words: once tainted as bool, you can throw all doubles in the universe
on a property node, and all it will accept is 0 and 1. Without warning!

BTW: I changed the patch: I was overly cautious: clear_value() does already
care for ties and for setting NONE, so we just need to make that public as
clearValue(), and use that. Makes the patch a bit more verbose, though.  :-/
2005-05-09 14:31:41 +00:00
ehofman
4707b363aa Solaris fix. 2005-05-07 08:46:04 +00:00
andy
1a72245c15 Properly release the mod lock when returning from a runtime error.
Ampere discovered that the interpreter would deadlock at runtime if it
hit such a condition during initialization.
2005-05-04 20:17:28 +00:00
ehofman
dea7b9050d Phil Cazzola:
This is a minor bug fix for sgBucketDiff().
If you crossed the bucket size boundary, the answer for dx could be wrong.

E.g.
 going from   0:0, 21:7  to 0:7, 21:7   would give you dx = 7 (correct)
 but going from 0:0, 21:7 to 0:3, 22:0 would give you dx = 6 (instead of 7)

Previously it differenced the center longitudes of the buckets.  When you
cross a boundary, the center point of the larger bucket now lies on the edge of the smaller bucket.

The result was a dx with an integer + 1/2 bucket, which rint() was rounding to the nearest even int.

This function only seems to be used in TerraGear.
2005-05-01 08:50:39 +00:00
ehofman
3bd810fedc Make use of the repeatable sg_random() function so display systems can synchronize 3d clouds too. 2005-04-30 10:00:16 +00:00
ehofman
f9cbf8361d Add a seed function that gives the same random seed within a ten minute period of time. This should be useful for synchronizing display systems. 2005-04-30 09:59:12 +00:00
ehofman
eccd4d0325 Mathias:
I have done a patch to eliminate the jitter of 3D-objects near the viewpoint
(for example 3D cockpit objects).
The problem is the roundoff accuracy of the float values used in the
scenegraph together with the transforms of the eyepoint relative to the
scenery center.

The solution will be to move the scenery center near the view point.
This way floats relative accuracy is enough to show a stable picture.

To get that right I have introduced a transform node for the scenegraph which
is responsible for that shift and uses double values as long as possible.
The scenery subsystem now has a list of all those transforms required to place
objects in the world and will tell all those transforms that the scenery
center has changed when the set_scenery_center() of the scenery subsystem is
called.
The problem was not solvable by SGModelPlacement and SGLocation, since not all
objects, especially the scenery, are placed using these classes.

The first approach was to have the scenery center exactly at the eyepoint.
This works well for the cockpit.
But then the ground jitters a bit below the aircraft. With our default views
you can't see that, but that F-18 has a camera view below the left engine
intake with the nose gear and the ground in its field of view, here I could
see that.
Having the scenery center constant will still have this roundoff problems, but
like it is now too, the roundoff error here is exactly the same in each
frame, so you will not notice any jitter.

The real solution is now to keep the scenery center constant as long as it is
in a ball of 30m radius around the view point. If the scenery center is
outside this ball, just put it at the view point.

As a sideeffect of now beeing able to switch the scenery center in the whole
scenegraph with one function call, I was able to remove a one half of a
problem when switching views, where the scenery center was far off for one or
two frames past switching from one view to the next. Also included is a fix
to the other half of this problem, where the view position was not yet copied
into a view when it is switched (at least under glut). This was responsible
for the 'Error: ...' messages of the cloud subsystem when views were
switched.
2005-04-29 14:37:27 +00:00
ehofman
e0decf1233 Mathias:
have done a patch to eliminate the jitter of 3D-objects near the viewpoint
(for example 3D cockpit objects).
The problem is the roundoff accuracy of the float values used in the
scenegraph together with the transforms of the eyepoint relative to the
scenery center.

The solution will be to move the scenery center near the view point.
This way floats relative accuracy is enough to show a stable picture.

To get that right I have introduced a transform node for the scenegraph which
is responsible for that shift and uses double values as long as possible.
The scenery subsystem now has a list of all those transforms required to place
objects in the world and will tell all those transforms that the scenery
center has changed when the set_scenery_center() of the scenery subsystem is
called.
The problem was not solvable by SGModelPlacement and SGLocation, since not all
objects, especially the scenery, are placed using these classes.

The first approach was to have the scenery center exactly at the eyepoint.
This works well for the cockpit.
But then the ground jitters a bit below the aircraft. With our default views
you can't see that, but that F-18 has a camera view below the left engine
intake with the nose gear and the ground in its field of view, here I could
see that.
Having the scenery center constant will still have this roundoff problems, but
like it is now too, the roundoff error here is exactly the same in each
frame, so you will not notice any jitter.

The real solution is now to keep the scenery center constant as long as it is
in a ball of 30m radius around the view point. If the scenery center is
outside this ball, just put it at the view point.

As a sideeffect of now beeing able to switch the scenery center in the whole
scenegraph with one function call, I was able to remove a one half of a
problem when switching views, where the scenery center was far off for one or
two frames past switching from one view to the next. Also included is a fix
to the other half of this problem, where the view position was not yet copied
into a view when it is switched (at least under glut). This was responsible
for the 'Error: ...' messages of the cloud subsystem when views were
switched.
2005-04-29 14:36:50 +00:00
ehofman
100927f16c Harald Johnsen: Fix a 'terrible' bug with culling of the clouds. 2005-04-26 20:14:37 +00:00
ehofman
bb670f6658 IRIX fixes. 2005-04-26 09:08:58 +00:00
ehofman
d37992aaf9 Harald Johnson:
Changes
=======

- corrected some strange behavior when playing with the render dialog options
- the density slider is now working : if you are fps limited and still want to see clouds in
  the distance you should play with that
- added the choice for texture resolution, its more comprehensible now (before it was
  wrongly allways choosing 64x64 textures)
- changed the initial texture size : you now have 64 texture of 64x64, this uses 1Mo of
  texture memory (before it was 20 texture of  256x256, that took more memory and there was
  not enought impostors)
- sun vector is now right so the lighting is a bit better
- removed useless sort and light computations for impostors, this should save a lot of cpu
- blending of distant cloud is more accurate now
- clouds are now positioned correctly, they don't try to escape you anymore
- no more red/white boxes around cloud
- textures are now filtered (no more big pixels)

known bugs
==========

- distant objects are seen in front of clouds
2005-04-26 08:30:38 +00:00
ehofman
9048ee533d Don't refference GLUT but GLU instead. 2005-04-24 13:55:20 +00:00
ehofman
2b1e5927ca This one time I did a commit using Linux. <sigh> 2005-04-24 11:45:34 +00:00
ehofman
b5e03030d1 Harald Johnson:
- new and updated sources for the new volumetric clouds
- 2 new textures for the clouds
- an update to the render dialog to enable/disable and change a few parameters
  for the new clouds
2005-04-24 11:16:50 +00:00
andy
65056bfa72 Support for a "forindex(idx; list) {...}" construct analagous to
foreach, except that the variable gets the index instead of the list
element.  Should be useful, and took almost no code to implement.

Support for operator/assignment syntax: +=, -=, *=, /= and ~= now do
what you think they should.

Library support for a bind() function (see the docs Andy is still
writing), allowing runtime modifications to function lexical
environments.
2005-04-22 21:54:16 +00:00
andy
c50bb90374 Fix clamping of the minimum hash size, because the Melchior discovered
that the column math goes wacky when lgalloced is allowed to be
  zero.
Augment the find() function to take a starting index.
Fix strc() to use a default index of zero.
Fix parser precedence of TOK_MINUS, so that "a-b-1" means (a-b)-1 and
  not a-(b-1).
2005-04-19 14:19:46 +00:00
ehofman
ec4fc265e0 Non gcc fixes. 2005-04-19 12:30:12 +00:00
andy
8ea41af5c4 Fix crash in the code generator when compiling a (now illegal, because
"var" is a reserved word) expresssion of the vorm "var=<expr>".
2005-04-18 20:43:29 +00:00
andy
966331dac7 Upgrade to nasal 1.0 test candidate 2005-04-18 19:48:47 +00:00
andy
cf056bace7 Fix boolean semantics so that the empty string evaluates to false, and
numeric strings are false if their numeric values are false.
2005-03-30 18:45:01 +00:00
ehofman
405a455906 Melchior FRANZ:
Re-organisation: <diffuse>, <ambient>, <emission>, <specular> are
now groups with members <red>, <green>, <blue>, <factor>, <offset>,
and their <*-prop> forms. Additionally, there's an option <property-base>
that can be used to set a path that is prepended to all <*-prop> paths.
It defaults to an empty string. Rationale: see model-howto.html.
2005-03-28 09:13:45 +00:00
andy
3a8b431a5b Don't parse a single "e" or "E" as a numerical zero. You need a
numerical prefix to use the 1.0e12 notation, "e" alone is not enough.
2005-03-22 20:28:47 +00:00
ehofman
3ce0c17237 Melchior FRANZ:
here is the promised material animation. It looks a bit longish, but that
wasn't avoidable -- there are simply too many parameters to consider. I tried
hard, though, to make the animation fast by only doing the necessary stuff.
It doesn't affect the frame rate here with my test model. The animation is
heavily based on Jim's "material-emission" animation.

* implementation of the "material" animation (this required to make the
  texture path available) + documentation update ($FG_ROOT/Docs/)
* fix some more return values (texture animations, and select) for the
  shadow problem (and some in anticipation of other problems  :-)
* fix compiler warning
2005-03-22 13:12:51 +00:00
ehofman
61a2e0f104 Melchior FRANZ:
the cause for the disappearing shadows is, that SimGear doesn't tell plib
to call the pre-traversal-callback function on culled objects. These calls,
however, are necessary to execute the transform animation that does, for
example, translate a shadow back into the frustum! Curretnly, the callback
is only executed, and the shadow only magically pops up again, when the object
enters the frustum because the view has changed significantly.

The plib documentation does only talk about TRUE and FALSE for possible
return values from the pre-traversal-callback. But src/ssgEntity.cxx reads
like this:

   int ssgEntity::preTravTests ( int *test_needed, int which )
   ...
       int result = (*preTravCB)(this,which) ;

       if ( result == 0 ) return FALSE ;
       if ( result == 2 ) *test_needed = 0 ;
   ...

So the return value needs to be 2 to bypass the cull test for pretraversal,
and get the pretraversal in any case. I only changed the return values in
four animations: scale, rotate, translate, and range, because these are
the most likely to move an object out of the frustum. It's not necessary
for blend/alpha/texture manipulation etc. Of course, this is a bit more work
for plib, but the performance will probably not be affected, because:

* these four animations are mainly used for the aircraft model (the spin
  and billboard (trees!) animations are not affected)

* the number of extra nodes to process is quite low

* a part of the time spent for the extra nodes to be processed, was before
  used for workarounds that are now not necessary any more

I didn't observe a frame rate drop, at least.
2005-03-19 10:19:30 +00:00
andy
7c44251216 Oops, fixed the wrong test 2005-03-12 15:51:37 +00:00
andy
26e70664d6 Off by one error when printing exact poweres of ten 2005-03-12 15:49:53 +00:00
andy
8ac27cc798 Fix an infinite loop (due to an overflow condition) when printing some
very large numbers.
2005-03-11 21:49:31 +00:00
andy
d314164fed Fix the fixes. Note that "." had the same problem as "+" and "-", and
that we can still match non-identical constants if they are both
strings with the same numerical value.
2005-03-11 20:39:07 +00:00
andy
d2cbed151b Don't parse the strings "+" and "-" as numerical zeros. Also fix the
code generation of constant objects to use real identity and not Nasal
equality, so (e.g.) the constants 1 (number) and "1.0" (string) do not
get turned into the same object in the generated code.
2005-03-11 19:07:06 +00:00
ehofman
fc06ae58b2 Ima Sudonim:
I have (hopefully) generated a patch for a previously mentioned simgear  problem for a hang condition in mac os x.  Mentioned in  <http://baron.flightgear.org/pipermail/flightgear-devel/2005-February/ 035004.html>
2005-03-10 08:58:48 +00:00
ehofman
a8768c78a2 automake 1.8+ fixes 2005-02-15 18:13:15 +00:00
ehofman
ee8763f60d More MacOS X fixes 2005-02-12 12:44:46 +00:00
ehofman
db633330fe Fixes from Norman for users running Cugwin with the XServer package installed. 2005-02-11 15:19:04 +00:00
ehofman
c1ffafd663 MacOS X fix(?) 2005-02-11 15:07:22 +00:00
ehofman
72f35dc914 Comment out GLX code for MacOS and (hopefully) add some MacOS AGL compattible code. More needs to be done though. 2005-02-01 10:35:43 +00:00
ehofman
e5f82f53b9 MacOS doesn't have glx.h 2005-01-31 18:29:38 +00:00
ehofman
e39e6893e0 Jim Wilson:
Fix a couple of loose ends and missed edits on the earlier patch.  For the
most part no change in functionality.
2005-01-31 18:21:12 +00:00
ehofman
9ab77d65f4 Cygwin fixes 2005-01-31 18:07:40 +00:00
ehofman
8ed96cad1d Windows fixes. 2005-01-29 11:44:01 +00:00
ehofman
7795eb8239 Jim Wilson:
This patch adds support to the model animation system for modifying emissive
states on the fly so that it is possible to make "lights" appear to dimm.

This is an example of a configuration entry which should explain how it is used:


 <animation>
  <type>material-emission</type>
  <object-name>Face</object-name>
  <property>/controls/lighting/instruments-norm</property>
  <emiss-red>1.0</emiss-red>
  <emiss-green>0.8</emiss-green>
  <emiss-blue>0.5</emiss-blue>
 </animation>

Note the color entries are the emissive colors when the "property" value is
1.0.  They are useful for tinting the light.   The "property" itself must be
float or double and is clamped to values between 0 ~ 1.0 inclusively.   The
"property" value is multiplied against the colors to get the actual material
properties.  Thus property value 0.0 = darkest, and 1.0 = brightest.
2005-01-29 10:31:25 +00:00
ehofman
207c7ab1e0 MSVC fix. 2005-01-28 15:23:26 +00:00
ehofman
27af79684f Frederic Bouvier:
code.c is C code ( according to the file extension ), so variables should be declared at the beginning of the function.
2005-01-28 15:21:29 +00:00
ehofman
6b61a8eed1 use a proper delete[] 2005-01-28 15:15:23 +00:00
ehofman
181e6eac75 MSVC fixes 2005-01-28 09:32:57 +00:00
ehofman
fd1979857c Fix an NVIDIA problem. 2005-01-27 17:49:22 +00:00
ehofman
448bc3facd Add a RenderTexture test program. 2005-01-27 10:56:22 +00:00
ehofman
97cabadb88 Melchior FRANZ:
If alcOpenDevice( NULL ) is NULL, then context is never assigned a
value, and it's pointless to ask for it in the next "if". But as the
ALCcontext that context points to doesn't seem to be fully defined
(OpenAL bug), valgrind still complains ...


Erik Hofman:
Extend this some further and define context=0 otherwise and check for
context != 0 before using it.
2005-01-27 10:47:09 +00:00
ehofman
8e284a70b7 Melchior FRANZ:
Trying to find the bug in tower.cxx (that crashes fgfs quite frequently
for me!), I'm playing with valgrind again. Until I'm in the ATC subsystem
there will be some other bugs and nitpicking along the way.

valgrind doesn't like that imgage->tmp is once allocated with new and
once with new[], sometimes with malloc() (via map), and sometimes freed
with delete (not delete[]!) and sometimes with free(). With simple types
such as GLubyte this shouldn't really make a difference, but anyway.

Also, I promised that I'd send patches for "if (foo) delete foo;" as
I'm making other changes to concerned files. texture.cxx is one with a
few occurrences thereof. (Remember: C++ explicitly allows to delete
null-pointers, so this check is redundant, and hence not tolerated in
other projects, such as KDE. Doesn't have to impress us, of course.  :-)

Also, fixes 4 signed/unsigned warnings (gcc 3.3.4)
2005-01-27 10:42:31 +00:00
ehofman
73f9febe06 Add Mark Haris' RenderTexture class based on SimGear's extesion support files. 2005-01-27 10:39:15 +00:00
andy
6a6cc22e9c Move error handling in setupFuncall above the stack frame creation.
The error properly belongs to the enclosing scope, not the called
(non-)function.  This bug was fixed a few months back in my private
tree, but Melchior just discovered that the new Concorde scripts
tickle it.  I really need to re-synchronize SimGear with my own Nasal
tree...
2005-01-25 22:37:22 +00:00
ehofman
b293639b76 Add a bunch of extensions in preparation of render-to-texture support. 2005-01-25 18:33:59 +00:00
curt
f06036be09 Frederic Bouvier:
The Beaver triggered a problem ( uninitialized variable ). Here is the updated
code.
2005-01-24 21:46:12 +00:00
curt
867571af78 Frederic Bouvier:
this is the animation code that do randomisation of the spin animation. The XML tags are modified to support the syntax below :

  <use-personality type="bool">true</use-personality>
  <factor>
    <random>
      <min>1.8</min>
      <max>2.2</max>
    </random>
  </factor>
  <starting-pos-deg>
    <random>
      <min>0</min>
      <max>360</max>
    </random>
  </starting-pos-deg>

instead of usual :

  <factor>1.42</factor>
  <starting-deg-pos>42.0</starting-deg-pos>
2005-01-24 19:49:35 +00:00
ehofman
f6314d3124 Erik Hofman
1. Remove the dependency on alut  which (on certein platforms) might pose
   some restrictuons on commercial use.

2. Create a sound source just prior to playing the sound and destroy it
   again when the sound has stopped. This should greatly reduce the
   error reports from Windows users.
2005-01-24 15:51:37 +00:00
ehofman
1e87dd7903 Melchior FRANZ:
The following patches to SimGear & FlightGear ...

- create an FGMetar abstraction layer, whose purpose is:
  * provide defaults for unset values
  * interpolate/randomize data (GREATER_THAN)
  * derive additional values (time, age, snow cover)
  * consider minimum identifier (CAVOK, mil. color codes)
- add rain/hail/snow/snowcover support on the METAR side
- add max age of METAR data handling (currently set to
- add support for an external METAR cache proxy server
- add CAVOK handling
- set missing year/month in regular METAR messages
- fix a small bug in metar.cxx (wrong return value)
2005-01-20 09:28:04 +00:00
curt
3b6af2f0c2 Ready for 0.3.8 release. 2005-01-18 14:34:13 +00:00
curt
5bdff41641 Require plib-1.8.4 2005-01-17 21:48:05 +00:00
ehofman
67e9d105cb Use the double precission pow() function to get Solaris compiling. 2005-01-16 08:52:22 +00:00
ehofman
f1fc99f16f Solaris fix 2005-01-15 14:24:28 +00:00
ehofman
f89e359d53 Solaris fix. 2005-01-15 14:22:56 +00:00
ehofman
77ec170a50 MingW/MSYS fix 2005-01-15 14:18:30 +00:00
ehofman
34320f5f20 Eliminate some compiler warnings about converting float to int. 2005-01-15 11:57:34 +00:00
ehofman
a26271e46e Add a make_bumpmap and a make_maxcolorwindow function, modify the make_normalmap function to maximize the color window before proceding. 2005-01-15 10:48:40 +00:00
ehofman
e2e7466250 Add support for contrast. 2005-01-14 15:52:56 +00:00
ehofman
1e24cc4643 little endian fixes. 2005-01-14 14:27:57 +00:00
ehofman
dfc23c3528 Add a make_grayscale function and call it from make_normalmap automatically, removing the need to do it make_grayscale prior to calling make_normalmap. 2005-01-14 13:36:38 +00:00
ehofman
cd11a5dc27 Fix a mistake. 2005-01-14 13:12:44 +00:00
ehofman
899734296b Add a function to calculate the normalmap from a regular texture. 2005-01-14 13:08:57 +00:00
ehofman
7a3a81c152 RGBA textures can be made monochrome also 2005-01-14 10:12:00 +00:00
ehofman
e62a4a05ac Fix a few bugs and add a make_monochrome() function 2005-01-14 10:09:21 +00:00
ehofman
463ca207ce Some small updates to the saving code. 2005-01-13 18:35:56 +00:00
ehofman
da6e1b31ea Fix a crash situation. 2005-01-13 18:05:46 +00:00
ehofman
8c783b1680 Update the code a bit more, add a function to retreive the last error string and add a function to write SGI texture fils. 2005-01-13 14:47:31 +00:00
curt
efce88ff12 - Fix a couple oops's in cloud.cxx
- In sky.cxx blend low density cloud layers (few/scattered) into nothing (but
  don't touch visibility distance) as we approach them so we can fly through
  clean.
- For high density cloud layers (broken/overcast) we do not fade the layers
  out, but we fade visibility to nearly nothing as we approach the layer.
2005-01-11 16:02:39 +00:00
curt
01608b7e18 Add a method to SGCloudLayer to set overall cloud alpha. This gives us the
capability to slowly fade a cloud layer in or out.

We use this effect in combination with lowering visibility as we approach
a cloud layer to hide the fact that it is simply a 2d textured polygon being
drawn across the sky.
2005-01-11 15:21:58 +00:00
david
a5f0e0395a Do not reduce visibility when passing through a 'few' or 'scattered'
cloud layer (i.e. <50% coverage).  This is a quick hack rather than a
proper fix, but it will at least make it possible to get above a
scattered layer VFR.
2005-01-10 23:34:52 +00:00
ehofman
0b723174fd Add support for binding a thread to a specific CPU (IRIX only at this time). 2005-01-09 10:24:54 +00:00
ehofman
5d248bf0df Frederic Bouvier:
It comes to me that the bulk of all problem reports, especially from Windows users, have it's cause in an obsolete sound driver. These messages should direct them to the right solution before complaining.
2005-01-08 11:47:19 +00:00
curt
c039ccdeb0 Updates for 0.3.8-pre2 release. 2005-01-03 19:05:32 +00:00
ehofman
d88fb32a73 Melchior FRANZ:
My recent fix for the load/save fgfs.sav feature was a bit too ambitious.
While aliases lead to abortion before, I tried to copy them properly,
although this wasn't a requirement. Unfortunately, this seems to have
worked for absolute aliases only, not for relative ones, and hence broke
several panel instruments. The attached patch backs most of the previous
patch out again, and goes a simpler route: just ignore aliases.
2004-12-23 13:32:01 +00:00
ehofman
37ac409586 Melchior FRANZ:
fgLoadFlight() loads a property file ("fgfs.sav") to a new property tree,
and then copies that over to the main tree. copyProperties() didn't know
how to handle type SGPropertyNode::ALIAS and hence threw an exception that
made fgfs abort.

The attached patch adds support for ALIAS to copyProperties(): aliased
nodes are created in the target tree if necessary, and then linked like in
the source tree. It seemed useful to add an optional argument to
props.[ch]xx/getType() that would indeed return the property type "ALIAS"
for aliased nodes, and not the type of the node that it refers to. The patch
also fixes a bug in writeNode() that caused extra lines after alias entries.

If there's resistance to the change to getType() (David?) I can easily use
isAlias(). This just makes copyProperties() a tad uglier, but I can live with
it. It's useful for scanning a tree, though, if an alias node can be treated
exactly like all other nodes, without automatic redirection.
2004-12-19 10:19:14 +00:00
ehofman
7b24e94c66 gcc 4.0 fix. 2004-12-18 10:53:54 +00:00
ehofman
e12cd2a50c Initialize volume to inaudiable at startup. 2004-12-16 13:15:13 +00:00
curt
98b2ba4fc1 More prerelease updates. 2004-12-15 16:45:57 +00:00
curt
2f0afdccc1 Prerelease updates. 2004-12-15 16:34:14 +00:00
ehofman
79734df554 Threads detection code cleanup and FreeBSD fixes. 2004-12-13 20:31:44 +00:00
ehofman
c52657fa1a This was too quick, now pthreads isn't detected on IRIX (and other platforms?) anymore. This needs some more thought. 2004-12-08 15:12:11 +00:00
ehofman
9cac8409cd FreeBSD fix. 2004-12-08 15:00:45 +00:00
ehofman
18703ce02d AIX fix 2004-12-05 09:36:49 +00:00
curt
709a166bd6 Oops, 2nd try ... 2004-12-02 15:08:54 +00:00
curt
8048e6297c Martin Spott: Revised handling of missing isnan() on earlier versions of
FreeBSD.
2004-12-02 15:00:26 +00:00
curt
fb0dded103 Fix a typo for the Mac OSX platform. 2004-12-01 17:37:43 +00:00
curt
055e969e7a Fix a dumb bug. 2004-11-21 21:46:02 +00:00
curt
f10db8a30e Fix a dumb bug for FreeBSD. 2004-11-21 21:45:35 +00:00
ehofman
c19af3525e Melchior FRANZ:
At last I've found the reason why fgfs crashed routinely for me. When I still
used KDE's artsdsp (preloads lib with OSS replacement functions) I saw
this crash only occasionally. After letting OpenAl communicate with artsd
directly (by means of ~/.openalrc setting), I got the crash always when
I left fgfs.

This bug may also have crashed fgfs when running with sound daemons other than
aRts.
2004-11-21 17:05:42 +00:00
curt
7c60ccfc35 I don't understand why FreeBSD doesn't see isnan() after including math.h
but it doesn't.  Trying the apple approach to fixing isnan results in an
infinite loop (making me wonder what happens on OSX?)  This is an alternative
approach to checking isnan() on freebsd ...
2004-11-21 03:13:54 +00:00
curt
84cba33aab FreeBSD fix. 2004-11-20 19:11:08 +00:00
ehofman
a52b1ec64f MSVC fix. 2004-11-20 12:35:28 +00:00
curt
f30c4720ae Update a few more instances of my email address. 2004-11-19 21:47:05 +00:00
curt
7fc8c02688 My old email address is no longer valid ... point to my web page. 2004-11-19 21:44:16 +00:00
curt
54a7a0d534 Ooops, fix an unintentional line wrap. 2004-11-18 19:12:17 +00:00
curt
8d73160a75 Abstract out location of gl.h, glut.h, and glu.h includes so that we can
make the Mac platform happy since they put these in a different place compared
to the rest of the world.
2004-11-18 19:10:34 +00:00
andy
ff10602c65 Make sure that timer delay values are positive-definite, otherwise
user code that wants to use zero delay to mean "next frame" will get
stuck in an infinite loop.
2004-11-17 19:37:45 +00:00
ehofman
ca50fe386d Roy Vegard Ovesen:
I've added two new debug log types for the instrumentation and systems. They
used to use the autopilot debug log, because I couldn't figure out how to
make new log types. Well, now I have figured it out.  ;-)
2004-10-24 09:29:56 +00:00
ehofman
39f3c6e41d Frederic Bouvier:
This is a patch to make display list usage optional. They are on by default.
Use --prop:/sim/rendering/use-display-list=false to use immediate mode.
There is also a change in exception handling in main.cxx and bootstrap.cxx
2004-10-17 17:06:50 +00:00
ehofman
ba1b96e518 Roy Vegard Ovesen:
I'm working on a route manager in the GPS module. So I've added a name
parameter to the waypoint class in Simgear. I use the existing ID parameter
to store the ID, for example KLAX, and the name parameter to store the name,
San Francisco Intl.
2004-10-16 12:23:53 +00:00
ehofman
ef486b2cc6 Remove the refference to fgsg 2004-10-14 13:35:11 +00:00
curt
06f3cb4f8e Fix a couple bugs in openal detection. I should actually generate a new
configure and test it, rather than testing the old configure script.
2004-10-13 20:18:35 +00:00
curt
074f5ff996 Oops, missed a part of the previous change. 2004-10-13 19:52:13 +00:00
curt
8c26f32d5f Add a sanity check for the existance of OpenAL. If not there, bail from
the configure script with an appropriate/helpful message.
2004-10-13 19:51:38 +00:00
421 changed files with 37083 additions and 38816 deletions

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.3.7
PROJECT_NUMBER = 0.3.10
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
@@ -303,16 +303,19 @@ INPUT = \
simgear/compiler.h \
simgear/constants.h \
simgear/debug \
simgear/environment \
simgear/ephemeris \
simgear/io \
simgear/magvar \
simgear/math \
simgear/misc \
simgear/nasal \
simgear/props \
simgear/route \
simgear/scene \
simgear/screen \
simgear/serial \
simgear/structure \
simgear/sg_inlines.h \
simgear/sg_traits.hxx \
simgear/sound \

View File

@@ -4,13 +4,15 @@ EXTRA_DIST = \
DoxygenMain.cxx \
README.MSVC \
README.zlib \
projects \
SimGear.dsp \
SimGear.dsw
SUBDIRS = src-libs simgear
SUBDIRS = simgear
dist-hook:
(cd $(top_srcdir); $(HOME)/Projects/FlightGear-0.9/admin/am2dsp.pl)
(cd $(top_srcdir); $(HOME)/Projects/FlightGear/admin/am2dsp.pl)
rm -rf `find $(distdir)/projects -name CVS`
#
# Rule to build RPM distribution package

96
NEWS
View File

@@ -1,3 +1,83 @@
New in 0.3.10
* April 5, 2006
* Add a small accessor function to expose local timezone offset.
* Improved exception handling and made output more helpful in various places.
* Better pbuffer runtime detection.
* Add directory creation capability to file/path library.
* Added a basic reference counting class to improve robustness of
memory management in places. Use this for all scenegraph
references, sgmaterial references, sgmatmodel references, and
sgsoundsample references.
* Add support for point sprites.
* Updates to rain cone rendering.
* Add a new vector library and integrate that with improved coordinate
system conversion code.
* Mutex locking and cleanup improvements in the threading abstraction
library.
* Add MacOS RenderTexture support.
* Add a Nasal based io libarary that is not activated by default.
* Added a set of MS-VC8 project files.
* Various platform related bug fixes.
* Various compiler related bug/warning fixes.
* Clean up some things that triggered valgrind warnings.
* Fix a Nasal cmp() bug.
* Removed ancient version of zlib from distribution.
New in 0.3.9
* November 17, 2005
* Add support for OpenAL 1.1 (with a separate alut library.)
* Add support for volumetric shadows. Aircraft can cast shadows on themselves
as well as onto the ground (by Harald Johnsen.)
* New 3d volumetric clouds by Harald Johnsen (along with several rounds of
followup fixes and improvements.)
* Remove Mark Harris's old 3d clouds because they were never properly
integrated. And we now have new 3d clouds.
* Add support for seasonal textures (with a set of winter textures added
to FlightGear.)
* Updated Nasal scripting system. Adds several new syntax convenience
features, fixes parser bugs, fixes several internal bugs.
* Our 3d cockpit jitter problem is fixed (woohoo!)
* Add code to support rendering to a texture.
* Allow "tip" popups to pop themselves down after the appropriate
timeout, even if the sim time is paused.
* Various low model level animation fixes and additions ... color,
transparency, 'chrome' effects, randomized spin, etc.
* Create our own portable stdint.h implementation.
* Fixed several memory leaks.
* removeChildren() added to the property system.
* Fix many cases of 'const'.
* Fixes for cygwin, solaris/sun, Mac OS X, MSVC, gcc-3.4.x.
New in 0.3.8
* January 18, 2005
* Configure script does a sanity check for the existence of openal.
* Better pthreads detection for FreeBSD.
* Abstract out the location of gl.h, glu.h, and glut.h so we can more
easily support MacOS which puts these in an oddball location.
* Added two new debug output types for instrumentation and systems.
* Add a name parameter to the waypoint class for supporting a route
manager in the flightgear gps module.
* Make display list usage optional.
* Event manager: specifying a zero delay will force event execution in
the next frame rather than entering an infinite loop.
* gcc-4.0 fix.
* Fixes to property tree loading and saving.
* Make volume inaudible at startup.
* Solaris fixes.
* For low density cloud coverage, blend the layer to nothing as we pass
through instead of fully engulfing the aircraft in the cloud.
* Add several new capabilities to the texture management code for building
normal maps and doing some simple on-the-fly effects on textures.
* Better error message for sound problems.
* Add support for binding a thread to a specific CPU.
New in 0.3.7
* October 12, 2004
@@ -33,7 +113,7 @@ New in 0.3.5
* Support VASI/PAPI lights correctly.
* Fixes to cloud animation.
* Updates to sky dome coloring as well as sun/moon coloring.
* Vary environment lighting with visibility (subtlely.)
* Vary environment lighting with visibility (subtlety.)
* Support control of alpha test in model animation.
* Complete rewrite of the event manager.
* Updates to low level socket code to make it more flexible.
@@ -84,7 +164,7 @@ New in 0.3.2
management, basic model and model animation management, sky
rendering, and low level loaders for the "TerraGear" tile object format.
* Removed support of the flat shaded and non-textured material
property varients. You can still do these things, but extra states
property variants. You can still do these things, but extra states
are no longer set up automatically.
* Removed 3d clouds from the default build ... these need a maintainer
or better yet, a complete plib-based rewrite.
@@ -129,7 +209,7 @@ New in 0.2.0
* Removed efence support (in favor of valgrind.)
* Added a javascript interpreter.
* SGSocket reimplimented on top of plib/net libs.
* SGSocket reimplemented on top of plib/net libs.
* Added a new random number generation algorithm.
* Total rewrite of the strutils package.
@@ -139,7 +219,7 @@ New in 0.2.0
* Mac OS X fixes.
* Irix fixes.
* Code clean ups to remove warning messages.
* Optimizations in sg_binobj to reduce the amout of memory copying
* Optimizations in sg_binobj to reduce the amount of memory copying
needed when loading a binobj format file.
* Fixed a couple places where variables could be used before they were
initialized.
@@ -159,7 +239,7 @@ New in 0.0.18
* Upgrade to metakit-2.4.2-32.tar.gz (latest upstream release)
* Added support for point objects in the scenery file format.
* Additions to the binary file format to make it *much* more flexible.
For each major primative type: points, triangles, fans, and strips, you
For each major primitive type: points, triangles, fans, and strips, you
can specify an index list of vertices, normals, colors, and texture
coordinates. You can skip any of these you like to save on space.
* Added support for new file features in the binary -> ascii scenery file
@@ -210,7 +290,7 @@ New in 0.0.17pre1
New in 0.0.16
* July 12, 2001
* Various changes to the property manager implimentation to better support
* Various changes to the property manager implementation to better support
dumping out the desired portions of the property tree to file.
* Don't compile the metakit demos by default (causes problems for Irix)'
* Other various tweaks for Irix.
@@ -253,7 +333,7 @@ New in 0.0.15
read/write routines.
* Added doxygen comments for all public interface code. Documentation
can be accessed via the SimGear web page.
* Many FG -> SG name space changes for better consistancy throughout
* Many FG -> SG name space changes for better consistency throughout
this package.
* Added property aliases, repeated name tags, and a general xml
inclusion facilities. Many other property manager clean ups
@@ -344,4 +424,4 @@ New in 0.0.4
New in 0.0.3
* Release that conincides with FlightGear-0.7.2
* Release that coincides with FlightGear-0.7.2

12
README.OpenAL Normal file
View File

@@ -0,0 +1,12 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://www.openal.org
Build notes:
The OpenAL developers do not make "versioned" releases so we recommend that
you pull the latest version via anonymous CVS (follow the instructions at
the OpenAL web site) and build/install that.

View File

@@ -1,173 +1,8 @@
For your convenience and allowed by zlib's license terms:
http://www.gzip.org/zlib/zlib_license.html a copy of the zlib source
is bundled with SimGear in $(top_srcdir)/src-libs/. You must have
zlib installed before you can build SimGear.
zlib is prerequisite for compiling SimGear and FlightGear. You can fetch
the latest version of zlib from:
- Most linux distributions have a zlib package. For linux
developers, we recommend ysou install your distributions package
rather than building from source.
http://www.zlib.net
- Cygwin installs zlib automatically.
Most modern unix distributions (and cygwin) come with a version of zlib
already installed or available to install as a package.
- For developers on most other platforms, you will have to build
zlib from source and install it yourself. For your convenience a
tar ball of the zlib source is included with the simgear source
distribution. Untar the zlib source, and follow the included
build and installation instructions.
Once zlib is installed you can return to configuring and building
Simgear.
We now send you to the official zlib README ...
=============================================================================
zlib 1.1.4 is a general purpose data compression library. All the code
is thread safe. The data format used by the zlib library
is described by RFCs (Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
format) and rfc1952.txt (gzip format). These documents are also available in
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
example of the library is given in the file example.c which also tests that
the library is working correctly. Another example is given in the file
minigzip.c. The compression library itself is composed of all source files
except example.c and minigzip.c.
To compile all files and run the test program, follow the instructions
given at the top of Makefile. In short "make test; make install"
should work for most machines. For Unix: "./configure; make test; make install"
For MSDOS, use one of the special makefiles such as Makefile.msc.
For VMS, use Make_vms.com or descrip.mms.
Questions about zlib should be sent to <zlib@gzip.org>, or to
Gilles Vollant <info@winimage.com> for the Windows DLL version.
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
Before reporting a problem, please check this site to verify that
you have the latest version of zlib; otherwise get the latest version and
check whether the problem still exists or not.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
before asking for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.1.4 are documented in the file ChangeLog.
The only changes made since 1.1.3 are bug corrections:
- ZFREE was repeated on same allocation on some error conditions.
This creates a security problem described in
http://www.zlib.org/advisory-2002-03-11.txt
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
- Avoid accesses before window for invalid distances with inflate window
less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5).
The beta version 1.1.5beta includes many more changes. A new official
version 1.1.5 will be released as soon as extensive testing has been
completed on it.
Unsupported third party contributions are provided in directory "contrib".
A Java implementation of zlib is available in the Java Development Kit
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
See the zlib home page http://www.zlib.org for details.
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
is in the CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
is available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
An experimental package to read and write files in .zip format,
written on top of zlib by Gilles Vollant <info@winimage.com>, is
available at http://www.winimage.com/zLibDll/unzip.html
and also in the contrib/minizip directory of zlib.
Notes for some targets:
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
The zlib DLL support was initially done by Alessandro Iacopetti and is
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
home page at http://www.winimage.com/zLibDll
From Visual Basic, you can call the DLL functions which do not take
a structure as argument: compress, uncompress and all gz* functions.
See contrib/visual-basic.txt for more information, or get
http://www.tcfb.com/dowseware/cmp-z-it.zip
- For 64-bit Irix, deflate.c must be compiled without any optimization.
With -O, one libpng test fails. The test works in 32 bit mode (with
the -n32 compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
it works when compiled with cc.
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
is necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
with other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
- For Turbo C the small model is supported only with reduced performance to
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
Per Harald Myrvang <perm@stud.cs.uit.no>
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate
and zlib specifications were written by L. Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib;
they are too numerous to cite here.
Copyright notice:
(C) 1995-2002 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
If you use the zlib library in a product, we would appreciate *not*
receiving lengthy legal documents to sign. The sources are provided
for free but without warranty of any kind. The library has been
entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.
If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes.

File diff suppressed because it is too large Load Diff

View File

@@ -15,30 +15,6 @@ Package=<4>
###############################################################################
Project: "mklib"=".\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "zlib"=".\SimGear\zlib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>

25
Thanks
View File

@@ -47,6 +47,18 @@ Jean-Francois Doue
http://www.animats.com/simpleppp/ftp/public_html/topics/developers.html
Melchior Franz
METAR parser and fetcher. "material" animation (based on Jim Wilsons's
"emission" animation). Debugging and extension of property listener
features. Addition of removeChildren.
Mathias Froehlich
Reworked and cleaned up large parts of the infrastructure, of math
files, animations and rendering in preparation of a transition to
the OSG library. Added new handlers for shared and referenced objects.
Bruce Finney <bfinney@gte.net>
MSVC5 compatibility.
@@ -71,6 +83,10 @@ Bruce Jackson of NASA <e.b.jackson@larc.nasa.gov>
http://dcb.larc.nasa.gov/www/DCBStaff/ebj/ebj.html
Maik Justus
Fixed an old bug in the SGPropertyNode class.
Richard Kaszeta <bofh@me.umn.edu>
Contributed screen buffer to ppm screen shot routine.
Rich has also helped in the early development of the Flight Gear "altitude
@@ -90,7 +106,12 @@ David Megginson <david@megginson.com>
SimGear property manager/registry
Curt Olson <curt@flightgear.org>
Tim Moore
Ported the (chrome) "shader" animation to OSG, and helped with porting
the "material" animation.
Curt Olson http://www.flightgear.org/~curt/
Curt is responsible for overall project and source code management.
He has his hands in many of the areas.
@@ -175,7 +196,7 @@ NOTE:
----
THIS DOCUMENT WAS INITIALLY WRITTEN BY
Curt L. Olson <curt@flightgear.org>
Curt L. Olson <http://www.flightgear.org/~curt>
05 Jul 2000 Removed non-SimGear entries (CLO)

View File

@@ -3,7 +3,7 @@ dnl originally from ncftp 2.3.0
dnl added wi_EXTRA_PDIR and wi_ANSI_C
dnl $Id$
dnl
AC_DEFUN(wi_EXTRA_IDIR, [
AC_DEFUN([wi_EXTRA_IDIR], [
incdir="$1"
if test -r $incdir ; then
case "$CPPFLAGS" in
@@ -25,7 +25,7 @@ dnl
dnl
dnl
dnl
AC_DEFUN(wi_EXTRA_LDIR, [
AC_DEFUN([wi_EXTRA_LDIR], [
mylibdir="$1"
if test -r $mylibdir ; then
case "$LDFLAGS" in
@@ -47,7 +47,7 @@ dnl
dnl __FP__
dnl
dnl
AC_DEFUN(wi_EXTRA_PDIR, [
AC_DEFUN([wi_EXTRA_PDIR], [
progdir="$1"
if test -r $progdir ; then
case "$PATH" in
@@ -76,7 +76,7 @@ dnl
dnl If you want to look for subdirectories in include/lib directories,
dnl you pass the names in argument 3, otherwise pass a dash.
dnl
AC_DEFUN(wi_EXTRA_DIRS, [echo "checking for extra include and lib directories..." 1>&6
AC_DEFUN([wi_EXTRA_DIRS], [echo "checking for extra include and lib directories..." 1>&6
ifelse([$1], yes, [dnl
b1=`cd .. ; pwd`
b2=`cd ../.. ; pwd`
@@ -111,7 +111,7 @@ done
dnl
dnl
dnl
AC_DEFUN(wi_HPUX_CFLAGS,
AC_DEFUN([wi_HPUX_CFLAGS],
[AC_MSG_CHECKING(if HP-UX ansi C compiler flags are needed)
AC_REQUIRE([AC_PROG_CC])
os=`uname -s | tr '[A-Z]' '[a-z]'`
@@ -144,7 +144,7 @@ AC_MSG_RESULT($ac_cv_hpux_flags)
dnl
dnl
dnl
AC_DEFUN(wi_CFLAGS, [AC_REQUIRE([AC_PROG_CC])
AC_DEFUN([wi_CFLAGS], [AC_REQUIRE([AC_PROG_CC])
wi_HPUX_CFLAGS
if test "$CFLAGS" = "" ; then
CFLAGS="-O"
@@ -165,7 +165,7 @@ wi_HPUX_CFLAGS
dnl
dnl
dnl
AC_DEFUN(wi_PROTOTYPES, [
AC_DEFUN([wi_PROTOTYPES], [
AC_MSG_CHECKING(if the compiler supports function prototypes)
AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes
AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no)
@@ -174,7 +174,7 @@ AC_MSG_RESULT($wi_cv_prototypes)
dnl
dnl
dnl
AC_DEFUN(wi_ANSI_C, [
AC_DEFUN([wi_ANSI_C], [
AC_MSG_CHECKING(ANSI-style function definitions)
AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes
AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no)
@@ -183,7 +183,7 @@ AC_MSG_RESULT($wi_cv_ansi_funcs)
dnl
dnl
dnl
AC_DEFUN(wi_HEADER_SYS_SELECT_H, [
AC_DEFUN([wi_HEADER_SYS_SELECT_H], [
# See if <sys/select.h> is includable after <sys/time.h>
if test "$ac_cv_header_sys_time_h" = no ; then
AC_CHECK_HEADERS(sys/time.h sys/select.h)
@@ -211,7 +211,7 @@ fi
dnl
dnl
dnl
AC_DEFUN(wi_LIB_RESOLV, [
AC_DEFUN([wi_LIB_RESOLV], [
# See if we could access two well-known sites without help of any special
# libraries, like resolv.
@@ -244,7 +244,7 @@ dnl
dnl
dnl
AC_DEFUN(wi_LIB_NSL, [
AC_DEFUN([wi_LIB_NSL], [
AC_MSG_CHECKING(if we can use -lnsl)
ac_save_LIBS="$LIBS";
LIBS="$LIBS -lnsl";
@@ -261,7 +261,7 @@ dnl
dnl
dnl
AC_DEFUN(nc_PATH_PROG_ZCAT, [
AC_DEFUN([nc_PATH_PROG_ZCAT], [
AC_PATH_PROG(GZCAT,gzcat)
AC_PATH_PROG(ZCAT,zcat)
if test "x$GZCAT" = x ; then
@@ -287,7 +287,7 @@ fi
dnl
dnl
dnl
AC_DEFUN(wi_SYSV_EXTRA_DIRS, [
AC_DEFUN([wi_SYSV_EXTRA_DIRS], [
# Use System V because their curses extensions are required. This must
# be done early so we use the -I and -L in the library checks also.
# This is mostly a Solaris/SunOS hack. Note that doing this will also
@@ -305,7 +305,7 @@ fi
dnl
dnl
dnl
AC_DEFUN(wi_DEFINE_UNAME, [
AC_DEFUN([wi_DEFINE_UNAME], [
# Get first 127 chars of all uname information. Some folks have
# way too much stuff there, so grab only the first 127.
unam=`uname -a 2>/dev/null | cut -c1-127`
@@ -316,7 +316,7 @@ fi
dnl
dnl
dnl
AC_DEFUN(wi_READLINE_WITH_NCURSES, [
AC_DEFUN([wi_READLINE_WITH_NCURSES], [
# Readline and Ncurses could both define "backspace".
# Warn about this if we have both things in our definitions list.
@@ -352,7 +352,7 @@ dnl
dnl AC_EXT_DAYLIGHT
dnl Check for an external variable daylight. Stolen from w3c-libwww.
AC_DEFUN(AC_EXT_DAYLIGHT,
AC_DEFUN([AC_EXT_DAYLIGHT],
[ AC_MSG_CHECKING(int daylight variable)
AC_TRY_COMPILE([#include <time.h>], [return daylight;],
have_daylight=yes,
@@ -362,7 +362,7 @@ AC_MSG_RESULT($have_daylight)
dnl AC_EXT_TIMEZONE
dnl Check for an external variable timezone. Stolen from tcl-8.0.
AC_DEFUN(AC_EXT_TIMEZONE,
AC_DEFUN([AC_EXT_TIMEZONE],
[
#
# Its important to include time.h in this check, as some systems (like convex)
@@ -395,7 +395,7 @@ fi
## AC_BZ_SET_COMPILER: Addition by Theodore Papadopoulo
## Patch by Jim McKelvey: change sed -e 's/ /@/g' to sed -e 's/ /@/'
AC_DEFUN(AC_SG_SET_COMPILER,
AC_DEFUN([AC_SG_SET_COMPILER],
[cxxwith=`echo $1 | sed -e 's/ /@/'`
case "$cxxwith" in
*:*@*) # Full initialization syntax

View File

@@ -4,14 +4,13 @@ exclude_dir = threads
include_path = .
include_path = ..
include_path = .\SimGear
include_path = .\SimGear\metakit-2.4.3\include
include_path = ..\SimGear\zlib-1.1.4
include_path = ..\zlib-1.2.3
include_path = "..\OpenAL 1.0 Software Development Kit\include"
define = _USE_MATH_DEFINES
define = _CRT_SECURE_NO_DEPRECATE
define = HAVE_CONFIG_H
add_project = .\SimGear\metakit-2.4.3\win\msvc60\mklib.dsp,mklib
add_project = .\SimGear\zlib.dsp,zlib
# Rule to create simgear_config.h
add_source_file = SOURCE=.\simgear\simgear_config.h.vc5\
\

View File

@@ -1,7 +1,5 @@
dnl Process this file with autoget.sh to produce a working configure
dnl script.
dnl
dnl $Id$
AC_INIT
AC_CONFIG_SRCDIR([simgear/bucket/newbucket.cxx])
@@ -10,7 +8,7 @@ dnl Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.3.7)
AM_INIT_AUTOMAKE(SimGear, 0.3.10)
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
@@ -121,9 +119,17 @@ if test "x$with_plib" != "x" ; then
EXTRA_DIRS="${EXTRA_DIRS} $with_plib"
fi
# specify the osg location
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
if test "x$with_osg" != "x" ; then
echo "osg prefix is $with_osg"
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi
dnl Determine an extra directories to add to include/lib search paths
case "${host}" in
*-apple-darwin* | *-*-mingw32*)
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
echo no EXTRA_DIRS for $host
;;
@@ -165,33 +171,18 @@ dnl Checks for libraries.
dnl Thread related checks
AC_CHECK_HEADER(pthread.h)
AC_CHECK_LIB(pthread, pthread_exit)
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
AC_SEARCH_LIBS(pthread_exit, [pthread c_r])
if test "x$ac_cv_header_pthread_h" = "xyes"; then
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
CFLAGS="$CFLAGS -D_REENTRANT"
fi
if test "x$ac_cv_lib_pthread_pthread_exit" != "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
dnl FreeBSD: System has pthread.h, but -lpthread library check
dnl fails. See if we need -pthread instead of -lpthread and look
dnl for the functions in libc_r.
save_CXXFLAGS="$CXXFLAGS"
save_CFLAGS="$CFLAGS"
if test "x$ac_cv_search_pthread_exit" = "x-lc_r"; then
CXXFLAGS="-pthread $CXXFLAGS"
CFLAGS="-pthread $FLAGS"
save_LIBS=$LIBS
AC_CHECK_LIB(c_r, pthread_exit)
if test "x$ac_cv_lib_c_r_pthread_exit" != "xyes"; then
CXXFLAGS=$save_CXXFLAGS
CFLAGS=$save_CFLAGS
else
dnl This is cheating a bit. pthread_exit comes with using -pthread, not
-lpthread
ac_cv_lib_pthread_pthread_exit="yes"
fi
LIBS=$save_LIBS
CFLAGS="-pthread $CFLAGS"
fi
fi
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes")
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_header_pthread_h" = "xyes")
thread_LIBS="$LIBS"
LIBS=""
@@ -267,34 +258,60 @@ case "${host}" in
esac
AC_SEARCH_LIBS(glutGetModifiers, [ glut glut32 freeglut ], have_glut=yes, have_glut=no)
AM_CONDITIONAL(HAVE_GLUT, test "x$have_glut" = "xyes")
opengl_LIBS="$LIBS"
LIBS="$base_LIBS"
dnl check for OpenAL libraries
OPENAL_OK="no"
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
AC_SEARCH_LIBS(alGenBuffers, openal32)
AC_SEARCH_LIBS(alutInit, [ openal32 ALut ] )
INCLUDES="$INCLUDES -I/usr/local/include/"
LIBS="$LIBS -L/usr/local/lib"
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"
;;
*-apple-darwin*)
dnl Mac OS X
LIBS="$LIBS -framework IOKit -framework OpenAL"
openal_LIBS="$LIBS"
# not sure how to test if OpenAL exists on MacOS (does it come by default?)
OPENAL_OK="yes"
;;
*)
dnl default unix style machines
save_LIBS=$LIBS
LIBS="$LIBS $thread_LIBS"
AC_SEARCH_LIBS(alGenBuffers, openal)
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
OPENAL_OK="$ac_cv_search_alGenBuffers"
openal_LIBS="$LIBS"
LIBS=$save_LIBS
;;
esac
openal_LIBS="$LIBS"
if test "$OPENAL_OK" == "no"; then
echo
echo "You *must* have the openal library installed on your system to build"
echo "SimGear!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
LIBS="$base_LIBS"
AC_SUBST(base_LIBS)
@@ -325,11 +342,11 @@ if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
exit
fi
AC_MSG_CHECKING([for plib 1.6.0 or newer])
AC_MSG_CHECKING([for plib 1.8.4 or newer])
AC_TRY_RUN([
#include <plib/ul.h>
#define MIN_PLIB_VERSION 160
#define MIN_PLIB_VERSION 184
int main() {
int major, minor, micro;
@@ -344,7 +361,7 @@ int main() {
],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(wrong version);
AC_MSG_ERROR([Install plib 1.6.0 or later first...])],
AC_MSG_ERROR([Install plib 1.8.4 or later first...])],
AC_MSG_RESULT(yes)
)
@@ -381,6 +398,7 @@ fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_MODE_T
AC_HEADER_TIME
AC_STRUCT_TM
@@ -399,7 +417,6 @@ AM_CONFIG_HEADER(simgear/simgear_config.h)
AC_CONFIG_FILES([ \
Makefile \
SimGear.spec \
src-libs/Makefile \
simgear/Makefile \
simgear/version.h \
simgear/compatibility/Makefile \
@@ -417,19 +434,17 @@ AC_CONFIG_FILES([ \
simgear/props/Makefile \
simgear/route/Makefile \
simgear/scene/Makefile \
simgear/scene/fgsg/Makefile \
simgear/scene/material/Makefile \
simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \
simgear/scene/sky/clouds3d/Makefile \
simgear/scene/tgdb/Makefile \
simgear/scene/util/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sound/Makefile \
simgear/structure/Makefile \
simgear/threads/Makefile \
simgear/timing/Makefile \
simgear/xgl/Makefile \
simgear/xml/Makefile \
])
AC_OUTPUT
@@ -456,7 +471,7 @@ else
echo "Without JPEG Factory support"
fi
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
if test "x$ac_cv_header_pthread_h" = "xyes"; then
echo "Threads: pthread lib found."
else
echo "Threads: no threads (pthread lib not found.)"

4
projects/VC7.1/.cvsignore Executable file
View File

@@ -0,0 +1,4 @@
Debug
Release
SimGear.ncb
SimGear.suo

21
projects/VC7.1/SimGear.sln Executable file
View File

@@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.ActiveCfg = Debug|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.Build.0 = Debug|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.ActiveCfg = Release|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

1079
projects/VC7.1/SimGear.vcproj Executable file

File diff suppressed because it is too large Load Diff

20
projects/VC8/SimGear.sln Executable file
View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "SimGear.vcproj", "{952B5B5B-7FC8-4AE9-A664-333322BEEEB0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{952B5B5B-7FC8-4AE9-A664-333322BEEEB0}.Debug|Win32.ActiveCfg = Debug|Win32
{952B5B5B-7FC8-4AE9-A664-333322BEEEB0}.Debug|Win32.Build.0 = Debug|Win32
{952B5B5B-7FC8-4AE9-A664-333322BEEEB0}.Release|Win32.ActiveCfg = Release|Win32
{952B5B5B-7FC8-4AE9-A664-333322BEEEB0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

1348
projects/VC8/SimGear.vcproj Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ endif
# METAR_DIRS =
METAR_DIRS = environment
EXTRA_DIST = simgear_config.h.vc5 version.h.in
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
include_HEADERS = \
compiler.h constants.h sg_inlines.h sg_traits.hxx version.h
@@ -32,7 +32,6 @@ SUBDIRS = \
serial \
sound \
$(SGTHREAD_DIR) \
timing \
xgl
timing
DIST_SUBDIRS = $(SUBDIRS) compatibility threads
DIST_SUBDIRS = $(SUBDIRS) compatibility

View File

@@ -3,7 +3,7 @@
*
* Written by Curtis L. Olson, started February 1999.
*
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
* Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -45,6 +44,9 @@ SGBucket::SGBucket(const double dlon, const double dlat) {
set_bucket(dlon, dlat);
}
SGBucket::SGBucket(const SGGeod& geod) {
set_bucket(geod);
}
// create an impossible bucket if false
SGBucket::SGBucket(const bool is_good) {
@@ -74,11 +76,6 @@ SGBucket::SGBucket(const long int bindex) {
}
// default destructor
SGBucket::~SGBucket() {
}
// Set the bucket params for the specified lat and lon
void SGBucket::set_bucket( double *lonlat ) {
set_bucket( lonlat[0], lonlat[1] );
@@ -136,6 +133,11 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
}
void SGBucket::set_bucket(const SGGeod& geod)
{
set_bucket(geod.getLongitudeDeg(), geod.getLatitudeDeg());
}
// Build the path name for this bucket
string SGBucket::gen_base_path() const {
// long int index;
@@ -208,7 +210,7 @@ double SGBucket::get_width_m() const {
double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
double cos_lat = cos( clat_rad );
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
double local_perimeter = 2.0 * local_radius * SGD_PI;
double local_perimeter = local_radius * SGD_2PI;
double degree_width = local_perimeter / 360.0;
return sg_bucket_span( get_center_lat() ) * degree_width;
@@ -217,7 +219,7 @@ double SGBucket::get_width_m() const {
// return height of the tile in meters
double SGBucket::get_height_m() const {
double perimeter = 2.0 * SG_EQUATORIAL_RADIUS_M * SGD_PI;
double perimeter = SG_EQUATORIAL_RADIUS_M * SGD_2PI;
double degree_height = perimeter / 360.0;
return SG_BUCKET_SPAN * degree_height;
@@ -271,16 +273,32 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
#endif
// longitude difference
double c1_lon = b1.get_center_lon();
double c2_lon = b2.get_center_lon();
double diff_lon = c2_lon - c1_lon;
double span;
if ( sg_bucket_span(c1_lat) <= sg_bucket_span(c2_lat) ) {
double diff_lon=0.0;
double span=0.0;
SGBucket tmp_bucket;
// To handle crossing the bucket size boundary
// we need to account for different size buckets.
if ( sg_bucket_span(c1_lat) <= sg_bucket_span(c2_lat) )
{
span = sg_bucket_span(c1_lat);
} else {
span = sg_bucket_span(c2_lat);
}
diff_lon = b2.get_center_lon() - b1.get_center_lon();
if (diff_lon <0.0)
{
diff_lon -= b1.get_width()*0.5 + b2.get_width()*0.5 - span;
}
else
{
diff_lon += b1.get_width()*0.5 + b2.get_width()*0.5 - span;
}
#ifdef HAVE_RINT
*dx = (int)rint( diff_lon / span );
#else

View File

@@ -3,7 +3,7 @@
*
* Written by Curtis L. Olson, started February 1999.
*
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
* Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -32,6 +31,7 @@
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/math/SGMath.hxx>
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
@@ -115,10 +115,10 @@ class SGBucket {
private:
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
int lon; // longitude index (-180 to 179)
int lat; // latitude index (-90 to 89)
int x; // x subdivision (0 to 7)
int y; // y subdivision (0 to 7)
short lon; // longitude index (-180 to 179)
short lat; // latitude index (-90 to 89)
char x; // x subdivision (0 to 7)
char y; // y subdivision (0 to 7)
public:
@@ -134,6 +134,13 @@ public:
*/
SGBucket(const double dlon, const double dlat);
/**
* Construct a bucket given a specific location.
* @param dlon longitude specified in degrees
* @param dlat latitude specified in degrees
*/
SGBucket(const SGGeod& geod);
/** Construct a bucket.
* @param is_good if false, create an invalid bucket. This is
* useful * if you are comparing cur_bucket to last_bucket and
@@ -147,11 +154,6 @@ public:
*/
SGBucket(const long int bindex);
/**
* Default destructor.
*/
~SGBucket();
/**
* Reset a bucket to represent a new lat and lon
* @param dlon longitude specified in degrees
@@ -166,6 +168,13 @@ public:
*/
void set_bucket( double *lonlat );
/**
* Reset a bucket to represent a new lat and lon
* @param dlon longitude specified in degrees
* @param dlat latitude specified in degrees
*/
void set_bucket(const SGGeod& geod);
/**
* Create an impossible bucket.
* This is useful if you are comparing cur_bucket to last_bucket
@@ -253,7 +262,24 @@ public:
* @return the height of the tile in meters.
*/
double get_height_m() const;
/**
* @return the center of the bucket in geodetic coordinates.
*/
SGGeod get_center() const
{ return SGGeod::fromDeg(get_center_lon(), get_center_lat()); }
/**
* @return the center of the bucket in geodetic coordinates.
*/
SGGeod get_corner(unsigned num) const
{
double lonFac = ((num + 1) & 2) ? 0.5 : -0.5;
double latFac = ((num ) & 2) ? 0.5 : -0.5;
return SGGeod::fromDeg(get_center_lon() + lonFac*get_width(),
get_center_lat() + latFac*get_height());
}
// Informational methods.
/**

View File

@@ -11,10 +11,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
*
@@ -121,7 +120,7 @@
# define STL_STRSTREAM <strstream>
# endif
# elif __GNUC__ == 3
# elif __GNUC__ >= 3
// g++-3.0.x
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_NEED_AUTO_PTR
@@ -231,6 +230,7 @@
# define isnan _isnan
# define snprintf _snprintf
# define copysign _copysign
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
# pragma warning(disable: 4244) // conversion from double to float
@@ -324,7 +324,7 @@
#endif // Native SGI compilers
#if defined ( sun )
#if defined (__sun)
# include <strings.h>
# include <memory.h>
# if defined ( __cplusplus )
@@ -336,7 +336,9 @@
extern void *memmove(void *, const void *, size_t);
# endif // __cplusplus
# define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
# if !defined( __GNUC__ )
# define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
# endif
#endif // sun
@@ -364,6 +366,27 @@
#endif // __ICC
//
// Platform dependent gl.h and glut.h definitions
//
#ifdef __APPLE__
# define SG_GL_H <OpenGL/gl.h>
# define SG_GLX_H <AGL/agl.h>
# define SG_GLU_H <OpenGL/glu.h>
# define SG_GLEXT_H <OpenGL/glext.h>
# define SG_GLUT_H <GLUT/glut.h>
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
#else
# define SG_GL_H <GL/gl.h>
# define SG_GLX_H <GL/glx.h>
# define SG_GLU_H <GL/glu.h>
# define SG_GLEXT_H <GL/glext.h>
# define SG_GLUT_H <GL/glut.h>
#endif
//
// No user modifiable definitions beyond here.
//
@@ -445,3 +468,4 @@ inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
#endif // SG_INCOMPLETE_FUNCTIONAL
#endif // _SG_COMPILER_H

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started February 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -14,10 +14,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -129,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

View File

@@ -25,7 +25,9 @@ typedef enum {
SG_NETWORK = 0x00004000,
SG_ATC = 0x00008000,
SG_NASAL = 0x00010000,
SG_UNDEFD = 0x00020000, // For range checking
SG_INSTR = 0x00020000,
SG_SYSTEMS = 0x00040000,
SG_UNDEFD = 0x00080000, // For range checking
SG_ALL = 0xFFFFFFFF
} sgDebugClass;

View File

@@ -14,10 +14,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -26,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;

View File

@@ -16,10 +16,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -140,6 +139,10 @@ public:
*/
void set_sb( streambuf* sb );
#ifdef _MSC_VER
static void has_no_console() { has_console = false; }
#endif
protected:
/** sync/flush */
@@ -155,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;
@@ -185,7 +191,6 @@ inline logbuf::int_type
logbuf::overflow( int c )
{
#ifdef _MSC_VER
static has_console = false;
if ( logging_enabled ) {
if ( !has_console ) {
AllocConsole();
@@ -194,7 +199,7 @@ logbuf::overflow( int c )
freopen("conout$", "w", stderr);
has_console = true;
}
sbuf->sputc(c);
return sbuf->sputc(c);
}
else
return EOF == 0 ? 1: 0;
@@ -317,6 +322,9 @@ sglog()
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
#endif
#define SG_STRINGIFY(x) #x
#define SG_TOSTRING(x) SG_STRINGIFY(x)
#define SG_ORIGIN __FILE__ ":" SG_TOSTRING(__LINE__)
#endif // _LOGSTREAM_H

View File

@@ -2,8 +2,8 @@ includedir = @includedir@/environment
lib_LIBRARIES = libsgenvironment.a
include_HEADERS = metar.hxx
include_HEADERS = metar.hxx visual_enviro.hxx
libsgenvironment_a_SOURCES = metar.cxx
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -24,8 +24,12 @@
* @file metar.cxx
* Interface for encoded Meteorological Aerodrome Reports (METAR).
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <string>
#include <time.h>
#include <simgear/io/sg_socket.hxx>
#include <simgear/debug/logstream.hxx>
@@ -59,8 +63,10 @@
* double d = n.getDewpoint_C();
* @endcode
*/
SGMetar::SGMetar(const string& m, const string& proxy, const string& port, const string& auth) :
SGMetar::SGMetar(const string& m, const string& proxy, const string& port,
const string& auth, const time_t time) :
_grpcount(0),
_x_proxy(false),
_year(-1),
_month(-1),
_day(-1),
@@ -74,13 +80,17 @@ SGMetar::SGMetar(const string& m, const string& proxy, const string& port, const
_wind_range_to(-1),
_temp(NaN),
_dewp(NaN),
_pressure(NaN)
_pressure(NaN),
_rain(false),
_hail(false),
_snow(false),
_cavok(false)
{
if (m.length() == 4 && isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3])) {
for (int i = 0; i < 4; i++)
_icao[i] = toupper(m[i]);
_icao[4] = '\0';
_data = loadData(_icao, proxy, port, auth);
_data = loadData(_icao, proxy, port, auth, time);
} else {
_data = new char[m.length() + 2]; // make room for " \0"
strcpy(_data, m.c_str());
@@ -92,14 +102,15 @@ SGMetar::SGMetar(const string& m, const string& proxy, const string& port, const
_icao[0] = '\0';
// NOAA preample
scanPreambleDate();
if (!scanPreambleDate())
useCurrentDate();
scanPreambleTime();
// METAR header
scanType();
if (!scanId() || !scanDate()) {
delete[] _data;
throw sg_io_exception("metar data bogus (" + _url + ')');
throw sg_io_exception("metar data bogus ", sg_location(_url));
}
scanModifier();
@@ -125,8 +136,9 @@ SGMetar::SGMetar(const string& m, const string& proxy, const string& port, const
if (_grpcount < 4) {
delete[] _data;
throw sg_io_exception("metar data incomplete (" + _url + ')');
throw sg_io_exception("metar data incomplete ", sg_location(_url));
}
_url = "";
}
@@ -143,6 +155,20 @@ SGMetar::~SGMetar()
}
void SGMetar::useCurrentDate()
{
struct tm now;
time_t now_sec = time(0);
#if defined( _MSC_VER ) || defined ( __MINGW32__ )
now = *gmtime(&now_sec);
#else
gmtime_r(&now_sec, &now);
#endif
_year = now.tm_year + 1900;
_month = now.tm_mon + 1;
}
/**
* If called with "KSFO" loads data from
* @code
@@ -157,10 +183,15 @@ SGMetar::~SGMetar()
* @return pointer to Metar data string, allocated by new char[].
* @see rfc2068.txt for proxy spec ("Proxy-Authorization")
*/
char *SGMetar::loadData(const char *id, const string& proxy, const string& port, const string& auth)
char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
const string& auth, time_t time)
{
const int buflen = 512;
char buf[2 * buflen];
string host = proxy.empty() ? "weather.noaa.gov" : proxy;
string path = "/pub/data/observations/metar/stations/";
path += string(id) + ".TXT";
_url = "http://weather.noaa.gov" + path;
@@ -168,30 +199,31 @@ char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
sock->set_timeout(10000);
if (!sock->open(SG_IO_OUT)) {
delete sock;
throw sg_io_exception("cannot connect to " + host);
throw sg_io_exception("cannot connect to ", sg_location(host));
}
string get = "GET ";
if (!proxy.empty())
get += "http://weather.noaa.gov";
get += path + " HTTP/1.0\r\n";
sprintf(buf, "%ld", time);
get += path + " HTTP/1.0\015\012X-Time: " + buf + "\015\012";
if (!auth.empty())
get += "Proxy-Authorization: " + auth + "\015\012";
get += "\015\012";
sock->writestring(get.c_str());
if (!auth.empty()) {
get = "Proxy-Authorization: " + auth + "\r\n";
sock->writestring(get.c_str());
}
sock->writestring("\r\n");
int i;
const int buflen = 512;
char buf[2 * buflen];
// skip HTTP header
while ((i = sock->readline(buf, buflen)))
while ((i = sock->readline(buf, buflen))) {
if (i <= 2 && isspace(buf[0]) && (!buf[1] || isspace(buf[1])))
break;
if (!strncmp(buf, "X-MetarProxy: ", 13))
_x_proxy = true;
}
if (i) {
i = sock->readline(buf, buflen);
if (i)
@@ -204,7 +236,8 @@ char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
char *b = buf;
scanBoundary(&b);
if (*b == '<')
throw sg_io_exception("no metar data available from " + _url);
throw sg_io_exception("no metar data available from ",
sg_location(_url));
char *metar = new char[strlen(b) + 2]; // make room for " \0"
strcpy(metar, b);
@@ -392,7 +425,7 @@ bool SGMetar::scanWind()
if (gust != NaN)
_gust_speed = gust * factor;
_grpcount++;
return false;
return true;
}
@@ -579,56 +612,56 @@ bool SGMetar::scanRwyVisRange()
static const struct Token special[] = {
"NSW", "no significant weather",
"VCSH", "showers in the vicinity",
"VCTS", "thunderstorm in the vicinity",
0, 0
{ "NSW", "no significant weather" },
{ "VCSH", "showers in the vicinity" },
{ "VCTS", "thunderstorm in the vicinity" },
{ 0, 0 }
};
static const struct Token description[] = {
"SH", "showers of",
"TS", "thunderstorm with",
"BC", "patches of",
"BL", "blowing",
"DR", "low drifting",
"FZ", "freezing",
"MI", "shallow",
"PR", "partial",
0, 0
{ "SH", "showers of" },
{ "TS", "thunderstorm with" },
{ "BC", "patches of" },
{ "BL", "blowing" },
{ "DR", "low drifting" },
{ "FZ", "freezing" },
{ "MI", "shallow" },
{ "PR", "partial" },
{ 0, 0 }
};
static const struct Token phenomenon[] = {
"DZ", "drizzle",
"GR", "hail",
"GS", "small hail and/or snow pellets",
"IC", "ice crystals",
"PE", "ice pellets",
"RA", "rain",
"SG", "snow grains",
"SN", "snow",
"UP", "unknown precipitation",
"BR", "mist",
"DU", "widespread dust",
"SG", "fog",
"SGBR", "fog bank",
"FU", "smoke",
"HZ", "haze",
"PY", "spray",
"SA", "sand",
"VA", "volcanic ash",
"DS", "duststorm",
"FC", "funnel cloud/tornado waterspout",
"PO", "well-developed dust/sand whirls",
"SQ", "squalls",
"SS", "sandstorm",
"UP", "unknown", // ... due to failed automatic acquisition
0, 0
{ "DZ", "drizzle" },
{ "GR", "hail" },
{ "GS", "small hail and/or snow pellets" },
{ "IC", "ice crystals" },
{ "PE", "ice pellets" },
{ "RA", "rain" },
{ "SG", "snow grains" },
{ "SN", "snow" },
{ "UP", "unknown precipitation" },
{ "BR", "mist" },
{ "DU", "widespread dust" },
{ "FG", "fog" },
{ "FGBR", "fog bank" },
{ "FU", "smoke" },
{ "HZ", "haze" },
{ "PY", "spray" },
{ "SA", "sand" },
{ "VA", "volcanic ash" },
{ "DS", "duststorm" },
{ "FC", "funnel cloud/tornado waterspout" },
{ "PO", "well-developed dust/sand whirls" },
{ "SQ", "squalls" },
{ "SS", "sandstorm" },
{ "UP", "unknown" }, // ... due to failed automatic acquisition
{ 0, 0 }
};
// (+|-|VC)?(NSW|MI|PR|BC|DR|BL|SH|TS|FZ)?((DZ|RA|SN|SG|IC|PE|GR|GS|UP){0,3})(BR|SG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS){0,3}
// (+|-|VC)?(NSW|MI|PR|BC|DR|BL|SH|TS|FZ)?((DZ|RA|SN|SG|IC|PE|GR|GS|UP){0,3})(BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS){0,3}
bool SGMetar::scanWeather()
{
char *m = _m;
@@ -643,14 +676,15 @@ bool SGMetar::scanWeather()
}
string pre, post;
int intensity = 0;
if (*m == '-')
m++, pre = "light ";
m++, pre = "light ", intensity = 1;
else if (*m == '+')
m++, pre = "heavy ";
m++, pre = "heavy ", intensity = 3;
else if (!strncmp(m, "VC", 2))
m += 2, post = "in the vicinity ";
else
pre = "moderate ";
pre = "moderate ", intensity = 2;
int i;
for (i = 0; i < 3; i++) {
@@ -662,6 +696,12 @@ bool SGMetar::scanWeather()
if (!(a = scanToken(&m, phenomenon)))
break;
weather += string(a->text) + " ";
if (!strcmp(a->id, "RA"))
_rain = intensity;
else if (!strcmp(a->id, "HA"))
_hail = intensity;
else if (!strcmp(a->id, "SN"))
_snow = intensity;
}
if (!weather.length())
return false;
@@ -677,26 +717,26 @@ bool SGMetar::scanWeather()
static const struct Token cloud_types[] = {
"AC", "altocumulus",
"ACC", "altocumulus castellanus",
"ACSL", "altocumulus standing lenticular",
"AS", "altostratus",
"CB", "cumulonimbus",
"CBMAM", "cumulonimbus mammatus",
"CC", "cirrocumulus",
"CCSL", "cirrocumulus standing lenticular",
"CI", "cirrus",
"CS", "cirrostratus",
"CU", "cumulus",
"CUFRA", "cumulus fractus",
"NS", "nimbostratus",
"SAC", "stratoaltocumulus", // guessed
"SC", "stratocumulus",
"SCSL", "stratocumulus standing lenticular",
"ST", "stratus",
"STFRA", "stratus fractus",
"TCU", "towering cumulus",
0, 0
{ "AC", "altocumulus" },
{ "ACC", "altocumulus castellanus" },
{ "ACSL", "altocumulus standing lenticular" },
{ "AS", "altostratus" },
{ "CB", "cumulonimbus" },
{ "CBMAM", "cumulonimbus mammatus" },
{ "CC", "cirrocumulus" },
{ "CCSL", "cirrocumulus standing lenticular" },
{ "CI", "cirrus" },
{ "CS", "cirrostratus" },
{ "CU", "cumulus" },
{ "CUFRA", "cumulus fractus" },
{ "NS", "nimbostratus" },
{ "SAC", "stratoaltocumulus" }, // guessed
{ "SC", "stratocumulus" },
{ "SCSL", "stratocumulus standing lenticular" },
{ "ST", "stratus" },
{ "STFRA", "stratus fractus" },
{ "TCU", "towering cumulus" },
{ 0, 0 }
};
@@ -707,6 +747,14 @@ bool SGMetar::scanSkyCondition()
int i;
SGMetarCloud cl;
if (!strncmp(m, "//////", 6)) {
m += 6;
if (!scanBoundary(&m))
return false;
_m = m;
return true;
}
if (!strncmp(m, "CLR", i = 3) // clear
|| !strncmp(m, "SKC", i = 3) // sky clear
|| !strncmp(m, "NSC", i = 3) // no significant clouds
@@ -714,8 +762,13 @@ bool SGMetar::scanSkyCondition()
m += i;
if (!scanBoundary(&m))
return false;
cl._coverage = 0;
_clouds.push_back(cl);
if (i == 3) {
cl._coverage = 0;
_clouds.push_back(cl);
} else {
_cavok = true;
}
_m = m;
return true;
}
@@ -791,7 +844,7 @@ bool SGMetar::scanTemperature()
return false;
if (!scanBoundary(&m)) {
if (!strncmp(m, "XX", 2)) // not spec compliant!
m += 2, sign = 0;
m += 2, sign = 0, dew = temp;
else {
sign = 1;
if (*m == 'M')
@@ -907,19 +960,22 @@ bool SGMetar::scanRunwayReport()
if (!strncmp(m, "CLRD", 4)) {
m += 4; // runway cleared
r._deposit = "cleared";
r._deposit_string = "cleared";
} else {
if (scanNumber(&m, &i, 1)) {
r._deposit = runway_deposit[i];
r._deposit = i;
r._deposit_string = runway_deposit[i];
} else if (*m == '/')
m++;
else
return false;
if (*m == '1' || *m == '2' || *m == '5' || *m == '9') { // extent of deposit
r._extent = *m - '0';
r._extent_string = runway_deposit_extent[*m - '0'];
} else if (*m != '/')
return false;
m++;
i = -1;
if (!strncmp(m, "//", 2))
@@ -928,7 +984,7 @@ bool SGMetar::scanRunwayReport()
return false;
if (i == 0)
r._depth = 0.5; // < 1 mm deep (let's say 0.5 :-)
r._depth = 0.0005; // < 1 mm deep (let's say 0.5 :-)
else if (i > 0 && i <= 90)
r._depth = i / 1000.0; // i mm deep
else if (i >= 92 && i <= 98)
@@ -954,6 +1010,7 @@ bool SGMetar::scanRunwayReport()
return false;
_runways[id]._deposit = r._deposit;
_runways[id]._deposit_string = r._deposit_string;
_runways[id]._extent = r._extent;
_runways[id]._extent_string = r._extent_string;
_runways[id]._depth = r._depth;
@@ -1033,13 +1090,13 @@ bool SGMetar::scanTrendForecast()
// (BLU|WHT|GRN|YLO|AMB|RED)
static const struct Token colors[] = {
"BLU", "Blue", // 2500 ft, 8.0 km
"WHT", "White", // 1500 ft, 5.0 km
"GRN", "Green", // 700 ft, 3.7 km
"YLO", "Yellow", // 300 ft, 1.6 km
"AMB", "Amber", // 200 ft, 0.8 km
"RED", "Red", // <200 ft, <0.8 km
0, 0
{ "BLU", "Blue" }, // 2500 ft, 8.0 km
{ "WHT", "White" }, // 1500 ft, 5.0 km
{ "GRN", "Green" }, // 700 ft, 3.7 km
{ "YLO", "Yellow" }, // 300 ft, 1.6 km
{ "AMB", "Amber" }, // 200 ft, 0.8 km
{ "RED", "Red" }, // <200 ft, <0.8 km
{ 0, 0 }
};
@@ -1137,4 +1194,24 @@ const struct Token *SGMetar::scanToken(char **str, const struct Token *list)
return longest;
}
void SGMetarCloud::set(double alt, int cov)
{
_altitude = alt;
if (cov != -1)
_coverage = cov;
}
void SGMetarVisibility::set(double dist, int dir, int mod, int tend)
{
_distance = dist;
if (dir != -1)
_direction = dir;
if (mod != -1)
_modifier = mod;
if (tend != 1)
_tendency = tend;
}
#undef NaN

View File

@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -67,6 +67,8 @@ public:
DECREASING
};
void set(double dist, int dir = -1, int mod = -1, int tend = -1);
inline double getVisibility_m() const { return _distance; }
inline double getVisibility_ft() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_FEET; }
inline double getVisibility_sm() const { return _distance == NaN ? NaN : _distance * SG_METER_TO_SM; }
@@ -87,7 +89,8 @@ class SGMetarRunway {
friend class SGMetar;
public:
SGMetarRunway() :
_deposit(0),
_deposit(-1),
_deposit_string(0),
_extent(-1),
_extent_string(0),
_depth(NaN),
@@ -96,7 +99,8 @@ public:
_comment(0),
_wind_shear(false) {}
inline const char *getDeposit() const { return _deposit; }
inline int getDeposit() const { return _deposit; }
inline const char *getDepositString() const { return _deposit_string; }
inline double getExtent() const { return _extent; }
inline const char *getExtentString() const { return _extent_string; }
inline double getDepth() const { return _depth; }
@@ -104,13 +108,14 @@ public:
inline const char *getFrictionString() const { return _friction_string; }
inline const char *getComment() const { return _comment; }
inline const bool getWindShear() const { return _wind_shear; }
inline SGMetarVisibility getMinVisibility() const { return _min_visibility; }
inline SGMetarVisibility getMaxVisibility() const { return _max_visibility; }
inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; }
inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; }
protected:
SGMetarVisibility _min_visibility;
SGMetarVisibility _max_visibility;
const char *_deposit;
int _deposit;
const char *_deposit_string;
int _extent;
const char *_extent_string;
double _depth;
@@ -131,6 +136,8 @@ public:
_type(0),
_type_long(0) {}
void set(double alt, int cov = -1);
inline int getCoverage() const { return _coverage; }
inline double getAltitude_m() const { return _altitude; }
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
@@ -147,7 +154,8 @@ protected:
class SGMetar {
public:
SGMetar(const string& m, const string& proxy = "", const string& port = "", const string &auth = "");
SGMetar(const string& m, const string& proxy = "", const string& port = "",
const string &auth = "", const time_t time = 0);
~SGMetar();
enum ReportType {
@@ -159,6 +167,7 @@ public:
inline const char *getData() const { return _data; }
inline const char *getUnusedData() const { return _m; }
inline const bool getProxy() const { return _x_proxy; }
inline const char *getId() const { return _icao; }
inline int getYear() const { return _year; }
inline int getMonth() const { return _month; }
@@ -181,10 +190,10 @@ public:
inline int getWindRangeFrom() const { return _wind_range_from; }
inline int getWindRangeTo() const { return _wind_range_to; }
inline SGMetarVisibility& getMinVisibility() { return _min_visibility; }
inline SGMetarVisibility& getMaxVisibility() { return _max_visibility; }
inline SGMetarVisibility& getVertVisibility() { return _vert_visibility; }
inline SGMetarVisibility *getDirVisibility() { return _dir_visibility; }
inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; }
inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; }
inline const SGMetarVisibility& getVertVisibility() const { return _vert_visibility; }
inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; }
inline double getTemperature_C() const { return _temp; }
inline double getTemperature_F() const { return _temp == NaN ? NaN : 1.8 * _temp + 32; }
@@ -193,15 +202,21 @@ public:
inline double getPressure_hPa() const { return _pressure == NaN ? NaN : _pressure / 100; }
inline double getPressure_inHg() const { return _pressure == NaN ? NaN : _pressure * SG_PA_TO_INHG; }
inline int getRain() const { return _rain; }
inline int getHail() const { return _hail; }
inline int getSnow() const { return _snow; }
inline bool getCAVOK() const { return _cavok; }
double getRelHumidity() const;
inline vector<SGMetarCloud>& getClouds() { return _clouds; }
inline map<string, SGMetarRunway>& getRunways() { return _runways; }
inline vector<string>& getWeather() { return _weather; }
inline const vector<SGMetarCloud>& getClouds() const { return _clouds; }
inline const map<string, SGMetarRunway>& getRunways() const { return _runways; }
inline const vector<string>& getWeather() const { return _weather; }
protected:
string _url;
int _grpcount;
bool _x_proxy;
char *_data;
char *_m;
char _icao[5];
@@ -219,6 +234,10 @@ protected:
double _temp;
double _dewp;
double _pressure;
int _rain;
int _hail;
int _snow;
bool _cavok;
SGMetarVisibility _min_visibility;
SGMetarVisibility _max_visibility;
@@ -230,6 +249,7 @@ protected:
bool scanPreambleDate();
bool scanPreambleTime();
void useCurrentDate();
bool scanType();
bool scanId();
@@ -253,7 +273,8 @@ protected:
int scanNumber(char **str, int *num, int min, int max = 0);
bool scanBoundary(char **str);
const struct Token *scanToken(char **str, const struct Token *list);
char *loadData(const char *id, const string& proxy, const string& port, const string &auth);
char *loadData(const char *id, const string& proxy, const string& port,
const string &auth, time_t time);
void normalizeData();
};

View File

@@ -0,0 +1,828 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/constants.h>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/sg_random.h>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/sound/soundmgr_openal.hxx>
#include <simgear/scene/sky/cloudfield.hxx>
#include <simgear/scene/sky/newcloud.hxx>
#include <simgear/props/props.hxx>
#include "visual_enviro.hxx"
#include <vector>
SG_USING_STD(vector);
typedef struct {
Point3D pt;
int depth;
int prev;
} lt_tree_seg;
#define MAX_RAIN_SLICE 200
static float rainpos[MAX_RAIN_SLICE];
#define MAX_LT_TREE_SEG 400
#define DFL_MIN_LIGHT 0.35
sgVec3 SGEnviro::min_light = {DFL_MIN_LIGHT, DFL_MIN_LIGHT, DFL_MIN_LIGHT};
#define DFL_STREAK_BRIGHT_NEARMOST_LAYER 0.9
SGfloat SGEnviro::streak_bright_nearmost_layer = DFL_STREAK_BRIGHT_NEARMOST_LAYER;
#define DFL_STREAK_BRIGHT_FARMOST_LAYER 0.5
SGfloat SGEnviro::streak_bright_farmost_layer = DFL_STREAK_BRIGHT_FARMOST_LAYER;
#define DFL_STREAK_PERIOD_MAX 2.5
SGfloat SGEnviro::streak_period_max = DFL_STREAK_PERIOD_MAX;
#define DFL_STREAK_PERIOD_CHANGE_PER_KT 0.005
SGfloat SGEnviro::streak_period_change_per_kt = DFL_STREAK_PERIOD_CHANGE_PER_KT;
#define DFL_STREAK_PERIOD_MIN 1.0
SGfloat SGEnviro::streak_period_min = DFL_STREAK_PERIOD_MIN;
#define DFL_STREAK_LENGTH_MIN 0.03
SGfloat SGEnviro::streak_length_min = DFL_STREAK_LENGTH_MIN;
#define DFL_STREAK_LENGTH_CHANGE_PER_KT 0.0005
SGfloat SGEnviro::streak_length_change_per_kt = DFL_STREAK_LENGTH_CHANGE_PER_KT;
#define DFL_STREAK_LENGTH_MAX 0.1
SGfloat SGEnviro::streak_length_max = DFL_STREAK_LENGTH_MAX;
#define DFL_STREAK_COUNT_MIN 40
int SGEnviro::streak_count_min = DFL_STREAK_COUNT_MIN;
#define DFL_STREAK_COUNT_MAX 190
#if (DFL_STREAK_COUNT_MAX > MAX_RAIN_SLICE)
#error "Bad default!"
#endif
int SGEnviro::streak_count_max = DFL_STREAK_COUNT_MAX;
#define DFL_CONE_BASE_RADIUS 15.0
SGfloat SGEnviro::cone_base_radius = DFL_CONE_BASE_RADIUS;
#define DFL_CONE_HEIGHT 30.0
SGfloat SGEnviro::cone_height = DFL_CONE_HEIGHT;
void SGEnviro::config(const SGPropertyNode* n)
{
if (!n)
return;
const float ml = n->getFloatValue("min-light", DFL_MIN_LIGHT);
sgSetVec3(min_light, ml, ml, ml);
streak_bright_nearmost_layer = n->getFloatValue(
"streak-brightness-nearmost-layer",
DFL_STREAK_BRIGHT_NEARMOST_LAYER);
streak_bright_farmost_layer = n->getFloatValue(
"streak-brightness-farmost-layer",
DFL_STREAK_BRIGHT_FARMOST_LAYER);
streak_period_max = n->getFloatValue(
"streak-period-max",
DFL_STREAK_PERIOD_MAX);
streak_period_min = n->getFloatValue(
"streak-period-min",
DFL_STREAK_PERIOD_MIN);
streak_period_change_per_kt = n->getFloatValue(
"streak-period-change-per-kt",
DFL_STREAK_PERIOD_CHANGE_PER_KT);
streak_length_max = n->getFloatValue(
"streak-length-max",
DFL_STREAK_LENGTH_MAX);
streak_length_min = n->getFloatValue(
"streak-length-min",
DFL_STREAK_LENGTH_MIN);
streak_length_change_per_kt = n->getFloatValue(
"streak-length-change-per-kt",
DFL_STREAK_LENGTH_CHANGE_PER_KT);
streak_count_min = n->getIntValue(
"streak-count-min", DFL_STREAK_COUNT_MIN);
streak_count_max = n->getIntValue(
"streak-count-max", DFL_STREAK_COUNT_MAX);
if (streak_count_max > MAX_RAIN_SLICE)
streak_count_max = MAX_RAIN_SLICE;
cone_base_radius = n->getFloatValue(
"cone-base-radius", DFL_CONE_BASE_RADIUS);
cone_height = n->getFloatValue("cone_height", DFL_CONE_HEIGHT);
}
/**
* A class to render lightnings.
*/
class SGLightning {
public:
/**
* Build a new lightning.
* The lightning has a limited life time. It will also play a thunder sounder once.
* @param lon lon longitude in degree
* @param lat lat latitude in degree
* @param alt asl of top of lightning
*/
SGLightning(double lon, double lat, double alt);
~SGLightning();
void lt_Render(void);
void lt_build(void);
void lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize);
// contains all the segments of the lightning
lt_tree_seg lt_tree[MAX_LT_TREE_SEG];
// segment count
int nb_tree;
// position of lightning
double lon, lat, alt;
int sequence_count;
// time to live
double age;
};
typedef vector<SGLightning *> list_of_lightning;
static list_of_lightning lightnings;
SGEnviro sgEnviro;
SGEnviro::SGEnviro() :
view_in_cloud(false),
precipitation_enable_state(true),
precipitation_density(100.0),
precipitation_max_alt(0.0),
turbulence_enable_state(false),
last_cloud_turbulence(0.0),
cloud_turbulence(0.0),
lightning_enable_state(false),
elapsed_time(0.0),
dt(0.0),
soundMgr(NULL),
snd_active(false),
snd_dist(0.0),
min_time_before_lt(0.0),
fov_width(55.0),
fov_height(55.0)
{
for(int i = 0; i < MAX_RAIN_SLICE ; i++)
rainpos[i] = sg_random();
radarEcho.reserve(100);
}
SGEnviro::~SGEnviro(void) {
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
delete (*iLightning);
}
lightnings.clear();
}
void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time) {
// OSGFIXME
return;
view_in_cloud = false;
// ask the impostor cache to do some cleanup
if(SGNewCloud::cldCache)
SGNewCloud::cldCache->startNewFrame();
last_cloud_turbulence = cloud_turbulence;
cloud_turbulence = 0.0;
elapsed_time += delta_time;
min_time_before_lt -= delta_time;
dt = delta_time;
sgMat4 T1, LON, LAT;
sgVec3 axis;
sgMakeTransMat4( T1, p );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( LON, lon, axis );
sgSetVec3( axis, 0.0, 1.0, 0.0 );
sgMakeRotMat4( LAT, 90.0 - lat, axis );
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, LON );
sgPreMultMat4( TRANSFORM, LAT );
sgCoord pos;
sgSetCoord( &pos, TRANSFORM );
sgMakeCoordMat4( transform, &pos );
last_lon = lon;
last_lat = lat;
last_alt = alt;
radarEcho.clear();
precipitation_max_alt = 400.0;
}
void SGEnviro::endOfFrame(void) {
}
double SGEnviro::get_cloud_turbulence(void) const {
return last_cloud_turbulence;
}
// this can be queried to add some turbulence for example
bool SGEnviro::is_view_in_cloud(void) const {
return view_in_cloud;
}
void SGEnviro::set_view_in_cloud(bool incloud) {
view_in_cloud = incloud;
}
int SGEnviro::get_CacheResolution(void) const {
return SGCloudField::get_CacheResolution();
}
int SGEnviro::get_clouds_CacheSize(void) const {
return SGCloudField::get_CacheSize();
}
float SGEnviro::get_clouds_visibility(void) const {
return SGCloudField::get_CloudVis();
}
float SGEnviro::get_clouds_density(void) const {
return SGCloudField::get_density();
}
bool SGEnviro::get_clouds_enable_state(void) const {
return SGCloudField::get_enable3dClouds();
}
bool SGEnviro::get_turbulence_enable_state(void) const {
return turbulence_enable_state;
}
void SGEnviro::set_CacheResolution(int resolutionPixels) {
SGCloudField::set_CacheResolution(resolutionPixels);
}
void SGEnviro::set_clouds_CacheSize(int sizeKb) {
SGCloudField::set_CacheSize(sizeKb);
}
void SGEnviro::set_clouds_visibility(float distance) {
SGCloudField::set_CloudVis(distance);
}
void SGEnviro::set_clouds_density(float density) {
SGCloudField::set_density(density);
}
void SGEnviro::set_clouds_enable_state(bool enable) {
SGCloudField::set_enable3dClouds(enable);
}
void SGEnviro::set_turbulence_enable_state(bool enable) {
turbulence_enable_state = enable;
}
// rain/snow
float SGEnviro::get_precipitation_density(void) const {
return precipitation_density;
}
bool SGEnviro::get_precipitation_enable_state(void) const {
return precipitation_enable_state;
}
void SGEnviro::set_precipitation_density(float density) {
precipitation_density = density;
}
void SGEnviro::set_precipitation_enable_state(bool enable) {
precipitation_enable_state = enable;
}
// others
bool SGEnviro::get_lightning_enable_state(void) const {
return lightning_enable_state;
}
void SGEnviro::set_lightning_enable_state(bool enable) {
lightning_enable_state = enable;
if( ! enable ) {
// TODO:cleanup
}
}
void SGEnviro::setLight(sgVec4 adj_fog_color) {
// OSGFIXME
return;
sgCopyVec4( fog_color, adj_fog_color );
if( false ) {
// ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
}
}
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
// send data to wx radar
// compute turbulence
// draw precipitation
// draw lightning
// compute illumination
// http://www.pilotfriend.com/flight_training/weather/THUNDERSTORM%20HAZARDS1.htm
double turbulence = 0.0;
if( dist < radius * radius * 2.25f ) {
switch(family) {
case SGNewCloud::CLFamilly_st:
turbulence = 0.2;
break;
case SGNewCloud::CLFamilly_ci:
case SGNewCloud::CLFamilly_cs:
case SGNewCloud::CLFamilly_cc:
case SGNewCloud::CLFamilly_ac:
case SGNewCloud::CLFamilly_as:
turbulence = 0.1;
break;
case SGNewCloud::CLFamilly_sc:
turbulence = 0.3;
break;
case SGNewCloud::CLFamilly_ns:
turbulence = 0.4;
break;
case SGNewCloud::CLFamilly_cu:
turbulence = 0.5;
break;
case SGNewCloud::CLFamilly_cb:
turbulence = 0.6;
break;
}
// full turbulence inside cloud, half in the vicinity
if( dist > radius * radius )
turbulence *= 0.5;
if( turbulence > cloud_turbulence )
cloud_turbulence = turbulence;
// we can do 'local' precipitations too
}
// convert to LWC for radar (experimental)
// http://www-das.uwyo.edu/~geerts/cwx/notes/chap08/moist_cloud.html
double LWC = 0.0;
switch(family) {
case SGNewCloud::CLFamilly_st:
LWC = 0.29;
break;
case SGNewCloud::CLFamilly_cu:
LWC = 0.27;
break;
case SGNewCloud::CLFamilly_cb:
LWC = 2.0;
break;
case SGNewCloud::CLFamilly_sc:
LWC = 0.44;
break;
case SGNewCloud::CLFamilly_ci:
LWC = 0.03;
break;
// no data
case SGNewCloud::CLFamilly_cs:
case SGNewCloud::CLFamilly_cc:
case SGNewCloud::CLFamilly_ac:
case SGNewCloud::CLFamilly_as:
LWC = 0.03;
break;
case SGNewCloud::CLFamilly_ns:
LWC = 0.29*2.0;
break;
}
// add to the list for the wxRadar instrument
if( LWC > 0.0 )
radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
// NB:data valid only from cockpit view
// spawn a new lightning
if(lightning_enable_state && min_time_before_lt <= 0.0 && (family == SGNewCloud::CLFamilly_cb) &&
dist < 15000.0 * 15000.0 && sg_random() > 0.9f) {
double lat, lon;
Point3D orig, dest;
orig.setlat(last_lat * SG_DEGREES_TO_RADIANS );
orig.setlon(last_lon * SG_DEGREES_TO_RADIANS );
orig.setelev(0.0);
dist = sgSqrt(dist);
dest = calc_gc_lon_lat(orig, heading, dist);
lon = dest.lon() * SG_RADIANS_TO_DEGREES;
lat = dest.lat() * SG_RADIANS_TO_DEGREES;
addLightning( lon, lat, alt );
// reset timer
min_time_before_lt = 5.0 + sg_random() * 30;
// DEBUG only
// min_time_before_lt = 5.0;
}
if( (alt - radius * 0.1) > precipitation_max_alt )
switch(family) {
case SGNewCloud::CLFamilly_st:
case SGNewCloud::CLFamilly_cu:
case SGNewCloud::CLFamilly_cb:
case SGNewCloud::CLFamilly_ns:
case SGNewCloud::CLFamilly_sc:
precipitation_max_alt = alt - radius * 0.1;
break;
}
}
list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
return &radarEcho;
}
// precipitation rendering code
void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
// OSGFIXME
return;
sgVec3 light;
sgAddVec3( light, fog_color, min_light );
float da = SG_PI * 2.0f / (float) slices;
// low number = faster
float speedf = streak_period_max - speed * streak_period_change_per_kt;
if( speedf < streak_period_min )
speedf = streak_period_min;
float lenf = streak_length_min + speed * streak_length_change_per_kt;
if( lenf > streak_length_max )
lenf = streak_length_max;
float t = fmod((float) elapsed_time, speedf) / speedf;
// t = 0.1f;
if( !down )
t = 1.0f - t;
float angle = 0.0f;
//glColor4f(1.0f, 0.7f, 0.7f, 0.9f); // XXX unneeded? overriden below
glBegin(GL_LINES);
if (slices > MAX_RAIN_SLICE)
slices = MAX_RAIN_SLICE; // should never happen
for( int i = 0 ; i < slices ; i++ ) {
float x = cos(angle) * baseRadius;
float y = sin(angle) * baseRadius;
angle += da;
sgVec3 dir = {x, -height, y};
// rain drops at 2 different speed to simulate depth
float t1 = (i & 1 ? t : t + t) + rainpos[i];
if(t1 > 1.0f) t1 -= 1.0f;
if(t1 > 1.0f) t1 -= 1.0f;
// distant raindrops are more transparent
float c = t1 * (i & 1 ?
streak_bright_farmost_layer
: streak_bright_nearmost_layer);
glColor4f(c * light[0], c * light[1], c * light[2], c);
sgVec3 p1, p2;
sgScaleVec3(p1, dir, t1);
// distant raindrops are shorter
float t2 = t1 + (i & 1 ? lenf : lenf+lenf);
sgScaleVec3(p2, dir, t2);
glVertex3f(p1[0], p1[1] + height, p1[2]);
glVertex3f(p2[0], p2[1] + height, p2[2]);
}
glEnd();
}
void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
// OSGFIXME
return;
#if 0
static int debug_period = 0;
if (debug_period++ == 50) {
debug_period = 0;
cout << "drawRain("
<< pitch << ", "
<< roll << ", "
<< heading << ", "
<< hspeed << ", "
<< rain_norm << ");"
//" angle = " << angle
//<< " raindrop(KTS) = " << raindrop_speed_kts
<< endl;
}
#endif
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
glDisable( GL_FOG );
glDisable(GL_LIGHTING);
int slice_count = static_cast<int>(
(streak_count_min + rain_norm*(streak_count_max-streak_count_min))
* precipitation_density / 100.0);
// www.wonderquest.com/falling-raindrops.htm says that
// Raindrop terminal velocity is 5 to 20mph
// Rather than model it accurately (temp, pressure, diameter), and make it
// smaller than terminal when closer to the precipitation cloud base,
// we interpolate in the 5-20mph range according to rain_norm.
double raindrop_speed_kts
= (5.0 + rain_norm*15.0) * SG_MPH_TO_MPS * SG_MPS_TO_KT;
float angle = atanf(hspeed / raindrop_speed_kts) * SG_RADIANS_TO_DEGREES;
glPushMatrix();
// the cone rotate with hspeed
angle = -pitch - angle;
glRotatef(roll, 0.0, 0.0, 1.0);
glRotatef(heading, 0.0, 1.0, 0.0);
glRotatef(angle, 1.0, 0.0, 0.0);
// up cone
DrawCone2(cone_base_radius, cone_height,
slice_count, true, rain_norm, hspeed);
// down cone (usually not visible)
if(angle > 0.0 || heading != 0.0)
DrawCone2(cone_base_radius, -cone_height,
slice_count, false, rain_norm, hspeed);
glPopMatrix();
glEnable(GL_LIGHTING);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glEnable( GL_FOG );
glEnable(GL_DEPTH_TEST);
}
void SGEnviro::set_soundMgr(SGSoundMgr *mgr) {
soundMgr = mgr;
}
void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
// OSGFIXME
return;
if( precipitation_enable_state && rain_norm > 0.0)
if( precipitation_max_alt >= last_alt )
drawRain(pitch, roll, heading, hspeed, rain_norm);
}
SGLightning::SGLightning(double _lon, double _lat, double _alt) :
nb_tree(0),
lon(_lon),
lat(_lat),
alt(_alt),
age(1.0 + sg_random() * 4.0)
{
// sequence_count = 1 + sg_random() * 5.0;
lt_build();
}
SGLightning::~SGLightning() {
}
// lightning rendering code
void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize) {
// OSGFIXME
return;
sgVec3 dir, newdir;
int nseg = 0;
Point3D pt = start;
if( nbseg == 50 )
sgSetVec3( dir, 0.0, -1.0, 0.0 );
else {
sgSetVec3( dir, sg_random() - 0.5f, sg_random() - 0.5f, sg_random() - 0.5f);
sgNormaliseVec3(dir);
}
if( nb_tree >= MAX_LT_TREE_SEG )
return;
lt_tree[nb_tree].depth = tree_nr;
nseg = 0;
lt_tree[nb_tree].pt = pt;
lt_tree[nb_tree].prev = -1;
nb_tree ++;
// TODO:check agl
while(nseg < nbseg && pt.y() > 0.0) {
int prev = nb_tree - 1;
nseg++;
// add a branch
if( energy * sg_random() > 0.8f )
lt_build_tree_branch(tree_nr + 1, pt, energy * 0.9f, nbseg == 50 ? 10 : static_cast<int>(nbseg * 0.4f), segsize * 0.7f);
if( nb_tree >= MAX_LT_TREE_SEG )
return;
sgSetVec3(newdir, (sg_random() - 0.5f), (sg_random() - 0.5f) - (nbseg == 50 ? 0.5f : 0.0), (sg_random() - 0.5f));
sgNormaliseVec3(newdir);
sgAddVec3( dir, newdir);
sgNormaliseVec3(dir);
sgVec3 scaleDir;
sgScaleVec3( scaleDir, dir, segsize * energy * 0.5f );
pt[PX] += scaleDir[0];
pt[PY] += scaleDir[1];
pt[PZ] += scaleDir[2];
lt_tree[nb_tree].depth = tree_nr;
lt_tree[nb_tree].pt = pt;
lt_tree[nb_tree].prev = prev;
nb_tree ++;
}
}
void SGLightning::lt_build(void) {
// OSGFIXME
return;
Point3D top;
nb_tree = 0;
top[PX] = 0 ;
top[PY] = alt;
top[PZ] = 0;
lt_build_tree_branch(0, top, 1.0, 50, top[PY] / 8.0);
if( ! sgEnviro.soundMgr )
return;
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
if( dist < 10000.0 && ! sgEnviro.snd_playing && (dist < sgEnviro.snd_dist || ! sgEnviro.snd_active) ) {
sgEnviro.snd_timer = 0.0;
sgEnviro.snd_wait = dist / 340;
sgEnviro.snd_dist = dist;
sgEnviro.snd_pos_lat = lat;
sgEnviro.snd_pos_lon = lon;
sgEnviro.snd_active = true;
sgEnviro.snd_playing = false;
}
}
void SGLightning::lt_Render(void) {
// OSGFIXME
return;
float flash = 0.5;
if( fmod(sgEnviro.elapsed_time*100.0, 100.0) > 50.0 )
flash = sg_random() * 0.75f + 0.25f;
float h = lt_tree[0].pt[PY];
sgVec4 col={0.62f, 0.83f, 1.0f, 1.0f};
sgVec4 c;
#define DRAW_SEG() \
{glColorMaterial(GL_FRONT, GL_EMISSION); \
glDisable(GL_LINE_SMOOTH); glBegin(GL_LINES); \
glColor4fv(c); \
glVertex3f(lt_tree[n].pt[PX], lt_tree[n].pt[PZ], lt_tree[n].pt[PY]); \
glVertex3f(lt_tree[lt_tree[n].prev].pt[PX], lt_tree[lt_tree[n].prev].pt[PZ], lt_tree[lt_tree[n].prev].pt[PY]); \
glEnd(); glEnable(GL_LINE_SMOOTH);}
glDepthMask( GL_FALSE );
glEnable(GL_BLEND);
glBlendFunc( GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_LIGHTING);
glDisable( GL_FOG );
glPushMatrix();
sgMat4 modelview, tmp;
// OSGFIXME
// ssgGetModelviewMatrix( modelview );
sgCopyMat4( tmp, sgEnviro.transform );
sgPostMultMat4( tmp, modelview );
// OSGFIXME
// ssgLoadModelviewMatrix( tmp );
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
double ax = 0.0, ay = 0.0;
ax = cos(course) * dist;
ay = sin(course) * dist;
glTranslatef( ax, ay, -sgEnviro.last_alt );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
for( int n = 0 ; n < nb_tree ; n++ ) {
if( lt_tree[n].prev < 0 )
continue;
float t1 = sgLerp(0.5, 1.0, lt_tree[n].pt[PY] / h);
t1 *= flash;
if( lt_tree[n].depth >= 2 ) {
glLineWidth(3);
sgScaleVec4(c, col, t1 * 0.6f);
DRAW_SEG();
} else {
if( lt_tree[n].depth == 0 ) {
glLineWidth(12);
sgScaleVec4(c, col, t1 * 0.5f);
DRAW_SEG();
glLineWidth(6);
sgScaleVec4(c, col, t1);
DRAW_SEG();
} else {
glLineWidth(6);
sgScaleVec4(c, col, t1 * 0.7f);
DRAW_SEG();
}
if( lt_tree[n].depth == 0 )
glLineWidth(3);
else
glLineWidth(2);
sgSetVec4(c, t1, t1, t1, t1);
DRAW_SEG();
}
}
glLineWidth(1);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glPopMatrix();
glDepthMask( GL_TRUE );
glEnable( GL_FOG );
glEnable(GL_LIGHTING);
}
void SGEnviro::addLightning(double lon, double lat, double alt) {
// OSGFIXME
return;
if( lightnings.size() > 10)
return;
SGLightning *lt= new SGLightning(lon, lat, alt);
lightnings.push_back(lt);
}
void SGEnviro::drawLightning(void) {
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
// play 'thunder' for lightning
if( snd_active )
if( !snd_playing ) {
// wait until sound has reached us
snd_timer += dt;
if( snd_timer >= snd_wait ) {
snd_playing = true;
// compute relative position of lightning
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( snd_pos_lon*SG_DEGREES_TO_RADIANS, snd_pos_lat*SG_DEGREES_TO_RADIANS, 0.0 );
double course = 0.0, dist = 0.0;
calc_gc_course_dist( dest, start, &course, &dist );
double ax = 0.0, ay = 0.0;
ax = cos(course) * dist;
ay = sin(course) * dist;
SGSharedPtr<SGSoundSample> snd = soundMgr->find("thunder");
if( snd ) {
ALfloat pos[3]={ax, ay, -sgEnviro.last_alt };
snd->set_source_pos(pos);
snd->play_once();
}
}
} else {
if( !soundMgr->is_playing("thunder") ) {
snd_active = false;
snd_playing = false;
}
}
if( ! lightning_enable_state )
return;
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
if( dt )
if( sg_random() > 0.95f )
(*iLightning)->lt_build();
(*iLightning)->lt_Render();
(*iLightning)->age -= dt;
if( (*iLightning)->age < 0.0 ) {
delete (*iLightning);
lightnings.erase( iLightning );
break;
}
}
}
void SGEnviro::setFOV( float w, float h ) {
fov_width = w;
fov_height = h;
}
void SGEnviro::getFOV( float &w, float &h ) {
w = fov_width;
h = fov_height;
}

View File

@@ -0,0 +1,257 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//
#ifndef _VISUAL_ENVIRO_HXX
#define _VISUAL_ENVIRO_HXX
#include <plib/sg.h>
#include <simgear/compiler.h>
#include STL_STRING
#include <vector>
SG_USING_STD(vector);
SG_USING_STD(string);
class SGLightning;
class SGSoundMgr;
/**
* Simulate some echo on a weather radar.
* Container class for the wx radar instrument.
*/
class SGWxRadarEcho {
public:
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist,
double _LWC, bool _lightning, int _cloudId ) :
heading( _heading ),
alt ( _alt ),
radius ( _radius ),
dist ( _dist ),
LWC ( _LWC ),
lightning ( _lightning ),
cloudId ( _cloudId )
{}
/** the heading in radian is versus north */
float heading;
float alt, radius, dist;
/** reflectivity converted to liquid water content. */
double LWC;
/** if true then this data is for a lightning else it is for water echo. */
bool lightning;
/** Unique identifier of cloud */
int cloudId;
};
typedef vector<SGWxRadarEcho> list_of_SGWxRadarEcho;
/**
* Visual environment helper class.
*/
class SGEnviro {
friend class SGLightning;
private:
void DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed);
void lt_update(void);
bool view_in_cloud;
bool precipitation_enable_state;
float precipitation_density;
float precipitation_max_alt;
bool turbulence_enable_state;
double last_cloud_turbulence, cloud_turbulence;
bool lightning_enable_state;
double elapsed_time, dt;
sgVec4 fog_color;
sgMat4 transform;
double last_lon, last_lat, last_alt;
SGSoundMgr *soundMgr;
bool snd_active, snd_playing;
double snd_timer, snd_wait, snd_pos_lat, snd_pos_lon, snd_dist;
double min_time_before_lt;
float fov_width, fov_height;
/** a list of all the radar echo. */
list_of_SGWxRadarEcho radarEcho;
static sgVec3 min_light;
static SGfloat streak_bright_nearmost_layer,
streak_bright_farmost_layer,
streak_period_max,
streak_period_change_per_kt,
streak_period_min,
streak_length_min,
streak_length_change_per_kt,
streak_length_max;
static int streak_count_min, streak_count_max;
static SGfloat cone_base_radius,
cone_height;
public:
SGEnviro();
~SGEnviro();
/** Read the config from the precipitation rendering config properties.
* @param precip_rendering_cfgNode "/sim/rendering/precipitation" in fg
* Set from whatever info present in the
* subnodes passed, substituting hardwired defaults for missing fields.
* If NULL is given, do nothing.
*/
void config(const class SGPropertyNode* precip_rendering_cfgNode);
/**
* Forward a few states used for renderings.
*/
void startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time);
void endOfFrame(void);
/**
* Whenever a cloud is drawn we check his 'impact' on the environment.
* @param heading direction of cloud in radians
* @param alt asl of cloud in meters
* @param radius radius of cloud in meters
* @param family cloud family
* @param dist squared dist to cloud in meters
*/
void callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId);
void drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm);
/**
* Draw rain or snow precipitation around the viewer.
* @param rain_norm rain normalized intensity given by metar class
* @param snow_norm snow normalized intensity given by metar class
* @param hail_norm hail normalized intensity given by metar class
* @param pitch pitch rotation of viewer
* @param roll roll rotation of viewer
* @param hspeed moving horizontal speed of viewer in kt
*/
void drawPrecipitation(double rain_norm, double snow_norm, double hail_norm,
double pitch, double roll, double heading, double hspeed);
/**
* Draw the lightnings spawned by cumulo nimbus.
*/
void drawLightning(void);
/**
* Forward the fog color used by the rain rendering.
* @param adj_fog_color color of the fog
*/
void setLight(sgVec4 adj_fog_color);
// this can be queried to add some turbulence for example
bool is_view_in_cloud(void) const;
void set_view_in_cloud(bool incloud);
double get_cloud_turbulence(void) const;
// Clouds
// return the size of the memory pool used by texture impostors
int get_clouds_CacheSize(void) const;
int get_CacheResolution(void) const;
float get_clouds_visibility(void) const;
float get_clouds_density(void) const;
bool get_clouds_enable_state(void) const;
bool get_turbulence_enable_state(void) const;
/**
* Set the size of the impostor texture cache for 3D clouds.
* @param sizeKb size of the texture pool in Kb
*/
void set_clouds_CacheSize(int sizeKb);
/**
* Set the resolution of the impostor texture for 3D clouds.
* @param resolutionPixels size of each texture in pixels (64|128|256)
*/
void set_CacheResolution(int resolutionPixels);
/**
* Set the maximum range used when drawing clouds.
* Clouds are blended from totaly transparent at max range to totaly opaque around the viewer
* @param distance in meters
*/
void set_clouds_visibility(float distance);
/**
* Set the proportion of clouds that will be rendered to limit drop in FPS.
* @param density 0..100 no clouds drawn when density == 0, all are drawn when density == 100
*/
void set_clouds_density(float density);
/**
* Enable or disable the use of 3D clouds.
* @param enable when false we draw the 2D layers
*/
void set_clouds_enable_state(bool enable);
/**
* Enable or disable the use of proximity cloud turbulence.
* @param enable when true the turbulence is computed based on type of cloud around the AC
*/
void set_turbulence_enable_state(bool enable);
// rain/snow
float get_precipitation_density(void) const;
bool get_precipitation_enable_state(void) const;
/**
* Decrease the precipitation density to the given percentage.
* (Only show the given percentage of rain streaks etc.)
* Default precipitation density upon construction is 100.0.
* @param density 0.0 to 100.0
*/
void set_precipitation_density(float density);
/**
* Enable or disable the rendering of precipitation around the viewer.
* @param enable when true we will draw precipitation depending on metar data
*/
void set_precipitation_enable_state(bool enable);
// others
bool get_lightning_enable_state(void) const;
/**
* Enable or disable the rendering of lightning and the thunder sound.
* @param enable when true we will draw lightning spwaned by cumulonimbus
*/
void set_lightning_enable_state(bool enable);
/**
* Spawn a new lighning at specified lon/lat.
* @param lon position of the new lightning
* @param lat position of the new lightning
* @param alt asl of the starting point of the lightning in meters
*/
void addLightning(double lon, double lat, double alt);
/**
* Forward the sound manager instance to be able to play samples.
* @param mgr a running sound manager
*/
void set_soundMgr(SGSoundMgr *mgr);
void setFOV( float w, float h );
void getFOV( float &w, float &h );
list_of_SGWxRadarEcho *get_radar_echo(void);
sgMat4 *get_transform(void) { return &transform; }
};
extern SGEnviro sgEnviro;
#endif // _VISUAL_ENVIRO_HXX

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -27,9 +26,9 @@
#ifndef _CELESTIALBODY_H_
#define _CELESTIALBODY_H_
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
#include <simgear/constants.h>

View File

@@ -3,7 +3,7 @@
//
// Written by Curtis Olson, started March 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -15,13 +15,15 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <iostream>
@@ -29,7 +31,7 @@
// Constructor
SGEphemeris::SGEphemeris( const string &path ) {
SGEphemeris::SGEphemeris( const std::string &path ) {
our_sun = new Star;
moon = new MoonPos;
mercury = new Mercury;
@@ -40,9 +42,8 @@ SGEphemeris::SGEphemeris( const string &path ) {
uranus = new Uranus;
neptune = new Neptune;
nplanets = 7;
for ( int i = 0; i < nplanets; ++i ) {
sgdSetVec3( planets[i], 0.0, 0.0, 0.0 );
}
for ( int i = 0; i < nplanets; ++i )
planets[i] = SGVec3d::zeros();
stars = new SGStarData( SGPath(path) );
}

View File

@@ -7,7 +7,7 @@
// All the core code underneath this is written by Durk Talsma. See
// the headers of all the other individual files for details.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -19,10 +19,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -30,8 +29,7 @@
#ifndef _EPHEMERIS_HXX
#define _EPHEMERIS_HXX
#include <plib/sg.h>
#include <string>
#include <simgear/ephemeris/star.hxx>
#include <simgear/ephemeris/moonpos.hxx>
@@ -44,11 +42,14 @@
#include <simgear/ephemeris/neptune.hxx>
#include <simgear/ephemeris/stardata.hxx>
#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sg_path.hxx>
/** Ephemeris class
*
* Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson
* <curt@flightgear.org>
* <http://www.flightgear.org/~curt>
*
* Introduction
*
@@ -84,7 +85,7 @@ class SGEphemeris {
// planets[i][1] = Declination
// planets[i][2] = Magnitude
int nplanets;
sgdVec3 planets[7];
SGVec3d planets[7];
SGStarData *stars;
@@ -96,7 +97,7 @@ public:
* calling the constructor you need to provide a path pointing to
* your star database file.
* @param path path to your star database */
SGEphemeris( const string &path );
SGEphemeris( const std::string &path );
/** Destructor */
~SGEphemeris( void );
@@ -156,7 +157,7 @@ public:
* the second is the declination, and the third is the magnitude.
* @return planets array
*/
inline sgdVec3 *getPlanets() { return planets; }
inline SGVec3d *getPlanets() { return planets; }
/** @return the numbers of defined stars. */
inline int getNumStars() const { return stars->getNumStars(); }
@@ -168,7 +169,7 @@ public:
* third is the magnitude.
* @returns star array
*/
inline sgdVec3 *getStars() { return stars->getStars(); }
inline SGVec3d *getStars() { return stars->getStars(); }
};

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -172,7 +171,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
if (geoRa < 0)
geoRa += (2*SGD_PI);
geoRa += SGD_2PI;
HA = lst - (3.8197186 * geoRa);
/* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst()

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -80,7 +79,7 @@ void Star::updatePosition(double mjd)
double
actTime, eccAnom,
xv, yv, v, r,
xe, ye, ze, ecl;
xe, ecl;
updateOrbElements(mjd);

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/
@@ -35,6 +34,7 @@ class Star : public CelestialBody
private:
double xs, ys; // the sun's rectangular geocentric coordinates
double ye, ze; // the sun's rectangularequatorial rectangular geocentric coordinates
double distance; // the sun's distance to the earth
public:
@@ -47,6 +47,8 @@ public:
double getw();
double getxs();
double getys();
double getye();
double getze();
double getDistance();
};
@@ -71,6 +73,16 @@ inline double Star::getys()
return ys;
}
inline double Star::getye()
{
return ye;
}
inline double Star::getze()
{
return ze;
}
inline double Star::getDistance()
{
return distance;

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started March 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -14,15 +14,18 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include "stardata.hxx"
@@ -32,16 +35,9 @@
#endif
// Constructor
SGStarData::SGStarData() :
nstars(0)
SGStarData::SGStarData( const SGPath& path )
{
}
SGStarData::SGStarData( SGPath path ) :
nstars(0)
{
data_path = SGPath( path );
load();
load(path);
}
@@ -50,31 +46,28 @@ SGStarData::~SGStarData() {
}
bool SGStarData::load() {
bool SGStarData::load( const SGPath& path ) {
// -dw- avoid local data > 32k error by dynamic allocation of the
// array, problem for some compilers
stars = new sgdVec3[SG_MAX_STARS];
_stars.clear();
// build the full path name to the stars data base file
data_path.append( "stars" );
SG_LOG( SG_ASTRO, SG_INFO, " Loading stars from " << data_path.str() );
// build the full path name to the stars data base file
SGPath tmp = path;
tmp.append( "stars" );
SG_LOG( SG_ASTRO, SG_INFO, " Loading stars from " << tmp.str() );
sg_gzifstream in( data_path.str() );
sg_gzifstream in( tmp.str() );
if ( ! in.is_open() ) {
SG_LOG( SG_ASTRO, SG_ALERT, "Cannot open star file: "
<< data_path.str() );
exit(-1);
<< tmp.str() );
return false;
}
double ra, dec, mag;
char c;
string name;
nstars = 0;
// read in each line of the file
while ( ! in.eof() && nstars < SG_MAX_STARS ) {
while ( ! in.eof() ) {
in >> skipcomment;
getline( in, name, ',' );
@@ -114,13 +107,10 @@ bool SGStarData::load() {
in >> mag;
// cout << " star data = " << ra << " " << dec << " " << mag << endl;
sgdSetVec3( stars[nstars], ra, dec, mag );
++nstars;
_stars.push_back(SGVec3d(ra, dec, mag));
}
SG_LOG( SG_ASTRO, SG_INFO, " Loaded " << nstars << " stars" );
SG_LOG( SG_ASTRO, SG_INFO, " Loaded " << _stars.size() << " stars" );
return true;
}

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started March 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -14,10 +14,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -25,37 +24,28 @@
#ifndef _SG_STARDATA_HXX
#define _SG_STARDATA_HXX
#include <vector>
#include <simgear/math/SGMath.hxx>
#include <plib/sg.h>
#include <simgear/misc/sg_path.hxx>
#define SG_MAX_STARS 850
class SGPath;
class SGStarData {
int nstars;
sgdVec3 *stars;
SGPath data_path;
public:
// Constructor
SGStarData();
SGStarData( SGPath path );
SGStarData( const SGPath& path );
// Destructor
~SGStarData();
// load the stars database
bool load();
bool load( const SGPath& path );
// stars
inline int getNumStars() const { return nstars; }
inline sgdVec3 *getStars() { return stars; }
inline int getNumStars() const { return _stars.size(); }
inline SGVec3d *getStars() { return &(_stars[0]); }
private:
std::vector<SGVec3d> _stars;
};

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -15,10 +15,9 @@
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* 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.
*
* $Id$
**************************************************************************/

View File

@@ -1,3 +1,7 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <unistd.h>
@@ -33,14 +37,14 @@ int main( int argc, char **argv ) {
obj.get_gbs_radius());
cout << endl;
point_list nodes = obj.get_wgs84_nodes();
std::vector<SGVec3d> nodes = obj.get_wgs84_nodes();
cout << "# vertex list" << endl;
for ( i = 0; i < (int)nodes.size(); ++i ) {
printf("v %.5f %.5f %.5f\n", nodes[i].x(), nodes[i].y(), nodes[i].z() );
}
cout << endl;
point_list normals = obj.get_normals();
std::vector<SGVec3f> normals = obj.get_normals();
cout << "# vertex normal list" << endl;
for ( i = 0; i < (int)normals.size(); ++i ) {
printf("vn %.5f %.5f %.5f\n",
@@ -48,7 +52,7 @@ int main( int argc, char **argv ) {
}
cout << endl;
point_list texcoords = obj.get_texcoords();
std::vector<SGVec2f> texcoords = obj.get_texcoords();
cout << "# texture coordinate list" << endl;
for ( i = 0; i < (int)texcoords.size(); ++i ) {
printf("vt %.5f %.5f\n",

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -70,3 +70,9 @@ int SGIOChannel::writestring( const char *str ) {
bool SGIOChannel::close() {
return false;
}
// dummy eof routine
bool SGIOChannel::eof() {
return false;
}

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -152,6 +152,14 @@ public:
*/
virtual bool close();
/**
* The eof() method returns true if end of file has been reached
* in a context where that makes sense. Otherwise it returns
* false.
* @return result of eof check
*/
virtual bool eof();
inline void set_type( SGChannelType t ) { type = t; }
inline SGChannelType get_type() const { return type; }

View File

@@ -4,7 +4,7 @@
// Shamelessly adapted from plib (plib.sourceforge.net) January 2001
//
// Original version Copyright (C) 2000 the plib team
// Local changes Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Local changes Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -59,7 +59,7 @@ void sgReadFloat ( gzFile fd, float *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)var);
sgEndianSwap( (uint32_t *)var);
}
}
@@ -67,7 +67,7 @@ void sgReadFloat ( gzFile fd, float *var )
void sgWriteFloat ( gzFile fd, const float var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)&var);
sgEndianSwap( (uint32_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) {
write_error = true ;
@@ -81,7 +81,7 @@ void sgReadDouble ( gzFile fd, double *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64*)var);
sgEndianSwap( (uint64_t *)var);
}
}
@@ -89,7 +89,7 @@ void sgReadDouble ( gzFile fd, double *var )
void sgWriteDouble ( gzFile fd, const double var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64*)&var);
sgEndianSwap( (uint64_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) {
write_error = true ;
@@ -103,7 +103,7 @@ void sgReadUInt ( gzFile fd, unsigned int *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)var);
sgEndianSwap( (uint32_t *)var);
}
}
@@ -111,7 +111,7 @@ void sgReadUInt ( gzFile fd, unsigned int *var )
void sgWriteUInt ( gzFile fd, const unsigned int var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)&var);
sgEndianSwap( (uint32_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
!= sizeof(unsigned int) )
@@ -127,7 +127,7 @@ void sgReadInt ( gzFile fd, int *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)var);
sgEndianSwap( (uint32_t *)var);
}
}
@@ -135,7 +135,7 @@ void sgReadInt ( gzFile fd, int *var )
void sgWriteInt ( gzFile fd, const int var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)&var);
sgEndianSwap( (uint32_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
write_error = true ;
@@ -143,48 +143,48 @@ void sgWriteInt ( gzFile fd, const int var )
}
void sgReadLong ( gzFile fd, long int *var )
void sgReadLong ( gzFile fd, int32_t *var )
{
if ( gzread ( fd, var, sizeof(long int) ) != sizeof(long int) ) {
if ( gzread ( fd, var, sizeof(int32_t) ) != sizeof(int32_t) ) {
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)var);
sgEndianSwap( (uint32_t *)var);
}
}
void sgWriteLong ( gzFile fd, const long int var )
void sgWriteLong ( gzFile fd, const int32_t var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int*)&var);
sgEndianSwap( (uint32_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(long int) )
!= sizeof(long int) )
if ( gzwrite ( fd, (void *)(&var), sizeof(int32_t) )
!= sizeof(int32_t) )
{
write_error = true ;
}
}
void sgReadLongLong ( gzFile fd, int64 *var )
void sgReadLongLong ( gzFile fd, int64_t *var )
{
if ( gzread ( fd, var, sizeof(int64) ) != sizeof(int64) ) {
if ( gzread ( fd, var, sizeof(int64_t) ) != sizeof(int64_t) ) {
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64*)var);
sgEndianSwap( (uint64_t *)var);
}
}
void sgWriteLongLong ( gzFile fd, const int64 var )
void sgWriteLongLong ( gzFile fd, const int64_t var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64*)&var);
sgEndianSwap( (uint64_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(int64) )
!= sizeof(int64) )
if ( gzwrite ( fd, (void *)(&var), sizeof(int64_t) )
!= sizeof(int64_t) )
{
write_error = true ;
}
@@ -197,7 +197,7 @@ void sgReadUShort ( gzFile fd, unsigned short *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short int*)var);
sgEndianSwap( (uint16_t *)var);
}
}
@@ -205,7 +205,7 @@ void sgReadUShort ( gzFile fd, unsigned short *var )
void sgWriteUShort ( gzFile fd, const unsigned short var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short*)&var);
sgEndianSwap( (uint16_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
!= sizeof(unsigned short) )
@@ -221,7 +221,7 @@ void sgReadShort ( gzFile fd, short *var )
read_error = true ;
}
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short int*)var);
sgEndianSwap( (uint16_t *)var);
}
}
@@ -229,7 +229,7 @@ void sgReadShort ( gzFile fd, short *var )
void sgWriteShort ( gzFile fd, const short var )
{
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned short*)&var);
sgEndianSwap( (uint16_t *)&var);
}
if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
write_error = true ;
@@ -244,7 +244,7 @@ void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)var++);
sgEndianSwap( (uint32_t *)var++);
}
}
}
@@ -257,7 +257,7 @@ void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
float *ptr = swab;
memcpy( swab, var, sizeof(float) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)ptr++);
sgEndianSwap( (uint32_t *)ptr++);
}
var = swab;
}
@@ -275,7 +275,7 @@ void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (uint64*)var++);
sgEndianSwap( (uint64_t *)var++);
}
}
}
@@ -288,7 +288,7 @@ void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
double *ptr = swab;
memcpy( swab, var, sizeof(double) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (uint64*)ptr++);
sgEndianSwap( (uint64_t *)ptr++);
}
var = swab;
}
@@ -325,7 +325,7 @@ void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned short int*)var++);
sgEndianSwap( (uint16_t *)var++);
}
}
}
@@ -338,7 +338,7 @@ void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var
unsigned short *ptr = swab;
memcpy( swab, var, sizeof(unsigned short) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned short*)ptr++);
sgEndianSwap( (uint16_t *)ptr++);
}
var = swab;
}
@@ -360,7 +360,7 @@ void sgReadShort ( gzFile fd, const unsigned int n, short *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned short int*)var++);
sgEndianSwap( (uint16_t *)var++);
}
}
}
@@ -373,7 +373,7 @@ void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
short *ptr = swab;
memcpy( swab, var, sizeof(short) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned short*)ptr++);
sgEndianSwap( (uint16_t *)ptr++);
}
var = swab;
}
@@ -394,7 +394,7 @@ void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)var++);
sgEndianSwap( (uint32_t *)var++);
}
}
}
@@ -407,7 +407,7 @@ void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
unsigned int *ptr = swab;
memcpy( swab, var, sizeof(unsigned int) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)ptr++);
sgEndianSwap( (uint32_t *)ptr++);
}
var = swab;
}
@@ -429,7 +429,7 @@ void sgReadInt ( gzFile fd, const unsigned int n, int *var )
}
if ( sgIsBigEndian() ) {
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)var++);
sgEndianSwap( (uint32_t *)var++);
}
}
}
@@ -442,7 +442,7 @@ void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
int *ptr = swab;
memcpy( swab, var, sizeof(int) * n );
for ( unsigned int i = 0; i < n; ++i ) {
sgEndianSwap( (unsigned int*)ptr++);
sgEndianSwap( (uint32_t *)ptr++);
}
var = swab;
}

View File

@@ -4,7 +4,7 @@
// Shamelessly adapted from plib January 2001
//
// Original version Copyright (C) 2000 the plib team
// Local changes Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Local changes Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
//
@@ -27,19 +27,13 @@
#ifndef _SG_LOWLEVEL_HXX
#define _SG_LOWLEVEL_HXX
#include <stdio.h>
#include <zlib.h>
#include <plib/sg.h>
#ifdef _MSC_VER
typedef __int64 int64;
typedef __int64 uint64;
#else
typedef long long int64;
typedef unsigned long long uint64;
#endif
#include <simgear/compiler.h>
#include <simgear/misc/stdint.hxx>
// Note that output is written in little endian form (and converted as
// necessary for big endian machines)
@@ -54,10 +48,10 @@ void sgReadUInt ( gzFile fd, unsigned int *var ) ;
void sgWriteUInt ( gzFile fd, const unsigned int var ) ;
void sgReadInt ( gzFile fd, int *var ) ;
void sgWriteInt ( gzFile fd, const int var ) ;
void sgReadLong ( gzFile fd, long int *var ) ;
void sgWriteLong ( gzFile fd, const long int var ) ;
void sgReadLongLong ( gzFile fd, int64 *var ) ;
void sgWriteLongLong ( gzFile fd, const int64 var ) ;
void sgReadLong ( gzFile fd, int32_t *var ) ;
void sgWriteLong ( gzFile fd, const int32_t var ) ;
void sgReadLongLong ( gzFile fd, int64_t *var ) ;
void sgWriteLongLong ( gzFile fd, const int64_t var ) ;
void sgReadUShort ( gzFile fd, unsigned short *var ) ;
void sgWriteUShort ( gzFile fd, const unsigned short var ) ;
void sgReadShort ( gzFile fd, short *var ) ;
@@ -121,52 +115,4 @@ void sgClearWriteError();
int sgReadError();
int sgWriteError();
inline bool sgIsLittleEndian() {
static const int sgEndianTest = 1;
return (*((char *) &sgEndianTest ) != 0);
}
inline bool sgIsBigEndian() {
static const int sgEndianTest = 1;
return (*((char *) &sgEndianTest ) == 0);
}
inline void sgEndianSwap(unsigned short *x) {
*x =
(( *x >> 8 ) & 0x00FF ) |
(( *x << 8 ) & 0xFF00 ) ;
}
inline void sgEndianSwap(unsigned int *x) {
*x =
(( *x >> 24 ) & 0x000000FF ) |
(( *x >> 8 ) & 0x0000FF00 ) |
(( *x << 8 ) & 0x00FF0000 ) |
(( *x << 24 ) & 0xFF000000 ) ;
}
inline void sgEndianSwap(uint64 *x) {
#ifndef _MSC_VER
*x =
(( *x >> 56 ) & 0x00000000000000FFULL ) |
(( *x >> 40 ) & 0x000000000000FF00ULL ) |
(( *x >> 24 ) & 0x0000000000FF0000ULL ) |
(( *x >> 8 ) & 0x00000000FF000000ULL ) |
(( *x << 8 ) & 0x000000FF00000000ULL ) |
(( *x << 24 ) & 0x0000FF0000000000ULL ) |
(( *x << 40 ) & 0x00FF000000000000ULL ) |
(( *x << 56 ) & 0xFF00000000000000ULL ) ;
#else
*x =
(( *x >> 56 ) & 0x00000000000000FF ) |
(( *x >> 40 ) & 0x000000000000FF00 ) |
(( *x >> 24 ) & 0x0000000000FF0000 ) |
(( *x >> 8 ) & 0x00000000FF000000 ) |
(( *x << 8 ) & 0x000000FF00000000 ) |
(( *x << 24 ) & 0x0000FF0000000000 ) |
(( *x << 40 ) & 0x00FF000000000000 ) |
(( *x << 56 ) & 0xFF00000000000000 ) ;
#endif
}
#endif // _SG_LOWLEVEL_HXX

View File

@@ -25,22 +25,22 @@ int main() {
short s = 1111;
cout << "short s = " << s << endl;
sgEndianSwap((unsigned short *)&s);
sgEndianSwap((uint16_t *)&s);
cout << "short s = " << s << endl;
sgEndianSwap((unsigned short *)&s);
sgEndianSwap((uint16_t *)&s);
cout << "short s = " << s << endl;
int i = 1111111;
cout << "int i = " << i << endl;
sgEndianSwap((unsigned int *)&i);
sgEndianSwap((uint32_t *)&i);
cout << "int i = " << i << endl;
sgEndianSwap((unsigned int *)&i);
sgEndianSwap((uint32_t *)&i);
cout << "int i = " << i << endl;
double x = 1111111111;
cout << "double x = " << x << endl;
sgEndianSwap((unsigned long long *)&x);
sgEndianSwap((uint64_t *)&x);
cout << "double x = " << x << endl;
sgEndianSwap((unsigned long long *)&x);
sgEndianSwap((uint64_t *)&x);
cout << "double x = " << x << endl;
}

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started January 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
//
@@ -36,6 +36,7 @@
#include STL_STRING
#include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx>
#include "lowlevel.hxx"
#include "sg_binobj.hxx"
@@ -45,7 +46,7 @@ SG_USING_STD( string );
SG_USING_STD( vector );
enum {
enum sgObjectTypes {
SG_BOUNDING_SPHERE = 0,
SG_VERTEX_LIST = 1,
@@ -58,20 +59,19 @@ enum {
SG_TRIANGLE_FACES = 10,
SG_TRIANGLE_STRIPS = 11,
SG_TRIANGLE_FANS = 12
} sgObjectTypes;
};
enum {
enum sgIndexTypes {
SG_IDX_VERTICES = 0x01,
SG_IDX_NORMALS = 0x02,
SG_IDX_COLORS = 0x04,
SG_IDX_TEXCOORDS = 0x08
} sgIndexTypes;
};
enum {
enum sgPropertyTypes {
SG_MATERIAL = 0,
SG_INDEX_TYPES = 1
} sgPropertyTypes;
};
class sgSimpleBuffer {
@@ -174,7 +174,7 @@ static void read_object( gzFile fp,
int idx_size;
bool do_vertices, do_normals, do_colors, do_texcoords;
int j, k, idx;
static sgSimpleBuffer buf( 32768 ); // 32 Kb
sgSimpleBuffer buf( 32768 ); // 32 Kb
char material[256];
// default values
@@ -240,8 +240,8 @@ static void read_object( gzFile fp,
if ( nbytes > buf.get_size() ) { buf.resize( nbytes ); }
char *ptr = buf.get_ptr();
sgReadBytes( fp, nbytes, ptr );
int count = nbytes / (idx_size * sizeof(short));
short *sptr = (short *)ptr;
int count = nbytes / (idx_size * sizeof(unsigned short));
unsigned short *sptr = (unsigned short *)ptr;
int_list vs; vs.clear();
int_list ns; ns.clear();
int_list cs; cs.clear();
@@ -249,7 +249,7 @@ static void read_object( gzFile fp,
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
for ( idx = 0; idx < idx_size; ++idx ) {
sgEndianSwap( (unsigned short *)&(sptr[idx]) );
sgEndianSwap( (uint16_t *)&(sptr[idx]) );
}
}
idx = 0;
@@ -280,13 +280,13 @@ static void read_object( gzFile fp,
// read a binary file and populate the provided structures.
bool SGBinObject::read_bin( const string& file ) {
Point3D p;
SGVec3d p;
int i, j, k;
unsigned int nbytes;
static sgSimpleBuffer buf( 32768 ); // 32 Kb
sgSimpleBuffer buf( 32768 ); // 32 Kb
// zero out structures
gbs_center = Point3D( 0 );
gbs_center = SGVec3d(0, 0, 0);
gbs_radius = 0.0;
wgs84_nodes.clear();
@@ -322,7 +322,7 @@ bool SGBinObject::read_bin( const string& file ) {
string filegz = file + ".gz";
if ( (fp = gzopen( filegz.c_str(), "rb" )) == NULL ) {
SG_LOG( SG_EVENT, SG_ALERT,
"ERROR: opening " << file << " or " << filegz << "for reading!");
"ERROR: opening " << file << " or " << filegz << " for reading!");
return false;
}
@@ -403,17 +403,17 @@ bool SGBinObject::read_bin( const string& file ) {
double *dptr = (double *)ptr;
if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64 *)&(dptr[0]) );
sgEndianSwap( (uint64 *)&(dptr[1]) );
sgEndianSwap( (uint64 *)&(dptr[2]) );
sgEndianSwap( (uint64_t *)&(dptr[0]) );
sgEndianSwap( (uint64_t *)&(dptr[1]) );
sgEndianSwap( (uint64_t *)&(dptr[2]) );
}
gbs_center = Point3D( dptr[0], dptr[1], dptr[2] );
gbs_center = SGVec3d( dptr[0], dptr[1], dptr[2] );
// cout << "Center = " << gbs_center << endl;
ptr += sizeof(double) * 3;
float *fptr = (float *)ptr;
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)fptr );
sgEndianSwap( (uint32_t *)fptr );
}
gbs_radius = fptr[0];
// cout << "Bounding radius = " << gbs_radius << endl;
@@ -443,11 +443,11 @@ bool SGBinObject::read_bin( const string& file ) {
wgs84_nodes.reserve( count );
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
sgEndianSwap( (unsigned int *)&(fptr[2]) );
sgEndianSwap( (uint32_t *)&(fptr[0]) );
sgEndianSwap( (uint32_t *)&(fptr[1]) );
sgEndianSwap( (uint32_t *)&(fptr[2]) );
}
wgs84_nodes.push_back( Point3D(fptr[0], fptr[1], fptr[2]) );
wgs84_nodes.push_back( SGVec3d(fptr[0], fptr[1], fptr[2]) );
fptr += 3;
}
}
@@ -476,12 +476,13 @@ bool SGBinObject::read_bin( const string& file ) {
colors.reserve(count);
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
sgEndianSwap( (unsigned int *)&(fptr[2]) );
sgEndianSwap( (unsigned int *)&(fptr[3]) );
sgEndianSwap( (uint32_t *)&(fptr[0]) );
sgEndianSwap( (uint32_t *)&(fptr[1]) );
sgEndianSwap( (uint32_t *)&(fptr[2]) );
sgEndianSwap( (uint32_t *)&(fptr[3]) );
}
colors.push_back( Point3D( fptr[0], fptr[1], fptr[2] ) );
SGVec4f color( fptr[0], fptr[1], fptr[2], fptr[3] );
colors.push_back( color );
fptr += 4;
}
}
@@ -508,14 +509,11 @@ bool SGBinObject::read_bin( const string& file ) {
int count = nbytes / 3;
normals.reserve( count );
for ( k = 0; k < count; ++k ) {
sgdVec3 normal;
sgdSetVec3( normal,
(ptr[0]) / 127.5 - 1.0,
(ptr[1]) / 127.5 - 1.0,
(ptr[2]) / 127.5 - 1.0 );
sgdNormalizeVec3( normal );
SGVec3f normal((ptr[0]) / 127.5 - 1.0,
(ptr[1]) / 127.5 - 1.0,
(ptr[2]) / 127.5 - 1.0);
normals.push_back(Point3D(normal[0], normal[1], normal[2]));
normals.push_back(normalize(normal));
ptr += 3;
}
}
@@ -544,10 +542,10 @@ bool SGBinObject::read_bin( const string& file ) {
texcoords.reserve(count);
for ( k = 0; k < count; ++k ) {
if ( sgIsBigEndian() ) {
sgEndianSwap( (unsigned int *)&(fptr[0]) );
sgEndianSwap( (unsigned int *)&(fptr[1]) );
sgEndianSwap( (uint32_t *)&(fptr[0]) );
sgEndianSwap( (uint32_t *)&(fptr[1]) );
}
texcoords.push_back( Point3D( fptr[0], fptr[1], 0 ) );
texcoords.push_back( SGVec2f( fptr[0], fptr[1] ) );
fptr += 2;
}
}
@@ -612,28 +610,17 @@ bool SGBinObject::read_bin( const string& file ) {
bool SGBinObject::write_bin( const string& base, const string& name,
const SGBucket& b )
{
Point3D p;
sgVec2 t;
sgVec3 pt;
sgVec4 color;
int i, j;
unsigned char idx_mask;
int idx_size;
string dir = base + "/" + b.gen_base_path();
string command = "mkdir -p " + dir;
#if defined(_MSC_VER) || defined(__MINGW32__)
system( (string("mkdir ") + dir).c_str() );
#else
system(command.c_str());
#endif
string file = dir + "/" + name + ".gz";
cout << "Output file = " << file << endl;
SGPath file = base + "/" + b.gen_base_path() + "/" + name + ".gz";
file.create_dir( 0755 );
cout << "Output file = " << file.str() << endl;
gzFile fp;
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
cout << "ERROR: opening " << file << " for writing!" << endl;
cout << "ERROR: opening " << file.str() << " for writing!" << endl;
return false;
}
@@ -656,7 +643,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write header magic
sgWriteUInt( fp, SG_FILE_MAGIC_NUMBER );
time_t calendar_time = time(NULL);
sgWriteLong( fp, (long int)calendar_time );
sgWriteLong( fp, (int32_t)calendar_time );
// calculate and write number of top level objects
string material;
@@ -745,9 +732,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteShort( fp, 1 ); // nelements
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
p = wgs84_nodes[i] - gbs_center;
sgSetVec3( pt, p.x(), p.y(), p.z() );
sgWriteVec3( fp, pt );
SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center);
sgWriteVec3( fp, p.data() );
}
// dump vertex color list
@@ -756,12 +742,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteShort( fp, 1 ); // nelements
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) {
p = colors[i];
// Right now we have a place holder for color alpha but we
// need to update the interface so the calling program can
// provide the info.
sgSetVec4( color, p.x(), p.y(), p.z(), 1.0 );
sgWriteVec4( fp, color );
sgWriteVec4( fp, colors[i].data() );
}
// dump vertex normal list
@@ -771,7 +752,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
char normal[3];
for ( i = 0; i < (int)normals.size(); ++i ) {
p = normals[i];
SGVec3f p = normals[i];
normal[0] = (unsigned char)((p.x() + 1.0) * 127.5);
normal[1] = (unsigned char)((p.y() + 1.0) * 127.5);
normal[2] = (unsigned char)((p.z() + 1.0) * 127.5);
@@ -784,9 +765,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteShort( fp, 1 ); // nelements
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
for ( i = 0; i < (int)texcoords.size(); ++i ) {
p = texcoords[i];
sgSetVec2( t, p.x(), p.y() );
sgWriteVec2( fp, t );
sgWriteVec2( fp, texcoords[i].data() );
}
// dump point groups if they exist
@@ -858,7 +837,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// find next group
material = tri_materials[start];
while ( (end < (int)tri_materials.size()) &&
(material == tri_materials[end]) )
(material == tri_materials[end]) &&
3*(end-start) < 32760 )
{
// cout << "end = " << end << endl;
end++;
@@ -1048,24 +1028,15 @@ bool SGBinObject::write_bin( const string& base, const string& name,
bool SGBinObject::write_ascii( const string& base, const string& name,
const SGBucket& b )
{
Point3D p;
int i, j;
string dir = base + "/" + b.gen_base_path();
string command = "mkdir -p " + dir;
#if defined(_MSC_VER) || defined(__MINGW32__)
system( (string("mkdir ") + dir).c_str() );
#else
system(command.c_str());
#endif
// string file = dir + "/" + b.gen_index_str();
string file = dir + "/" + name;
cout << "Output file = " << file << endl;
SGPath file = base + "/" + b.gen_base_path() + "/" + name;
file.create_dir( 0755 );
cout << "Output file = " << file.str() << endl;
FILE *fp;
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
cout << "ERROR: opening " << file << " for writing!" << endl;
cout << "ERROR: opening " << file.str() << " for writing!" << endl;
return false;
}
@@ -1098,7 +1069,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
// dump vertex list
fprintf(fp, "# vertex list\n");
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
p = wgs84_nodes[i] - gbs_center;
SGVec3d p = wgs84_nodes[i] - gbs_center;
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
}
@@ -1106,7 +1077,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
fprintf(fp, "# vertex normal list\n");
for ( i = 0; i < (int)normals.size(); ++i ) {
p = normals[i];
SGVec3f p = normals[i];
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
}
fprintf(fp, "\n");
@@ -1114,7 +1085,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
// dump texture coordinates
fprintf(fp, "# texture coordinate list\n");
for ( i = 0; i < (int)texcoords.size(); ++i ) {
p = texcoords[i];
SGVec2f p = texcoords[i];
fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() );
}
fprintf(fp, "\n");
@@ -1140,13 +1111,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
// make a list of points for the group
point_list group_nodes;
group_nodes.clear();
Point3D bs_center;
SGVec3d bs_center;
double bs_radius = 0;
for ( i = start; i < end; ++i ) {
for ( j = 0; j < (int)tris_v[i].size(); ++j ) {
group_nodes.push_back( wgs84_nodes[ tris_v[i][j] ] );
bs_center = sgCalcCenter( group_nodes );
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ tris_v[i][j] ]) );
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
}
}
@@ -1191,13 +1162,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
// make a list of points for the group
point_list group_nodes;
group_nodes.clear();
Point3D bs_center;
SGVec3d bs_center;
double bs_radius = 0;
for ( i = start; i < end; ++i ) {
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
group_nodes.push_back( wgs84_nodes[ strips_v[i][j] ] );
bs_center = sgCalcCenter( group_nodes );
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ strips_v[i][j] ]) );
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
}
}
@@ -1224,7 +1195,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
// close the file
fclose(fp);
command = "gzip --force --best " + file;
string command = "gzip --force --best " + file.str();
system(command.c_str());
return true;

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started January 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -89,13 +89,13 @@ typedef group_list::const_iterator const_group_list_iterator;
class SGBinObject {
unsigned short version;
Point3D gbs_center;
SGVec3d gbs_center;
float gbs_radius;
point_list wgs84_nodes; // vertex list
point_list colors; // color list
point_list normals; // normal list
point_list texcoords; // texture coordinate list
std::vector<SGVec3d> wgs84_nodes; // vertex list
std::vector<SGVec4f> colors; // color list
std::vector<SGVec3f> normals; // normal list
std::vector<SGVec2f> texcoords; // texture coordinate list
group_list pts_v; // points vertex index
group_list pts_n; // points normal index
@@ -125,23 +125,51 @@ public:
inline unsigned short get_version() const { return version; }
inline const Point3D& get_gbs_center() const { return gbs_center; }
inline void set_gbs_center( const Point3D& p ) { gbs_center = p; }
inline Point3D get_gbs_center() const { return Point3D::fromSGVec3(gbs_center); }
inline void set_gbs_center( const Point3D& p ) { gbs_center = p.toSGVec3d(); }
inline const SGVec3d& get_gbs_center2() const { return gbs_center; }
inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; }
inline float get_gbs_radius() const { return gbs_radius; }
inline void set_gbs_radius( float r ) { gbs_radius = r; }
inline const point_list& get_wgs84_nodes() const { return wgs84_nodes; }
inline void set_wgs84_nodes( const point_list& n ) { wgs84_nodes = n; }
inline const std::vector<SGVec3d>& get_wgs84_nodes() const
{ return wgs84_nodes; }
inline void set_wgs84_nodes( const std::vector<SGVec3d>& n )
{ wgs84_nodes = n; }
inline void set_wgs84_nodes( const point_list& n )
{
wgs84_nodes.resize(n.size());
for (unsigned i = 0; i < wgs84_nodes.size(); ++i)
wgs84_nodes[i] = n[i].toSGVec3d();
}
inline const point_list& get_colors() const { return colors; }
inline void set_colors( const point_list& c ) { colors = c; }
inline const std::vector<SGVec4f>& get_colors() const { return colors; }
inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; }
inline void set_colors( const point_list& c )
{
colors.resize(c.size());
for (unsigned i = 0; i < colors.size(); ++i)
colors[i] = SGVec4f(c[i].toSGVec3f(), 1);
}
inline const point_list& get_normals() const { return normals; }
inline void set_normals( const point_list& n ) { normals = n; }
inline const std::vector<SGVec3f>& get_normals() const { return normals; }
inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; }
inline void set_normals( const point_list& n )
{
normals.resize(n.size());
for (unsigned i = 0; i < normals.size(); ++i)
normals[i] = n[i].toSGVec3f();
}
inline const point_list& get_texcoords() const { return texcoords; }
inline void set_texcoords( const point_list& t ) { texcoords = t; }
inline const std::vector<SGVec2f>& get_texcoords() const { return texcoords; }
inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; }
inline void set_texcoords( const point_list& t )
{
texcoords.resize(t.size());
for (unsigned i = 0; i < texcoords.size(); ++i)
texcoords[i] = t[i].toSGVec2f();
}
inline const group_list& get_pts_v() const { return pts_v; }
inline void set_pts_v( const group_list& g ) { pts_v = g; }

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -29,6 +29,7 @@
# include <io.h>
#endif
#include <simgear/misc/stdint.hxx>
#include <simgear/debug/logstream.hxx>
#include "sg_file.hxx"
@@ -39,6 +40,7 @@ SG_USING_STD(string);
SGFile::SGFile( const string &file) {
set_type( sgFileType );
file_name = file;
eof_flag = true;
}
@@ -70,6 +72,7 @@ bool SGFile::open( const SGProtocolDir d ) {
return false;
}
eof_flag = false;
return true;
}
@@ -77,7 +80,11 @@ bool SGFile::open( const SGProtocolDir d ) {
// read a block of data of specified size
int SGFile::read( char *buf, int length ) {
// read a chunk
return ::read( fp, buf, length );
ssize_t result = ::read( fp, buf, length );
if ( length > 0 && result == 0 ) {
eof_flag = true;
}
return result;
}
@@ -87,7 +94,10 @@ int SGFile::readline( char *buf, int length ) {
int pos = lseek( fp, 0, SEEK_CUR );
// read a chunk
int result = ::read( fp, buf, length );
ssize_t result = ::read( fp, buf, length );
if ( length > 0 && result == 0 ) {
eof_flag = true;
}
// find the end of line and reset position
int i;
@@ -130,5 +140,6 @@ bool SGFile::close() {
return false;
}
eof_flag = true;
return true;
}

View File

@@ -4,7 +4,7 @@
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -18,7 +18,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -54,6 +54,7 @@ class SGFile : public SGIOChannel {
string file_name;
int fp;
bool eof_flag;
public:
@@ -89,6 +90,9 @@ public:
/** @return the name of the file being manipulated. */
inline string get_file_name() const { return file_name; }
/** @return true of eof conditions exists */
inline bool eof() const { return eof_flag; };
};

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$

View File

@@ -3,7 +3,7 @@
// Written by Curtis Olson, started November 1999.
// Modified by Bernie Bright <bbright@bigpond.net.au>, May 2002.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -17,10 +17,13 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started November 1999.
//
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -16,10 +16,13 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started November 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$

View File

@@ -1,3 +1,7 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <unistd.h>

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
@@ -57,10 +70,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$
@@ -76,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},
@@ -187,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;
@@ -273,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];
}
}
@@ -341,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;
@@ -398,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];
}
}

View File

@@ -26,10 +26,9 @@
// 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 Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 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.
//
// $Id$

View File

@@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started July 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$

View File

@@ -5,7 +5,7 @@
// Written by Curtis Olson, started July 2000.
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
@@ -28,9 +28,9 @@
#define _MAGVAR_HXX
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
/**

View File

@@ -1,3 +1,4 @@
.deps
Makefile
Makefile.in
SGMathTest

View File

@@ -1,11 +1,19 @@
includedir = @includedir@/math
check_PROGRAMS = SGMathTest SGGeometryTest
TESTS = $(check_PROGRAMS)
SGMathTest_SOURCES = SGMathTest.cxx
SGMathTest_LDADD = libsgmath.a $(base_LIBS)
SGGeometryTest_SOURCES = SGGeometryTest.cxx
SGGeometryTest_LDADD = libsgmath.a $(base_LIBS)
lib_LIBRARIES = libsgmath.a
include_HEADERS = \
interpolater.hxx \
leastsqs.hxx \
localconsts.hxx \
point3d.hxx \
polar3d.hxx \
sg_geodesy.hxx \
@@ -13,9 +21,28 @@ include_HEADERS = \
sg_random.h \
sg_types.hxx \
vector.hxx \
fastmath.hxx
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
SGBox.hxx \
SGCMath.hxx \
SGGeoc.hxx \
SGGeod.hxx \
SGGeodesy.hxx \
SGGeometry.hxx \
SGGeometryFwd.hxx \
SGIntersect.hxx \
SGLimits.hxx \
SGLineSegment.hxx \
SGMatrix.hxx \
SGMath.hxx \
SGMathFwd.hxx \
SGMisc.hxx \
SGPlane.hxx \
SGQuat.hxx \
SGRay.hxx \
SGSphere.hxx \
SGTriangle.hxx \
SGVec2.hxx \
SGVec3.hxx \
SGVec4.hxx
libsgmath_a_SOURCES = \
interpolater.cxx \
@@ -24,6 +51,6 @@ libsgmath_a_SOURCES = \
sg_geodesy.cxx \
sg_random.c \
vector.cxx \
fastmath.cxx
SGGeodesy.cxx
INCLUDES = -I$(top_srcdir)

107
simgear/math/SGBox.hxx Normal file
View File

@@ -0,0 +1,107 @@
// 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 SGBox_H
#define SGBox_H
template<typename T>
class SGBox {
public:
SGBox() :
_min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()),
_max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max())
{ }
void setMin(const SGVec3<T>& min)
{ _min = min; }
const SGVec3<T>& getMin() const
{ return _min; }
void setMax(const SGVec3<T>& max)
{ _max = max; }
const SGVec3<T>& getMax() const
{ return _max; }
// Only works for floating point types
SGVec3<T> getCenter() const
{ return T(0.5)*(_min + _max); }
// Only valid for nonempty boxes
SGVec3<T> getSize() const
{ return _max - _min; }
T getVolume() const
{
if (empty())
return 0;
return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
}
const bool empty() const
{ return !valid(); }
bool valid() const
{
if (_max[0] < _min[0])
return false;
if (_max[1] < _min[1])
return false;
if (_max[2] < _min[2])
return false;
return true;
}
void clear()
{
_min[0] = SGLimits<T>::max();
_min[1] = SGLimits<T>::max();
_min[2] = SGLimits<T>::max();
_max[0] = -SGLimits<T>::max();
_max[1] = -SGLimits<T>::max();
_max[2] = -SGLimits<T>::max();
}
void expandBy(const SGVec3<T>& v)
{ _min = min(_min, v); _max = max(_max, v); }
void expandBy(const SGBox<T>& b)
{ _min = min(_min, b._min); _max = max(_max, b._max); }
// Note that this only works if the box is nonmepty
unsigned getBroadestAxis() const
{
SGVec3d size = getSize();
if (size[1] <= size[0] && size[2] <= size[0])
return 0;
else if (size[2] <= size[1])
return 1;
else
return 2;
}
private:
SGVec3<T> _min;
SGVec3<T> _max;
};
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGBox<T>& box)
{ return s << "min = " << box.getMin() << ", max = " << box.getMax(); }
#endif

31
simgear/math/SGCMath.hxx Normal file
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

302
simgear/math/SGGeoc.hxx Normal file
View File

@@ -0,0 +1,302 @@
// 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 SGGeoc_H
#define SGGeoc_H
#include <simgear/constants.h>
// #define SG_GEOC_NATIVE_DEGREE
/// Class representing a geocentric location
class SGGeoc {
public:
/// Default constructor, initializes the instance to lat = lon = lat = 0
SGGeoc(void);
/// Factory from angular values in radians and radius in ft
static SGGeoc fromRadFt(double lon, double lat, double radius);
/// Factory from angular values in degrees and radius in ft
static SGGeoc fromDegFt(double lon, double lat, double radius);
/// Factory from angular values in radians and radius in m
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;
/// Set the geocentric longitude from the argument given in radians
void setLongitudeRad(double lon);
/// Return the geocentric longitude in degrees
double getLongitudeDeg(void) const;
/// Set the geocentric longitude from the argument given in degrees
void setLongitudeDeg(double lon);
/// Return the geocentric latitude in radians
double getLatitudeRad(void) const;
/// Set the geocentric latitude from the argument given in radians
void setLatitudeRad(double lat);
/// Return the geocentric latitude in degrees
double getLatitudeDeg(void) const;
/// Set the geocentric latitude from the argument given in degrees
void setLatitudeDeg(double lat);
/// Return the geocentric radius in meters
double getRadiusM(void) const;
/// Set the geocentric radius from the argument given in meters
void setRadiusM(double radius);
/// Return the geocentric radius in feet
double getRadiusFt(void) const;
/// Set the geocentric radius from the argument given in feet
void setRadiusFt(double radius);
private:
/// This one is private since construction is not unique if you do
/// not know the units of the arguments, use the factory methods for
/// that purpose
SGGeoc(double lon, double lat, double radius);
/// The actual data, angles in degree, radius in meters
/// The rationale for storing the values in degrees is that most code places
/// in flightgear/terragear use degrees as a nativ input and output value.
/// The places where it makes sense to use radians is when we convert
/// to other representations or compute rotation matrices. But both tasks
/// are computionally intensive anyway and that additional 'toRadian'
/// conversion does not hurt too much
double _lon;
double _lat;
double _radius;
};
inline
SGGeoc::SGGeoc(void) :
_lon(0), _lat(0), _radius(0)
{
}
inline
SGGeoc::SGGeoc(double lon, double lat, double radius) :
_lon(lon), _lat(lat), _radius(radius)
{
}
inline
SGGeoc
SGGeoc::fromRadFt(double lon, double lat, double radius)
{
#ifdef SG_GEOC_NATIVE_DEGREE
return SGGeoc(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
radius*SG_FEET_TO_METER);
#else
return SGGeoc(lon, lat, radius*SG_FEET_TO_METER);
#endif
}
inline
SGGeoc
SGGeoc::fromDegFt(double lon, double lat, double radius)
{
#ifdef SG_GEOC_NATIVE_DEGREE
return SGGeoc(lon, lat, radius*SG_FEET_TO_METER);
#else
return SGGeoc(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
radius*SG_FEET_TO_METER);
#endif
}
inline
SGGeoc
SGGeoc::fromRadM(double lon, double lat, double radius)
{
#ifdef SG_GEOC_NATIVE_DEGREE
return SGGeoc(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
radius);
#else
return SGGeoc(lon, lat, radius);
#endif
}
inline
SGGeoc
SGGeoc::fromDegM(double lon, double lat, double radius)
{
#ifdef SG_GEOC_NATIVE_DEGREE
return SGGeoc(lon, lat, radius);
#else
return SGGeoc(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
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
{
#ifdef SG_GEOC_NATIVE_DEGREE
return _lon*SGD_DEGREES_TO_RADIANS;
#else
return _lon;
#endif
}
inline
void
SGGeoc::setLongitudeRad(double lon)
{
#ifdef SG_GEOC_NATIVE_DEGREE
_lon = lon*SGD_RADIANS_TO_DEGREES;
#else
_lon = lon;
#endif
}
inline
double
SGGeoc::getLongitudeDeg(void) const
{
#ifdef SG_GEOC_NATIVE_DEGREE
return _lon;
#else
return _lon*SGD_DEGREES_TO_RADIANS;
#endif
}
inline
void
SGGeoc::setLongitudeDeg(double lon)
{
#ifdef SG_GEOC_NATIVE_DEGREE
_lon = lon;
#else
_lon = lon*SGD_RADIANS_TO_DEGREES;
#endif
}
inline
double
SGGeoc::getLatitudeRad(void) const
{
#ifdef SG_GEOC_NATIVE_DEGREE
return _lat*SGD_DEGREES_TO_RADIANS;
#else
return _lat;
#endif
}
inline
void
SGGeoc::setLatitudeRad(double lat)
{
#ifdef SG_GEOC_NATIVE_DEGREE
_lat = lat*SGD_RADIANS_TO_DEGREES;
#else
_lat = lat;
#endif
}
inline
double
SGGeoc::getLatitudeDeg(void) const
{
#ifdef SG_GEOC_NATIVE_DEGREE
return _lat;
#else
return _lat*SGD_DEGREES_TO_RADIANS;
#endif
}
inline
void
SGGeoc::setLatitudeDeg(double lat)
{
#ifdef SG_GEOC_NATIVE_DEGREE
_lat = lat;
#else
_lat = lat*SGD_RADIANS_TO_DEGREES;
#endif
}
inline
double
SGGeoc::getRadiusM(void) const
{
return _radius;
}
inline
void
SGGeoc::setRadiusM(double radius)
{
_radius = radius;
}
inline
double
SGGeoc::getRadiusFt(void) const
{
return _radius*SG_METER_TO_FEET;
}
inline
void
SGGeoc::setRadiusFt(double radius)
{
_radius = radius*SG_FEET_TO_METER;
}
/// Output to an ostream
template<typename char_type, typename traits_type>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeoc& g)
{
return s << "lon = " << g.getLongitudeDeg()
<< ", lat = " << g.getLatitudeDeg()
<< ", radius = " << g.getRadiusM();
}
#endif

329
simgear/math/SGGeod.hxx Normal file
View File

@@ -0,0 +1,329 @@
// 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 SGGeod_H
#define SGGeod_H
#include <simgear/constants.h>
// #define SG_GEOD_NATIVE_DEGREE
/// Class representing a geodetic location
class SGGeod {
public:
/// Default constructor, initializes the instance to lat = lon = elev = 0
SGGeod(void);
/// Factory from angular values in radians and elevation is 0
static SGGeod fromRad(double lon, double lat);
/// Factory from angular values in degrees and elevation is 0
static SGGeod fromDeg(double lon, double lat);
/// Factory from angular values in radians and elevation in ft
static SGGeod fromRadFt(double lon, double lat, double elevation);
/// Factory from angular values in degrees and elevation in ft
static SGGeod fromDegFt(double lon, double lat, double elevation);
/// Factory from angular values in radians and elevation in m
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;
/// Set the geodetic longitude from the argument given in radians
void setLongitudeRad(double lon);
/// Return the geodetic longitude in degrees
double getLongitudeDeg(void) const;
/// Set the geodetic longitude from the argument given in degrees
void setLongitudeDeg(double lon);
/// Return the geodetic latitude in radians
double getLatitudeRad(void) const;
/// Set the geodetic latitude from the argument given in radians
void setLatitudeRad(double lat);
/// Return the geodetic latitude in degrees
double getLatitudeDeg(void) const;
/// Set the geodetic latitude from the argument given in degrees
void setLatitudeDeg(double lat);
/// Return the geodetic elevation in meters
double getElevationM(void) const;
/// Set the geodetic elevation from the argument given in meters
void setElevationM(double elevation);
/// Return the geodetic elevation in feet
double getElevationFt(void) const;
/// Set the geodetic elevation from the argument given in feet
void setElevationFt(double elevation);
private:
/// This one is private since construction is not unique if you do
/// not know the units of the arguments. Use the factory methods for
/// that purpose
SGGeod(double lon, double lat, double elevation);
/// The actual data, angles in degree, elevation in meters
/// The rationale for storing the values in degrees is that most code places
/// in flightgear/terragear use degrees as a nativ input and output value.
/// The places where it makes sense to use radians is when we convert
/// to other representations or compute rotation matrices. But both tasks
/// are computionally intensive anyway and that additional 'toRadian'
/// conversion does not hurt too much
double _lon;
double _lat;
double _elevation;
};
inline
SGGeod::SGGeod(void) :
_lon(0), _lat(0), _elevation(0)
{
}
inline
SGGeod::SGGeod(double lon, double lat, double elevation) :
_lon(lon), _lat(lat), _elevation(elevation)
{
}
inline
SGGeod
SGGeod::fromRad(double lon, double lat)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES, 0);
#else
return SGGeod(lon, lat, 0);
#endif
}
inline
SGGeod
SGGeod::fromDeg(double lon, double lat)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon, lat, 0);
#else
return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0);
#endif
}
inline
SGGeod
SGGeod::fromRadFt(double lon, double lat, double elevation)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
elevation*SG_FEET_TO_METER);
#else
return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
#endif
}
inline
SGGeod
SGGeod::fromDegFt(double lon, double lat, double elevation)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon, lat, elevation*SG_FEET_TO_METER);
#else
return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
elevation*SG_FEET_TO_METER);
#endif
}
inline
SGGeod
SGGeod::fromRadM(double lon, double lat, double elevation)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon*SGD_RADIANS_TO_DEGREES, lat*SGD_RADIANS_TO_DEGREES,
elevation);
#else
return SGGeod(lon, lat, elevation);
#endif
}
inline
SGGeod
SGGeod::fromDegM(double lon, double lat, double elevation)
{
#ifdef SG_GEOD_NATIVE_DEGREE
return SGGeod(lon, lat, elevation);
#else
return SGGeod(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS,
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
{
#ifdef SG_GEOD_NATIVE_DEGREE
return _lon*SGD_DEGREES_TO_RADIANS;
#else
return _lon;
#endif
}
inline
void
SGGeod::setLongitudeRad(double lon)
{
#ifdef SG_GEOD_NATIVE_DEGREE
_lon = lon*SGD_RADIANS_TO_DEGREES;
#else
_lon = lon;
#endif
}
inline
double
SGGeod::getLongitudeDeg(void) const
{
#ifdef SG_GEOD_NATIVE_DEGREE
return _lon;
#else
return _lon*SGD_RADIANS_TO_DEGREES;
#endif
}
inline
void
SGGeod::setLongitudeDeg(double lon)
{
#ifdef SG_GEOD_NATIVE_DEGREE
_lon = lon;
#else
_lon = lon*SGD_DEGREES_TO_RADIANS;
#endif
}
inline
double
SGGeod::getLatitudeRad(void) const
{
#ifdef SG_GEOD_NATIVE_DEGREE
return _lat*SGD_DEGREES_TO_RADIANS;
#else
return _lat;
#endif
}
inline
void
SGGeod::setLatitudeRad(double lat)
{
#ifdef SG_GEOD_NATIVE_DEGREE
_lat = lat*SGD_RADIANS_TO_DEGREES;
#else
_lat = lat;
#endif
}
inline
double
SGGeod::getLatitudeDeg(void) const
{
#ifdef SG_GEOD_NATIVE_DEGREE
return _lat;
#else
return _lat*SGD_RADIANS_TO_DEGREES;
#endif
}
inline
void
SGGeod::setLatitudeDeg(double lat)
{
#ifdef SG_GEOD_NATIVE_DEGREE
_lat = lat;
#else
_lat = lat*SGD_DEGREES_TO_RADIANS;
#endif
}
inline
double
SGGeod::getElevationM(void) const
{
return _elevation;
}
inline
void
SGGeod::setElevationM(double elevation)
{
_elevation = elevation;
}
inline
double
SGGeod::getElevationFt(void) const
{
return _elevation*SG_METER_TO_FEET;
}
inline
void
SGGeod::setElevationFt(double elevation)
{
_elevation = elevation*SG_FEET_TO_METER;
}
/// Output to an ostream
template<typename char_type, typename traits_type>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGGeod& g)
{
return s << "lon = " << g.getLongitudeDeg()
<< "deg, lat = " << g.getLatitudeDeg()
<< "deg, elev = " << g.getElevationM()
<< "m";
}
#endif

157
simgear/math/SGGeodesy.cxx Normal file
View File

@@ -0,0 +1,157 @@
// 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.
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <cmath>
#include "SGMath.hxx"
// These are hard numbers from the WGS84 standard. DON'T MODIFY
// unless you want to change the datum.
#define _EQURAD 6378137.0
#define _FLATTENING 298.257223563
// These are derived quantities more useful to the code:
#if 0
#define _SQUASH (1 - 1/_FLATTENING)
#define _STRETCH (1/_SQUASH)
#define _POLRAD (EQURAD * _SQUASH)
#else
// High-precision versions of the above produced with an arbitrary
// precision calculator (the compiler might lose a few bits in the FPU
// operations). These are specified to 81 bits of mantissa, which is
// higher than any FPU known to me:
#define _SQUASH 0.9966471893352525192801545
#define _STRETCH 1.0033640898209764189003079
#define _POLRAD 6356752.3142451794975639668
#endif
// The constants from the WGS84 standard
const double SGGeodesy::EQURAD = _EQURAD;
const double SGGeodesy::iFLATTENING = _FLATTENING;
const double SGGeodesy::SQUASH = _SQUASH;
const double SGGeodesy::STRETCH = _STRETCH;
const double SGGeodesy::POLRAD = _POLRAD;
// additional derived and precomputable ones
// for the geodetic conversion algorithm
#define E2 fabs(1 - _SQUASH*_SQUASH)
static double a = _EQURAD;
static double ra2 = 1/(_EQURAD*_EQURAD);
static double e = sqrt(E2);
static double e2 = E2;
static double e4 = E2*E2;
#undef _EQURAD
#undef _FLATTENING
#undef _SQUASH
#undef _STRETCH
#undef _POLRAD
#undef E2
void
SGGeodesy::SGCartToGeod(const SGVec3<double>& cart, SGGeod& geod)
{
// according to
// H. Vermeille,
// Direct transformation from geocentric to geodetic ccordinates,
// Journal of Geodesy (2002) 76:451-454
double X = cart(0);
double Y = cart(1);
double Z = cart(2);
double XXpYY = X*X+Y*Y;
double sqrtXXpYY = sqrt(XXpYY);
double p = XXpYY*ra2;
double q = Z*Z*(1-e2)*ra2;
double r = 1/6.0*(p+q-e4);
double s = e4*p*q/(4*r*r*r);
double t = pow(1+s+sqrt(s*(2+s)), 1/3.0);
double u = r*(1+t+1/t);
double v = sqrt(u*u+e4*q);
double w = e2*(u+v-q)/(2*v);
double k = sqrt(u+v+w*w)-w;
double D = k*sqrtXXpYY/(k+e2);
geod.setLongitudeRad(2*atan2(Y, X+sqrtXXpYY));
double sqrtDDpZZ = sqrt(D*D+Z*Z);
geod.setLatitudeRad(2*atan2(Z, D+sqrtDDpZZ));
geod.setElevationM((k+e2-1)*sqrtDDpZZ/k);
}
void
SGGeodesy::SGGeodToCart(const SGGeod& geod, SGVec3<double>& cart)
{
// according to
// H. Vermeille,
// Direct transformation from geocentric to geodetic ccordinates,
// Journal of Geodesy (2002) 76:451-454
double lambda = geod.getLongitudeRad();
double phi = geod.getLatitudeRad();
double h = geod.getElevationM();
double sphi = sin(phi);
double n = a/sqrt(1-e2*sphi*sphi);
double cphi = cos(phi);
double slambda = sin(lambda);
double clambda = cos(lambda);
cart(0) = (h+n)*cphi*clambda;
cart(1) = (h+n)*cphi*slambda;
cart(2) = (h+n-e2*n)*sphi;
}
double
SGGeodesy::SGGeodToSeaLevelRadius(const SGGeod& geod)
{
// this is just a simplified version of the SGGeodToCart function above,
// substitute h = 0, take the 2-norm of the cartesian vector and simplify
double phi = geod.getLatitudeRad();
double sphi = sin(phi);
double sphi2 = sphi*sphi;
return a*sqrt((1 + (e4 - 2*e2)*sphi2)/(1 - e2*sphi2));
}
void
SGGeodesy::SGCartToGeoc(const SGVec3<double>& cart, SGGeoc& geoc)
{
double minVal = SGLimits<double>::min();
if (fabs(cart(0)) < minVal && fabs(cart(1)) < minVal)
geoc.setLongitudeRad(0);
else
geoc.setLongitudeRad(atan2(cart(1), cart(0)));
double nxy = sqrt(cart(0)*cart(0) + cart(1)*cart(1));
if (fabs(nxy) < minVal && fabs(cart(2)) < minVal)
geoc.setLatitudeRad(0);
else
geoc.setLatitudeRad(atan2(cart(2), nxy));
geoc.setRadiusM(norm(cart));
}
void
SGGeodesy::SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart)
{
double lat = geoc.getLatitudeRad();
double lon = geoc.getLongitudeRad();
double slat = sin(lat);
double clat = cos(lat);
double slon = sin(lon);
double clon = cos(lon);
cart = geoc.getRadiusM()*SGVec3<double>(clat*clon, clat*slon, slat);
}

View File

@@ -0,0 +1,50 @@
// 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 SGGeodesy_H
#define SGGeodesy_H
class SGGeodesy {
public:
// Hard numbers from the WGS84 standard.
static const double EQURAD;
static const double iFLATTENING;
static const double SQUASH;
static const double STRETCH;
static const double POLRAD;
/// Takes a cartesian coordinate data and returns the geodetic
/// coordinates.
static void SGCartToGeod(const SGVec3<double>& cart, SGGeod& geod);
/// Takes a geodetic coordinate data and returns the cartesian
/// coordinates.
static void SGGeodToCart(const SGGeod& geod, SGVec3<double>& cart);
/// Takes a geodetic coordinate data and returns the sea level radius.
static double SGGeodToSeaLevelRadius(const SGGeod& geod);
/// Takes a cartesian coordinate data and returns the geocentric
/// coordinates.
static void SGCartToGeoc(const SGVec3<double>& cart, SGGeoc& geoc);
/// Takes a geocentric coordinate data and returns the cartesian
/// coordinates.
static void SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart);
};
#endif

View File

@@ -0,0 +1,38 @@
// 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 SGGeometry_HXX
#define SGGeometry_HXX
// Required ...
#include "SGMath.hxx"
// Make sure all is defined
#include "SGGeometryFwd.hxx"
// Geometric primitives we know about
#include "SGBox.hxx"
#include "SGSphere.hxx"
#include "SGRay.hxx"
#include "SGLineSegment.hxx"
#include "SGPlane.hxx"
#include "SGTriangle.hxx"
// Intersection tests
#include "SGIntersect.hxx"
#endif

View File

@@ -0,0 +1,51 @@
// 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 SGGeometryFwd_HXX
#define SGGeometryFwd_HXX
template<typename T>
class SGBox;
typedef SGBox<float> SGBoxf;
typedef SGBox<double> SGBoxd;
template<typename T>
class SGSphere;
typedef SGSphere<float> SGSpheref;
typedef SGSphere<double> SGSphered;
template<typename T>
class SGRay;
typedef SGRay<float> SGRayf;
typedef SGRay<double> SGRayd;
template<typename T>
class SGLineSegment;
typedef SGLineSegment<float> SGLineSegmentf;
typedef SGLineSegment<double> SGLineSegmentd;
template<typename T>
class SGPlane;
typedef SGPlane<float> SGPlanef;
typedef SGPlane<double> SGPlaned;
template<typename T>
class SGTriangle;
typedef SGTriangle<float> SGTrianglef;
typedef SGTriangle<double> SGTriangled;
#endif

View File

@@ -0,0 +1,442 @@
// 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.
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <cstdlib>
#include <iostream>
#include "SGGeometry.hxx"
#include "sg_random.h"
template<typename T>
SGVec3<T> rndVec3(void)
{
return SGVec3<T>(sg_random(), sg_random(), sg_random());
}
template<typename T>
bool
TriangleLineIntersectionTest(void)
{
unsigned nTests = 100000;
unsigned failedCount = 0;
for (unsigned i = 0; i < nTests; ++i) {
SGVec3<T> v0 = rndVec3<T>();
SGVec3<T> v1 = rndVec3<T>();
SGVec3<T> v2 = rndVec3<T>();
SGTriangle<T> tri(v0, v1, v2);
// generate random coeficients
T u = 4*sg_random() - 2;
T v = 4*sg_random() - 2;
T t = 4*sg_random() - 2;
SGVec3<T> isectpt = v0 + u*(v1 - v0) + v*(v2 - v0);
SGLineSegment<T> lineSegment;
SGVec3<T> dir = rndVec3<T>();
SGVec3<T> isectres;
lineSegment.set(isectpt - t*dir, isectpt + (1 - t)*dir);
if (intersects(isectres, tri, lineSegment)) {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) {
if (!equivalent(isectres, isectpt)) {
std::cout << "Failed line segment intersection test #" << i
<< ": not equivalent!\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << lineSegment << std::endl;
++failedCount;
}
} else {
std::cout << "Failed line segment intersection test #" << i
<< ": false positive!\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << lineSegment << std::endl;
++failedCount;
}
} else {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) {
std::cout << "Failed line segment intersection test #" << i
<< ": false negative!\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << lineSegment << std::endl;
++failedCount;
}
}
SGRay<T> ray;
ray.set(isectpt - t*dir, dir);
if (intersects(isectres, tri, ray)) {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) {
if (!equivalent(isectres, isectpt)) {
std::cout << "Failed ray intersection test #" << i
<< ": not equivalent!\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << ray << std::endl;
++failedCount;
}
} else {
std::cout << "Failed ray intersection test #" << i
<< ": false positive!\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << ray << std::endl;
++failedCount;
}
} else {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) {
std::cout << "Failed ray intersection test #" << i
<< ": false negative !\nu = "
<< u << ", v = " << v << ", t = " << t
<< "\n" << tri << "\n" << ray << std::endl;
++failedCount;
}
}
}
if (nTests < 100*failedCount) {
std::cout << "Failed ray intersection tests: " << failedCount
<< " tests out of " << nTests
<< " went wrong. Abort!" << std::endl;
return false;
}
/// Some crude handmade test
SGVec3<T> v0 = SGVec3<T>(0, 0, 0);
SGVec3<T> v1 = SGVec3<T>(1, 0, 0);
SGVec3<T> v2 = SGVec3<T>(0, 1, 0);
SGTriangle<T> tri(v0, v1, v2);
SGRay<T> ray;
ray.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0.1, 0.1, -1));
if (!intersects(tri, ray)) {
std::cout << "Failed test #1!" << std::endl;
return false;
}
ray.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 0, -1));
if (!intersects(tri, ray)) {
std::cout << "Failed test #2!" << std::endl;
return false;
}
SGLineSegment<T> lineSegment;
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0.1, 0.1, -1));
if (!intersects(tri, lineSegment)) {
std::cout << "Failed test #3!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 0, -1));
if (!intersects(tri, lineSegment)) {
std::cout << "Failed test #4!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 1, -1));
if (!intersects(tri, lineSegment)) {
std::cout << "Failed test #5!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 0, -1));
if (!intersects(tri, lineSegment)) {
std::cout << "Failed test #6!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 1, -1));
if (!intersects(tri, lineSegment)) {
std::cout << "Failed test #7!" << std::endl;
return false;
}
// is exactly in the plane
// FIXME: cannot detect that yet ??
// lineSegment.set(SGVec3<T>(0, 0, 0), SGVec3<T>(1, 0, 0));
// if (!intersects(tri, lineSegment)) {
// std::cout << "Failed test #8!" << std::endl;
// return false;
// }
// is exactly in the plane
// FIXME: cannot detect that yet ??
// lineSegment.set(SGVec3<T>(-1, 0, 0), SGVec3<T>(1, 0, 0));
// if (!intersects(tri, lineSegment)) {
// std::cout << "Failed test #9!" << std::endl;
// return false;
// }
// is exactly paralell to the plane
// FIXME: cannot detect that yet ??
// lineSegment.set(SGVec3<T>(-1, 1, 0), SGVec3<T>(1, 1, 0));
// if (intersects(tri, lineSegment)) {
// std::cout << "Failed test #10!" << std::endl;
// return false;
// }
// should fail since the line segment poins slightly beyond the triangle
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 1, -0.9));
if (intersects(tri, lineSegment)) {
std::cout << "Failed test #11!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, -0.1, -1));
if (intersects(tri, lineSegment)) {
std::cout << "Failed test #12!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(-0.1, -0.1, -1));
if (intersects(tri, lineSegment)) {
std::cout << "Failed test #13!" << std::endl;
return false;
}
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(-0.1, 0, -1));
if (intersects(tri, lineSegment)) {
std::cout << "Failed test #14!" << std::endl;
return false;
}
return true;
}
template<typename T>
bool
SphereLineIntersectionTest(void)
{
unsigned nTests = 100000;
unsigned failedCount = 0;
for (unsigned i = 0; i < nTests; ++i) {
SGVec3<T> center = rndVec3<T>();
T radius = 2*sg_random();
SGSphere<T> sphere(center, radius);
SGVec3<T> offset = normalize(rndVec3<T>());
T t = 4*sg_random();
// This one is the point we use to judge if the test should fail or not
SGVec3<T> base = center + t*offset;
SGVec3<T> per = perpendicular(offset);
SGVec3<T> start = base + 4*sg_random()*per;
SGVec3<T> end = base - 4*sg_random()*per;
SGLineSegment<T> lineSegment;
lineSegment.set(start, end);
if (intersects(sphere, lineSegment)) {
if (radius < t) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false positive!\nt = " << t << "\n"
<< sphere << "\n" << lineSegment << std::endl;
++failedCount;
}
} else {
if (t <= radius) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false negative!\nt = " << t << "\n"
<< sphere << "\n" << lineSegment << std::endl;
++failedCount;
}
}
SGRay<T> ray;
ray.set(start, end - start);
if (intersects(sphere, ray)) {
if (radius < t) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false positive!\nt = " << t << "\n"
<< sphere << "\n" << ray << std::endl;
++failedCount;
}
} else {
if (t <= radius) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false negative!\nt = " << t << "\n"
<< sphere << "\n" << ray << std::endl;
++failedCount;
}
}
}
if (nTests < 100*failedCount) {
std::cout << "Failed sphere line intersection tests: " << failedCount
<< " tests out of " << nTests
<< " went wrong. Abort!" << std::endl;
return false;
}
failedCount = 0;
for (unsigned i = 0; i < nTests; ++i) {
SGVec3<T> center = rndVec3<T>();
T radius = 2*sg_random();
SGSphere<T> sphere(center, radius);
SGVec3<T> offset = normalize(rndVec3<T>());
T t = 4*sg_random();
// This one is the point we use to judge if the test should fail or not
SGVec3<T> base = center + t*offset;
SGVec3<T> start = base;
SGVec3<T> end = base + 2*sg_random()*offset;
SGLineSegment<T> lineSegment;
lineSegment.set(start, end);
if (intersects(sphere, lineSegment)) {
if (radius < t) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false positive!\nt = " << t << "\n"
<< sphere << "\n" << lineSegment << std::endl;
++failedCount;
}
} else {
if (t <= radius) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false negative!\nt = " << t << "\n"
<< sphere << "\n" << lineSegment << std::endl;
++failedCount;
}
}
SGRay<T> ray;
ray.set(start, end - start);
if (intersects(sphere, ray)) {
if (radius < t) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false positive!\nt = " << t << "\n"
<< sphere << "\n" << ray << std::endl;
++failedCount;
}
} else {
if (t <= radius) {
std::cout << "Failed sphere line intersection test #" << i
<< ": false negative!\nt = " << t << "\n"
<< sphere << "\n" << ray << std::endl;
++failedCount;
}
}
}
if (nTests < 100*failedCount) {
std::cout << "Failed sphere line intersection tests: " << failedCount
<< " tests out of " << nTests
<< " went wrong. Abort!" << std::endl;
return false;
}
return true;
}
template<typename T>
bool
BoxLineIntersectionTest(void)
{
// ok, bad test case coverage, but better than nothing ...
unsigned nTests = 100000;
unsigned failedCount = 0;
for (unsigned i = 0; i < nTests; ++i) {
SGBox<T> box;
box.expandBy(rndVec3<T>());
box.expandBy(rndVec3<T>());
SGVec3<T> center = box.getCenter();
// This one is the point we use to judge if the test should fail or not
SGVec3<T> base = rndVec3<T>();
SGVec3<T> dir = base - center;
SGLineSegment<T> lineSegment;
lineSegment.set(base, base + dir);
if (intersects(box, lineSegment)) {
if (!intersects(box, base)) {
std::cout << "Failed box line intersection test #" << i
<< ": false positive!\n"
<< box << "\n" << lineSegment << std::endl;
++failedCount;
}
} else {
if (intersects(box, base)) {
std::cout << "Failed box line intersection test #" << i
<< ": false negative!\n"
<< box << "\n" << lineSegment << std::endl;
++failedCount;
}
}
SGRay<T> ray;
ray.set(base, dir);
if (intersects(box, ray)) {
if (!intersects(box, base)) {
std::cout << "Failed box line intersection test #" << i
<< ": false positive!\n"
<< box << "\n" << ray << std::endl;
++failedCount;
}
} else {
if (intersects(box, base)) {
std::cout << "Failed box line intersection test #" << i
<< ": false negative!\n"
<< box << "\n" << ray << std::endl;
++failedCount;
}
}
}
if (nTests < 100*failedCount) {
std::cout << "Failed box line intersection tests: " << failedCount
<< " tests out of " << nTests
<< " went wrong. Abort!" << std::endl;
return false;
}
return true;
}
int
main(void)
{
std::cout << "Testing Geometry intersection routines.\n"
<< "Some of these tests can fail due to roundoff problems...\n"
<< "Dont worry if only a few of them fail..." << std::endl;
if (!TriangleLineIntersectionTest<float>())
return EXIT_FAILURE;
if (!TriangleLineIntersectionTest<double>())
return EXIT_FAILURE;
if (!SphereLineIntersectionTest<float>())
return EXIT_FAILURE;
if (!SphereLineIntersectionTest<double>())
return EXIT_FAILURE;
if (!BoxLineIntersectionTest<float>())
return EXIT_FAILURE;
if (!BoxLineIntersectionTest<double>())
return EXIT_FAILURE;
std::cout << "Successfully passed all tests!" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,627 @@
// 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 SGIntersect_HXX
#define SGIntersect_HXX
template<typename T>
inline bool
intersects(const SGBox<T>& box, const SGSphere<T>& sphere)
{
if (sphere.empty())
return false;
// Is more or less trivially included in the next tests
// if (box.empty())
// return false;
if (sphere.getCenter().x() < box.getMin().x() - sphere.getRadius())
return false;
if (sphere.getCenter().y() < box.getMin().y() - sphere.getRadius())
return false;
if (sphere.getCenter().z() < box.getMin().z() - sphere.getRadius())
return false;
if (box.getMax().x() + sphere.getRadius() < sphere.getCenter().x())
return false;
if (box.getMax().y() + sphere.getRadius() < sphere.getCenter().y())
return false;
if (box.getMax().z() + sphere.getRadius() < sphere.getCenter().z())
return false;
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGSphere<T>& sphere, const SGBox<T>& box)
{ return intersects(box, sphere); }
template<typename T>
inline bool
intersects(const SGVec3<T>& v, const SGBox<T>& box)
{
if (v[0] < box.getMin()[0])
return false;
if (box.getMax()[0] < v[0])
return false;
if (v[1] < box.getMin()[1])
return false;
if (box.getMax()[1] < v[1])
return false;
if (v[2] < box.getMin()[2])
return false;
if (box.getMax()[2] < v[2])
return false;
return true;
}
template<typename T>
inline bool
intersects(const SGBox<T>& box, const SGVec3<T>& v)
{ return intersects(v, box); }
template<typename T>
inline bool
intersects(const SGRay<T>& ray, const SGPlane<T>& plane)
{
// We compute the intersection point
// x = origin + \alpha*direction
// from the ray origin and non nomalized direction.
// For 0 <= \alpha the ray intersects the infinite plane.
// The intersection point x can also be written
// x = n*dist + y
// where n is the planes normal, dist is the distance of the plane from
// the origin in normal direction and y is ana aproriate vector
// perpendicular to n.
// Equate the x values and take the scalar product with the plane normal n.
// dot(n, origin) + \alpha*dot(n, direction) = dist
// We can now compute alpha from the above equation.
// \alpha = (dist - dot(n, origin))/dot(n, direction)
// The negative numerator for the \alpha expression
T num = plane.getPositiveDist();
num -= dot(plane.getNormal(), ray.getOrigin());
// If the numerator is zero, we have the rays origin included in the plane
if (fabs(num) <= SGLimits<T>::min())
return true;
// The denominator for the \alpha expression
T den = dot(plane.getNormal(), ray.getDirection());
// If we get here, we already know that the rays origin is not included
// in the plane. Thus if we have a zero denominator we have
// a ray paralell to the plane. That is no intersection.
if (fabs(den) <= SGLimits<T>::min())
return false;
// We would now compute \alpha = num/den and compare with 0 and 1.
// But to avoid that expensive division, check equation multiplied by
// the denominator.
T alphaDen = copysign(1, den)*num;
if (alphaDen < 0)
return false;
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGPlane<T>& plane, const SGRay<T>& ray)
{ return intersects(ray, plane); }
template<typename T>
inline bool
intersects(SGVec3<T>& dst, const SGRay<T>& ray, const SGPlane<T>& plane)
{
// We compute the intersection point
// x = origin + \alpha*direction
// from the ray origin and non nomalized direction.
// For 0 <= \alpha the ray intersects the infinite plane.
// The intersection point x can also be written
// x = n*dist + y
// where n is the planes normal, dist is the distance of the plane from
// the origin in normal direction and y is ana aproriate vector
// perpendicular to n.
// Equate the x values and take the scalar product with the plane normal n.
// dot(n, origin) + \alpha*dot(n, direction) = dist
// We can now compute alpha from the above equation.
// \alpha = (dist - dot(n, origin))/dot(n, direction)
// The negative numerator for the \alpha expression
T num = plane.getPositiveDist();
num -= dot(plane.getNormal(), ray.getOrigin());
// If the numerator is zero, we have the rays origin included in the plane
if (fabs(num) <= SGLimits<T>::min()) {
dst = ray.getOrigin();
return true;
}
// The denominator for the \alpha expression
T den = dot(plane.getNormal(), ray.getDirection());
// If we get here, we already know that the rays origin is not included
// in the plane. Thus if we have a zero denominator we have
// a ray paralell to the plane. That is no intersection.
if (fabs(den) <= SGLimits<T>::min())
return false;
// We would now compute \alpha = num/den and compare with 0 and 1.
// But to avoid that expensive division, check equation multiplied by
// the denominator.
T alpha = num/den;
if (alpha < 0)
return false;
dst = ray.getOrigin() + alpha*ray.getDirection();
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(SGVec3<T>& dst, const SGPlane<T>& plane, const SGRay<T>& ray)
{ return intersects(dst, ray, plane); }
template<typename T>
inline bool
intersects(const SGLineSegment<T>& lineSegment, const SGPlane<T>& plane)
{
// We compute the intersection point
// x = origin + \alpha*direction
// from the line segments origin and non nomalized direction.
// For 0 <= \alpha <= 1 the line segment intersects the infinite plane.
// The intersection point x can also be written
// x = n*dist + y
// where n is the planes normal, dist is the distance of the plane from
// the origin in normal direction and y is ana aproriate vector
// perpendicular to n.
// Equate the x values and take the scalar product with the plane normal n.
// dot(n, origin) + \alpha*dot(n, direction) = dist
// We can now compute alpha from the above equation.
// \alpha = (dist - dot(n, origin))/dot(n, direction)
// The negative numerator for the \alpha expression
T num = plane.getPositiveDist();
num -= dot(plane.getNormal(), lineSegment.getOrigin());
// If the numerator is zero, we have the lines origin included in the plane
if (fabs(num) <= SGLimits<T>::min())
return true;
// The denominator for the \alpha expression
T den = dot(plane.getNormal(), lineSegment.getDirection());
// If we get here, we already know that the lines origin is not included
// in the plane. Thus if we have a zero denominator we have
// a line paralell to the plane. That is no intersection.
if (fabs(den) <= SGLimits<T>::min())
return false;
// We would now compute \alpha = num/den and compare with 0 and 1.
// But to avoid that expensive division, compare equations
// multiplied by |den|. Note that copysign is usually a compiler intrinsic
// that expands in assembler code that not even stalls the cpus pipes.
T alphaDen = copysign(1, den)*num;
if (alphaDen < 0)
return false;
if (den < alphaDen)
return false;
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGPlane<T>& plane, const SGLineSegment<T>& lineSegment)
{ return intersects(lineSegment, plane); }
template<typename T>
inline bool
intersects(SGVec3<T>& dst, const SGLineSegment<T>& lineSegment, const SGPlane<T>& plane)
{
// We compute the intersection point
// x = origin + \alpha*direction
// from the line segments origin and non nomalized direction.
// For 0 <= \alpha <= 1 the line segment intersects the infinite plane.
// The intersection point x can also be written
// x = n*dist + y
// where n is the planes normal, dist is the distance of the plane from
// the origin in normal direction and y is an aproriate vector
// perpendicular to n.
// Equate the x values and take the scalar product with the plane normal n.
// dot(n, origin) + \alpha*dot(n, direction) = dist
// We can now compute alpha from the above equation.
// \alpha = (dist - dot(n, origin))/dot(n, direction)
// The negative numerator for the \alpha expression
T num = plane.getPositiveDist();
num -= dot(plane.getNormal(), lineSegment.getOrigin());
// If the numerator is zero, we have the lines origin included in the plane
if (fabs(num) <= SGLimits<T>::min()) {
dst = lineSegment.getOrigin();
return true;
}
// The denominator for the \alpha expression
T den = dot(plane.getNormal(), lineSegment.getDirection());
// If we get here, we already know that the lines origin is not included
// in the plane. Thus if we have a zero denominator we have
// a line paralell to the plane. That is: no intersection.
if (fabs(den) <= SGLimits<T>::min())
return false;
// We would now compute \alpha = num/den and compare with 0 and 1.
// But to avoid that expensive division, check equation multiplied by
// the denominator. FIXME: shall we do so? or compute like that?
T alpha = num/den;
if (alpha < 0)
return false;
if (1 < alpha)
return false;
dst = lineSegment.getOrigin() + alpha*lineSegment.getDirection();
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(SGVec3<T>& dst, const SGPlane<T>& plane, const SGLineSegment<T>& lineSegment)
{ return intersects(dst, lineSegment, plane); }
// Distance of a line segment to a point
template<typename T>
inline T
distSqr(const SGLineSegment<T>& lineSeg, const SGVec3<T>& p)
{
SGVec3<T> ps = p - lineSeg.getStart();
T psdotdir = dot(ps, lineSeg.getDirection());
if (psdotdir <= 0)
return dot(ps, ps);
SGVec3<T> pe = p - lineSeg.getEnd();
if (0 <= dot(pe, lineSeg.getDirection()))
return dot(pe, pe);
return dot(ps, ps) - psdotdir*psdotdir/dot(lineSeg.getDirection(), lineSeg.getDirection());
}
// make it symmetric
template<typename T>
inline T
distSqr(const SGVec3<T>& p, const SGLineSegment<T>& lineSeg)
{ return distSqr(lineSeg, p); }
// with sqrt
template<typename T>
inline T
dist(const SGVec3<T>& p, const SGLineSegment<T>& lineSeg)
{ return sqrt(distSqr(lineSeg, p)); }
template<typename T>
inline T
dist(const SGLineSegment<T>& lineSeg, const SGVec3<T>& p)
{ return sqrt(distSqr(lineSeg, p)); }
template<typename T>
inline bool
intersects(const SGRay<T>& ray, const SGSphere<T>& sphere)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering,
// second edition, page 571
SGVec3<T> l = sphere.getCenter() - ray.getOrigin();
T s = dot(l, ray.getDirection());
T l2 = dot(l, l);
T r2 = sphere.getRadius2();
if (s < 0 && l2 > r2)
return false;
T d2 = dot(ray.getDirection(), ray.getDirection());
// The original test would read
// T m2 = l2 - s*s/d2;
// if (m2 > r2)
// return false;
// but to avoid the expensive division, we multiply by d2
T m2 = d2*l2 - s*s;
if (m2 > d2*r2)
return false;
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGSphere<T>& sphere, const SGRay<T>& ray)
{ return intersects(ray, sphere); }
template<typename T>
inline bool
intersects(const SGLineSegment<T>& lineSegment, const SGSphere<T>& sphere)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering,
// second edition, page 571
SGVec3<T> l = sphere.getCenter() - lineSegment.getStart();
T ld = length(lineSegment.getDirection());
T s = dot(l, lineSegment.getDirection())/ld;
T l2 = dot(l, l);
T r2 = sphere.getRadius2();
if (s < 0 && l2 > r2)
return false;
T m2 = l2 - s*s;
if (m2 > r2)
return false;
T q = sqrt(r2 - m2);
T t = s - q;
if (ld < t)
return false;
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGSphere<T>& sphere, const SGLineSegment<T>& lineSegment)
{ return intersects(lineSegment, sphere); }
template<typename T>
inline bool
// FIXME do not use that default argument later. Just for development now
intersects(SGVec3<T>& x, const SGTriangle<T>& tri, const SGRay<T>& ray, T eps = 0)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
// Method based on the observation that we are looking for a
// point x that can be expressed in terms of the triangle points
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
// with 0 <= u, v and u + v <= 1.
// OTOH it could be expressed in terms of the ray
// x = o + t*d
// Now we can compute u, v and t.
SGVec3<T> p = cross(ray.getDirection(), tri.getEdge(1));
T denom = dot(p, tri.getEdge(0));
T signDenom = copysign(1, denom);
SGVec3<T> s = ray.getOrigin() - tri.getBaseVertex();
SGVec3<T> q = cross(s, tri.getEdge(0));
// Now t would read
// t = 1/denom*dot(q, tri.getEdge(1));
// To avoid an expensive division we multiply by |denom|
T tDenom = signDenom*dot(q, tri.getEdge(1));
if (tDenom < 0)
return false;
// For line segment we would test against
// if (1 < t)
// return false;
// with the original t. The multiplied test would read
// if (absDenom < tDenom)
// return false;
T absDenom = fabs(denom);
T absDenomEps = absDenom*eps;
// T u = 1/denom*dot(p, s);
T u = signDenom*dot(p, s);
if (u < -absDenomEps)
return false;
// T v = 1/denom*dot(q, d);
// if (v < -eps)
// return false;
T v = signDenom*dot(q, ray.getDirection());
if (v < -absDenomEps)
return false;
if (u + v > absDenom + absDenomEps)
return false;
// return if paralell ??? FIXME what if paralell and in plane?
// may be we are ok below than anyway??
if (absDenom <= SGLimits<T>::min())
return false;
x = ray.getOrigin();
// if we have survived here it could only happen with denom == 0
// that the point is already in plane. Then return the origin ...
if (SGLimitsd::min() < absDenom)
x += (tDenom/absDenom)*ray.getDirection();
return true;
}
template<typename T>
inline bool
intersects(const SGTriangle<T>& tri, const SGRay<T>& ray, T eps = 0)
{
// FIXME: for now just wrap the other method. When that has prooven
// well optimized, implement that special case
SGVec3<T> dummy;
return intersects(dummy, tri, ray, eps);
}
template<typename T>
inline bool
// FIXME do not use that default argument later. Just for development now
intersects(SGVec3<T>& x, const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
// Method based on the observation that we are looking for a
// point x that can be expressed in terms of the triangle points
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
// with 0 <= u, v and u + v <= 1.
// OTOH it could be expressed in terms of the lineSegment
// x = o + t*d
// Now we can compute u, v and t.
SGVec3<T> p = cross(lineSegment.getDirection(), tri.getEdge(1));
T denom = dot(p, tri.getEdge(0));
T signDenom = copysign(1, denom);
SGVec3<T> s = lineSegment.getStart() - tri.getBaseVertex();
SGVec3<T> q = cross(s, tri.getEdge(0));
// Now t would read
// t = 1/denom*dot(q, tri.getEdge(1));
// To avoid an expensive division we multiply by |denom|
T tDenom = signDenom*dot(q, tri.getEdge(1));
if (tDenom < 0)
return false;
// For line segment we would test against
// if (1 < t)
// return false;
// with the original t. The multiplied test reads
T absDenom = fabs(denom);
if (absDenom < tDenom)
return false;
// take the CPU accuracy in account
T absDenomEps = absDenom*eps;
// T u = 1/denom*dot(p, s);
T u = signDenom*dot(p, s);
if (u < -absDenomEps)
return false;
// T v = 1/denom*dot(q, d);
// if (v < -eps)
// return false;
T v = signDenom*dot(q, lineSegment.getDirection());
if (v < -absDenomEps)
return false;
if (u + v > absDenom + absDenomEps)
return false;
// return if paralell ??? FIXME what if paralell and in plane?
// may be we are ok below than anyway??
if (absDenom <= SGLimits<T>::min())
return false;
x = lineSegment.getStart();
// if we have survived here it could only happen with denom == 0
// that the point is already in plane. Then return the origin ...
if (SGLimitsd::min() < absDenom)
x += (tDenom/absDenom)*lineSegment.getDirection();
return true;
}
template<typename T>
inline bool
intersects(const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0)
{
// FIXME: for now just wrap the othr method. When that has prooven
// well optimized, implement that special case
SGVec3<T> dummy;
return intersects(dummy, tri, lineSegment, eps);
}
template<typename T>
inline bool
intersects(const SGVec3<T>& v, const SGSphere<T>& sphere)
{
if (sphere.empty())
return false;
return distSqr(v, sphere.getCenter()) <= sphere.getRadius2();
}
template<typename T>
inline bool
intersects(const SGSphere<T>& sphere, const SGVec3<T>& v)
{ return intersects(v, sphere); }
template<typename T>
inline bool
intersects(const SGBox<T>& box, const SGLineSegment<T>& lineSegment)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
SGVec3<T> c = lineSegment.getCenter() - box.getCenter();
SGVec3<T> w = 0.5*lineSegment.getDirection();
SGVec3<T> v(fabs(w.x()), fabs(w.y()), fabs(w.z()));
SGVec3<T> h = 0.5*box.getSize();
if (fabs(c[0]) > v[0] + h[0])
return false;
if (fabs(c[1]) > v[1] + h[1])
return false;
if (fabs(c[2]) > v[2] + h[2])
return false;
if (fabs(c[1]*w[2] - c[2]*w[1]) > h[1]*v[2] + h[2]*v[1])
return false;
if (fabs(c[0]*w[2] - c[2]*w[0]) > h[0]*v[2] + h[2]*v[0])
return false;
if (fabs(c[0]*w[1] - c[1]*w[0]) > h[0]*v[1] + h[1]*v[0])
return false;
return true;
}
template<typename T>
inline bool
intersects(const SGLineSegment<T>& lineSegment, const SGBox<T>& box)
{ return intersects(box, lineSegment); }
template<typename T>
inline bool
intersects(const SGBox<T>& box, const SGRay<T>& ray)
{
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
for (unsigned i = 0; i < 3; ++i) {
T cMin = box.getMin()[i];
T cMax = box.getMax()[i];
T cOrigin = ray.getOrigin()[i];
T cDir = ray.getDirection()[i];
if (fabs(cDir) <= SGLimits<T>::min()) {
if (cOrigin < cMin)
return false;
if (cMax < cOrigin)
return false;
}
T nearr = - SGLimits<T>::max();
T farr = SGLimits<T>::max();
T T1 = (cMin - cOrigin) / cDir;
T T2 = (cMax - cOrigin) / cDir;
if (T1 > T2) std::swap (T1, T2);/* since T1 intersection with near plane */
if (T1 > nearr) nearr = T1; /* want largest Tnear */
if (T2 < farr) farr = T2; /* want smallest Tfarr */
if (nearr > farr) // farr box is missed
return false;
if (farr < 0) // box is behind ray
return false;
}
return true;
}
// make it symmetric
template<typename T>
inline bool
intersects(const SGRay<T>& ray, const SGBox<T>& box)
{ return intersects(box, ray); }
#endif

29
simgear/math/SGLimits.hxx Normal file
View File

@@ -0,0 +1,29 @@
// 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 SGLimits_H
#define SGLimits_H
#include <limits>
/// Helper class for epsilon and so on
/// This is the possible place to hook in for machines not
/// providing numeric_limits ...
template<typename T>
class SGLimits : public std::numeric_limits<T> {};
#endif

View File

@@ -0,0 +1,62 @@
// 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 SGLineSegment_H
#define SGLineSegment_H
template<typename T>
class SGLineSegment {
public:
SGLineSegment()
{ }
SGLineSegment(const SGVec3<T>& start, const SGVec3<T>& end) :
_start(start),
_direction(end - start)
{ }
void set(const SGVec3<T>& start, const SGVec3<T>& end)
{ _start = start; _direction = end - start; }
const SGVec3<T>& getStart() const
{ return _start; }
SGVec3<T> getEnd() const
{ return _start + _direction; }
const SGVec3<T>& getDirection() const
{ return _direction; }
SGVec3<T> getNormalizedDirection() const
{ return normalize(getDirection()); }
SGVec3<T> getCenter() const
{ return _start + T(0.5)*_direction; }
private:
SGVec3<T> _start;
SGVec3<T> _direction;
};
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s,
const SGLineSegment<T>& lineSegment)
{
return s << "line segment: start = " << lineSegment.getStart()
<< ", end = " << lineSegment.getEnd();
}
#endif

44
simgear/math/SGMath.hxx Normal file
View File

@@ -0,0 +1,44 @@
// 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 SGMath_H
#define SGMath_H
/// Just include them all
#include <iosfwd>
// FIXME, make it compile on IRIX
#include <osg/GL>
#undef GLUT_APIENTRY_DEFINED // GL/glut.h undef APIENTRY when this symbol is defined. osg/GL defines it (?).
// This probably would work if we didn't use plib/pu.h that include GL/glut.h
// on its side.
#include "SGMathFwd.hxx"
#include "SGCMath.hxx"
#include "SGLimits.hxx"
#include "SGMisc.hxx"
#include "SGGeodesy.hxx"
#include "SGVec2.hxx"
#include "SGVec3.hxx"
#include "SGVec4.hxx"
#include "SGGeoc.hxx"
#include "SGGeod.hxx"
#include "SGQuat.hxx"
#include "SGMatrix.hxx"
#endif

View File

@@ -0,0 +1,56 @@
// 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 SGVec2;
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 SGVec2<float> SGVec2f;
typedef SGVec2<double> SGVec2d;
typedef SGVec3<float> SGVec3f;
typedef SGVec3<double> SGVec3d;
typedef SGVec4<float> SGVec4f;
typedef SGVec4<double> SGVec4d;
#endif

366
simgear/math/SGMathTest.cxx Normal file
View File

@@ -0,0 +1,366 @@
// 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.
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <cstdlib>
#include <iostream>
#include <plib/sg.h>
#include "SGMath.hxx"
template<typename T>
bool
Vec3Test(void)
{
SGVec3<T> v1, v2, v3;
// Check if the equivalent function works
v1 = SGVec3<T>(1, 2, 3);
v2 = SGVec3<T>(3, 2, 1);
if (equivalent(v1, v2))
return false;
// Check the unary minus operator
v3 = SGVec3<T>(-1, -2, -3);
if (!equivalent(-v1, v3))
return false;
// Check the unary plus operator
v3 = SGVec3<T>(1, 2, 3);
if (!equivalent(+v1, v3))
return false;
// Check the addition operator
v3 = SGVec3<T>(4, 4, 4);
if (!equivalent(v1 + v2, v3))
return false;
// Check the subtraction operator
v3 = SGVec3<T>(-2, 0, 2);
if (!equivalent(v1 - v2, v3))
return false;
// Check the scaler multiplication operator
v3 = SGVec3<T>(2, 4, 6);
if (!equivalent(2*v1, v3))
return false;
// Check the dot product
if (fabs(dot(v1, v2) - 10) > 10*SGLimits<T>::epsilon())
return false;
// Check the cross product
v3 = SGVec3<T>(-4, 8, -4);
if (!equivalent(cross(v1, v2), v3))
return false;
// Check the euclidean length
if (fabs(14 - length(v1)*length(v1)) > 14*SGLimits<T>::epsilon())
return false;
return true;
}
template<typename T>
bool
QuatTest(void)
{
const SGVec3<T> e1(1, 0, 0);
const SGVec3<T> e2(0, 1, 0);
const SGVec3<T> e3(0, 0, 1);
SGVec3<T> v1, v2;
SGQuat<T> q1, q2, q3, q4;
// Check a rotation around the x axis
q1 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), e1);
v1 = SGVec3<T>(1, 2, 3);
v2 = SGVec3<T>(1, -2, -3);
if (!equivalent(q1.transform(v1), v2))
return false;
// Check a rotation around the x axis
q1 = SGQuat<T>::fromAngleAxis(0.5*SGMisc<T>::pi(), e1);
v2 = SGVec3<T>(1, 3, -2);
if (!equivalent(q1.transform(v1), v2))
return false;
// Check a rotation around the y axis
q1 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), e2);
v2 = SGVec3<T>(-1, 2, -3);
if (!equivalent(q1.transform(v1), v2))
return false;
// Check a rotation around the y axis
q1 = SGQuat<T>::fromAngleAxis(0.5*SGMisc<T>::pi(), e2);
v2 = SGVec3<T>(-3, 2, 1);
if (!equivalent(q1.transform(v1), v2))
return false;
// Check a rotation around the z axis
q1 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), e3);
v2 = SGVec3<T>(-1, -2, 3);
if (!equivalent(q1.transform(v1), v2))
return false;
// Check a rotation around the z axis
q1 = SGQuat<T>::fromAngleAxis(0.5*SGMisc<T>::pi(), e3);
v2 = SGVec3<T>(2, -1, 3);
if (!equivalent(q1.transform(v1), v2))
return false;
// Now check some successive transforms
// We can reuse the prevously tested stuff
q1 = SGQuat<T>::fromAngleAxis(0.5*SGMisc<T>::pi(), e1);
q2 = SGQuat<T>::fromAngleAxis(0.5*SGMisc<T>::pi(), e2);
q3 = q1*q2;
v2 = q2.transform(q1.transform(v1));
if (!equivalent(q3.transform(v1), v2))
return false;
/// Test from Euler angles
float x = 0.2*SGMisc<T>::pi();
float y = 0.3*SGMisc<T>::pi();
float z = 0.4*SGMisc<T>::pi();
q1 = SGQuat<T>::fromAngleAxis(z, e3);
q2 = SGQuat<T>::fromAngleAxis(y, e2);
q3 = SGQuat<T>::fromAngleAxis(x, e1);
v2 = q3.transform(q2.transform(q1.transform(v1)));
q4 = SGQuat<T>::fromEulerRad(z, y, x);
if (!equivalent(q4.transform(v1), v2))
return false;
/// Test angle axis forward and back transform
q1 = SGQuat<T>::fromAngleAxis(0.2*SGMisc<T>::pi(), e1);
q2 = SGQuat<T>::fromAngleAxis(0.7*SGMisc<T>::pi(), e2);
q3 = q1*q2;
SGVec3<T> angleAxis;
q1.getAngleAxis(angleAxis);
q4 = SGQuat<T>::fromAngleAxis(angleAxis);
if (!equivalent(q1, q4))
return false;
q2.getAngleAxis(angleAxis);
q4 = SGQuat<T>::fromAngleAxis(angleAxis);
if (!equivalent(q2, q4))
return false;
q3.getAngleAxis(angleAxis);
q4 = SGQuat<T>::fromAngleAxis(angleAxis);
if (!equivalent(q3, q4))
return false;
return true;
}
template<typename T>
bool
MatrixTest(void)
{
// Create some test matrix
SGVec3<T> v0(2, 7, 17);
SGQuat<T> q0 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), normalize(v0));
SGMatrix<T> m0;
m0.postMultTranslate(v0);
m0.postMultRotate(q0);
// Check the tqo forms of the inverse for that kind of special matrix
SGMatrix<T> m1, m2;
invert(m1, m0);
m2 = transNeg(m0);
if (!equivalent(m1, m2))
return false;
// Check matrix multiplication and inversion
if (!equivalent(m0*m1, SGMatrix<T>::unit()))
return false;
if (!equivalent(m1*m0, SGMatrix<T>::unit()))
return false;
if (!equivalent(m0*m2, SGMatrix<T>::unit()))
return false;
if (!equivalent(m2*m0, SGMatrix<T>::unit()))
return false;
return true;
}
bool
GeodesyTest(void)
{
// We know that the values are on the order of 1
double epsDeg = 10*SGLimits<double>::epsilon();
// For the altitude values we need to tolerate relative errors in the order
// of the radius
double epsM = 1e6*SGLimits<double>::epsilon();
SGVec3<double> cart0, cart1;
SGGeod geod0, geod1;
SGGeoc geoc0;
// create some geodetic position
geod0 = SGGeod::fromDegM(30, 20, 17);
// Test the conversion routines to cartesian coordinates
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 = SGGeoc::fromCart(cart0);
cart1 = SGVec3<double>::fromGeoc(geoc0);
if (!equivalent(cart0, cart1))
return false;
return true;
}
bool
sgInterfaceTest(void)
{
SGVec3f v3f = SGVec3f::e2();
SGVec4f v4f = SGVec4f::e2();
SGQuatf qf = SGQuatf::fromEulerRad(1.2, 1.3, -0.4);
SGMatrixf mf;
mf.postMultTranslate(v3f);
mf.postMultRotate(qf);
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGVec3f tv3f;
sgVec3 sv3f;
sgCopyVec3(sv3f, v3f.sg());
sgCopyVec3(tv3f.sg(), sv3f);
if (tv3f != v3f)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGVec4f tv4f;
sgVec4 sv4f;
sgCopyVec4(sv4f, v4f.sg());
sgCopyVec4(tv4f.sg(), sv4f);
if (tv4f != v4f)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGQuatf tqf;
sgQuat sqf;
sgCopyQuat(sqf, qf.sg());
sgCopyQuat(tqf.sg(), sqf);
if (tqf != qf)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGMatrixf tmf;
sgMat4 smf;
sgCopyMat4(smf, mf.sg());
sgCopyMat4(tmf.sg(), smf);
if (tmf != mf)
return false;
return true;
}
bool
sgdInterfaceTest(void)
{
SGVec3d v3d = SGVec3d::e2();
SGVec4d v4d = SGVec4d::e2();
SGQuatd qd = SGQuatd::fromEulerRad(1.2, 1.3, -0.4);
SGMatrixd md;
md.postMultTranslate(v3d);
md.postMultRotate(qd);
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGVec3d tv3d;
sgdVec3 sv3d;
sgdCopyVec3(sv3d, v3d.sg());
sgdCopyVec3(tv3d.sg(), sv3d);
if (tv3d != v3d)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGVec4d tv4d;
sgdVec4 sv4d;
sgdCopyVec4(sv4d, v4d.sg());
sgdCopyVec4(tv4d.sg(), sv4d);
if (tv4d != v4d)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGQuatd tqd;
sgdQuat sqd;
sgdCopyQuat(sqd, qd.sg());
sgdCopyQuat(tqd.sg(), sqd);
if (tqd != qd)
return false;
// Copy to and from plibs types check if result is equal,
// test for exact equality
SGMatrixd tmd;
sgdMat4 smd;
sgdCopyMat4(smd, md.sg());
sgdCopyMat4(tmd.sg(), smd);
if (tmd != md)
return false;
return true;
}
int
main(void)
{
// Do vector tests
if (!Vec3Test<float>())
return EXIT_FAILURE;
if (!Vec3Test<double>())
return EXIT_FAILURE;
// Do quaternion tests
if (!QuatTest<float>())
return EXIT_FAILURE;
if (!QuatTest<double>())
return EXIT_FAILURE;
// Do matrix tests
if (!MatrixTest<float>())
return EXIT_FAILURE;
if (!MatrixTest<double>())
return EXIT_FAILURE;
// Check geodetic/geocentric/cartesian conversions
if (!GeodesyTest())
return EXIT_FAILURE;
// Check interaction with sg*/sgd*
if (!sgInterfaceTest())
return EXIT_FAILURE;
if (!sgdInterfaceTest())
return EXIT_FAILURE;
std::cout << "Successfully passed all tests!" << std::endl;
return EXIT_SUCCESS;
}

612
simgear/math/SGMatrix.hxx Normal file
View File

@@ -0,0 +1,612 @@
// 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 SGMatrix_H
#define SGMatrix_H
/// Expression templates for poor programmers ... :)
template<typename T>
struct TransNegRef;
/// 3D Matrix Class
template<typename T>
class SGMatrix {
public:
enum { nCols = 4, nRows = 4, nEnts = 16 };
typedef T value_type;
/// Default constructor. Does not initialize at all.
/// If you need them zero initialized, use SGMatrix::zeros()
SGMatrix(void)
{
/// Initialize with nans in the debug build, that will guarantee to have
/// a fast uninitialized default constructor in the release but shows up
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < nEnts; ++i)
_data.flat[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 16 elements
explicit SGMatrix(const T* data)
{ for (unsigned i = 0; i < nEnts; ++i) _data.flat[i] = data[i]; }
/// Constructor, build up a SGMatrix from given elements
SGMatrix(T m00, T m01, T m02, T m03,
T m10, T m11, T m12, T m13,
T m20, T m21, T m22, T m23,
T m30, T m31, T m32, T m33)
{
_data.flat[0] = m00; _data.flat[1] = m10;
_data.flat[2] = m20; _data.flat[3] = m30;
_data.flat[4] = m01; _data.flat[5] = m11;
_data.flat[6] = m21; _data.flat[7] = m31;
_data.flat[8] = m02; _data.flat[9] = m12;
_data.flat[10] = m22; _data.flat[11] = m32;
_data.flat[12] = m03; _data.flat[13] = m13;
_data.flat[14] = m23; _data.flat[15] = m33;
}
/// Constructor, build up a SGMatrix from a translation
template<typename S>
SGMatrix(const SGVec3<S>& trans)
{ set(trans); }
/// Constructor, build up a SGMatrix from a rotation and a translation
template<typename S>
SGMatrix(const SGQuat<S>& quat)
{ set(quat); }
/// Copy constructor for a transposed negated matrix
SGMatrix(const TransNegRef<T>& tm)
{ set(tm); }
/// Set from a tranlation
template<typename S>
void set(const SGVec3<S>& trans)
{
_data.flat[0] = 1; _data.flat[4] = 0;
_data.flat[8] = 0; _data.flat[12] = T(trans(0));
_data.flat[1] = 0; _data.flat[5] = 1;
_data.flat[9] = 0; _data.flat[13] = T(trans(1));
_data.flat[2] = 0; _data.flat[6] = 0;
_data.flat[10] = 1; _data.flat[14] = T(trans(2));
_data.flat[3] = 0; _data.flat[7] = 0;
_data.flat[11] = 0; _data.flat[15] = 1;
}
/// Set from a scale/rotation and tranlation
template<typename S>
void set(const SGQuat<S>& quat)
{
T w = quat.w(); T x = quat.x(); T y = quat.y(); T z = quat.z();
T xx = x*x; T yy = y*y; T zz = z*z;
T wx = w*x; T wy = w*y; T wz = w*z;
T xy = x*y; T xz = x*z; T yz = y*z;
_data.flat[0] = 1-2*(yy+zz); _data.flat[1] = 2*(xy-wz);
_data.flat[2] = 2*(xz+wy); _data.flat[3] = 0;
_data.flat[4] = 2*(xy+wz); _data.flat[5] = 1-2*(xx+zz);
_data.flat[6] = 2*(yz-wx); _data.flat[7] = 0;
_data.flat[8] = 2*(xz-wy); _data.flat[9] = 2*(yz+wx);
_data.flat[10] = 1-2*(xx+yy); _data.flat[11] = 0;
_data.flat[12] = 0; _data.flat[13] = 0;
_data.flat[14] = 0; _data.flat[15] = 1;
}
/// set from a transposed negated matrix
void set(const TransNegRef<T>& tm)
{
const SGMatrix& m = tm.m;
_data.flat[0] = m(0,0);
_data.flat[1] = m(0,1);
_data.flat[2] = m(0,2);
_data.flat[3] = m(3,0);
_data.flat[4] = m(1,0);
_data.flat[5] = m(1,1);
_data.flat[6] = m(1,2);
_data.flat[7] = m(3,1);
_data.flat[8] = m(2,0);
_data.flat[9] = m(2,1);
_data.flat[10] = m(2,2);
_data.flat[11] = m(3,2);
// Well, this one is ugly here, as that xform method on the current
// object needs the above data to be already set ...
SGVec3<T> t = xformVec(SGVec3<T>(m(0,3), m(1,3), m(2,3)));
_data.flat[12] = -t(0);
_data.flat[13] = -t(1);
_data.flat[14] = -t(2);
_data.flat[15] = m(3,3);
}
/// Access by index, the index is unchecked
const T& operator()(unsigned i, unsigned j) const
{ return _data.flat[i + 4*j]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i, unsigned j)
{ return _data.flat[i + 4*j]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return _data.flat[i]; }
/// Access by index, the index is unchecked
T& operator[](unsigned i)
{ return _data.flat[i]; }
/// Get the data pointer
const T* data(void) const
{ return _data.flat; }
/// Get the data pointer
T* data(void)
{ return _data.flat; }
/// Readonly interface function to ssg's sgMat4/sgdMat4
const T (&sg(void) const)[4][4]
{ return _data.carray; }
/// Interface function to ssg's sgMat4/sgdMat4
T (&sg(void))[4][4]
{ return _data.carray; }
/// Inplace addition
SGMatrix& operator+=(const SGMatrix& m)
{ for (unsigned i = 0; i < nEnts; ++i) _data.flat[i] += m._data.flat[i]; return *this; }
/// Inplace subtraction
SGMatrix& operator-=(const SGMatrix& m)
{ for (unsigned i = 0; i < nEnts; ++i) _data.flat[i] -= m._data.flat[i]; return *this; }
/// Inplace scalar multiplication
template<typename S>
SGMatrix& operator*=(S s)
{ for (unsigned i = 0; i < nEnts; ++i) _data.flat[i] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGMatrix& operator/=(S s)
{ return operator*=(1/T(s)); }
/// Inplace matrix multiplication, post multiply
SGMatrix& operator*=(const SGMatrix<T>& m2);
template<typename S>
SGMatrix& preMultTranslate(const SGVec3<S>& t)
{
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i)
(*this)(i,3) += T(t(i));
return *this;
}
template<typename S>
SGMatrix& postMultTranslate(const SGVec3<S>& t)
{
SGVec4<T> col3((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3));
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i) {
SGVec4<T> tmp((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3));
col3 += T(t(i))*tmp;
}
(*this)(0,3) = col3(0); (*this)(1,3) = col3(1);
(*this)(2,3) = col3(2); (*this)(3,3) = col3(3);
return *this;
}
SGMatrix& preMultRotate(const SGQuat<T>& r)
{
for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
SGVec3<T> col((*this)(0,i), (*this)(1,i), (*this)(2,i));
col = r.transform(col);
(*this)(0,i) = col(0); (*this)(1,i) = col(1); (*this)(2,i) = col(2);
}
return *this;
}
SGMatrix& postMultRotate(const SGQuat<T>& r)
{
for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
SGVec3<T> col((*this)(i,0), (*this)(i,1), (*this)(i,2));
col = r.backTransform(col);
(*this)(i,0) = col(0); (*this)(i,1) = col(1); (*this)(i,2) = col(2);
}
return *this;
}
SGVec3<T> xformPt(const SGVec3<T>& pt) const
{
SGVec3<T> tpt;
tpt(0) = (*this)(0,3);
tpt(1) = (*this)(1,3);
tpt(2) = (*this)(2,3);
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i) {
T tmp = pt(i);
tpt(0) += tmp*(*this)(0,i);
tpt(1) += tmp*(*this)(1,i);
tpt(2) += tmp*(*this)(2,i);
}
return tpt;
}
SGVec3<T> xformVec(const SGVec3<T>& v) const
{
SGVec3<T> tv;
T tmp = v(0);
tv(0) = tmp*(*this)(0,0);
tv(1) = tmp*(*this)(1,0);
tv(2) = tmp*(*this)(2,0);
for (unsigned i = 1; i < SGMatrix<T>::nCols-1; ++i) {
T tmp = v(i);
tv(0) += tmp*(*this)(0,i);
tv(1) += tmp*(*this)(1,i);
tv(2) += tmp*(*this)(2,i);
}
return tv;
}
/// Return an all zero matrix
static SGMatrix zeros(void)
{ return SGMatrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); }
/// Return a unit matrix
static SGMatrix unit(void)
{ return SGMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
private:
/// Required to make that alias safe.
union Data {
T flat[16];
T carray[4][4];
};
/// The actual data, the matrix is stored in column major order,
/// that matches the storage format of OpenGL
Data _data;
};
/// Class to distinguish between a matrix and the matrix with a transposed
/// rotational part and a negated translational part
template<typename T>
struct TransNegRef {
TransNegRef(const SGMatrix<T>& _m) : m(_m) {}
const SGMatrix<T>& m;
};
/// Unary +, do nothing ...
template<typename T>
inline
const SGMatrix<T>&
operator+(const SGMatrix<T>& m)
{ return m; }
/// Unary -, do nearly nothing
template<typename T>
inline
SGMatrix<T>
operator-(const SGMatrix<T>& m)
{
SGMatrix<T> ret;
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
ret[i] = -m[i];
return ret;
}
/// Binary +
template<typename T>
inline
SGMatrix<T>
operator+(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{
SGMatrix<T> ret;
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
ret[i] = m1[i] + m2[i];
return ret;
}
/// Binary -
template<typename T>
inline
SGMatrix<T>
operator-(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{
SGMatrix<T> ret;
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
ret[i] = m1[i] - m2[i];
return ret;
}
/// Scalar multiplication
template<typename S, typename T>
inline
SGMatrix<T>
operator*(S s, const SGMatrix<T>& m)
{
SGMatrix<T> ret;
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
ret[i] = s*m[i];
return ret;
}
/// Scalar multiplication
template<typename S, typename T>
inline
SGMatrix<T>
operator*(const SGMatrix<T>& m, S s)
{
SGMatrix<T> ret;
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
ret[i] = s*m[i];
return ret;
}
/// Vector multiplication
template<typename T>
inline
SGVec4<T>
operator*(const SGMatrix<T>& m, const SGVec4<T>& v)
{
SGVec4<T> mv;
T tmp = v(0);
mv(0) = tmp*m(0,0);
mv(1) = tmp*m(1,0);
mv(2) = tmp*m(2,0);
mv(3) = tmp*m(3,0);
for (unsigned i = 1; i < SGMatrix<T>::nCols; ++i) {
T tmp = v(i);
mv(0) += tmp*m(0,i);
mv(1) += tmp*m(1,i);
mv(2) += tmp*m(2,i);
mv(3) += tmp*m(3,i);
}
return mv;
}
/// Vector multiplication
template<typename T>
inline
SGVec4<T>
operator*(const TransNegRef<T>& tm, const SGVec4<T>& v)
{
const SGMatrix<T>& m = tm.m;
SGVec4<T> mv;
SGVec3<T> v2;
T tmp = v(3);
mv(0) = v2(0) = -tmp*m(0,3);
mv(1) = v2(1) = -tmp*m(1,3);
mv(2) = v2(2) = -tmp*m(2,3);
mv(3) = tmp*m(3,3);
for (unsigned i = 0; i < SGMatrix<T>::nCols - 1; ++i) {
T tmp = v(i) + v2(i);
mv(0) += tmp*m(i,0);
mv(1) += tmp*m(i,1);
mv(2) += tmp*m(i,2);
mv(3) += tmp*m(3,i);
}
return mv;
}
/// Matrix multiplication
template<typename T>
inline
SGMatrix<T>
operator*(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{
SGMatrix<T> m;
for (unsigned j = 0; j < SGMatrix<T>::nCols; ++j) {
T tmp = m2(0,j);
m(0,j) = tmp*m1(0,0);
m(1,j) = tmp*m1(1,0);
m(2,j) = tmp*m1(2,0);
m(3,j) = tmp*m1(3,0);
for (unsigned i = 1; i < SGMatrix<T>::nCols; ++i) {
T tmp = m2(i,j);
m(0,j) += tmp*m1(0,i);
m(1,j) += tmp*m1(1,i);
m(2,j) += tmp*m1(2,i);
m(3,j) += tmp*m1(3,i);
}
}
return m;
}
/// Inplace matrix multiplication, post multiply
template<typename T>
inline
SGMatrix<T>&
SGMatrix<T>::operator*=(const SGMatrix<T>& m2)
{ (*this) = operator*(*this, m2); return *this; }
/// Return a reference to the matrix typed to make sure we use the transposed
/// negated matrix
template<typename T>
inline
TransNegRef<T>
transNeg(const SGMatrix<T>& m)
{ return TransNegRef<T>(m); }
/// Compute the inverse if the matrix src. Store the result in dst.
/// Return if the matrix is nonsingular. If it is singular dst contains
/// undefined values
template<typename T>
inline
bool
invert(SGMatrix<T>& dst, const SGMatrix<T>& src)
{
// Do a LU decomposition with row pivoting and solve into dst
SGMatrix<T> tmp = src;
dst = SGMatrix<T>::unit();
for (unsigned i = 0; i < 4; ++i) {
T val = tmp(i,i);
unsigned ind = i;
// Find the row with the maximum value in the i-th colum
for (unsigned j = i + 1; j < 4; ++j) {
if (fabs(tmp(j, i)) > fabs(val)) {
ind = j;
val = tmp(j, i);
}
}
// Do row pivoting
if (ind != i) {
for (unsigned j = 0; j < 4; ++j) {
T t;
t = dst(i,j); dst(i,j) = dst(ind,j); dst(ind,j) = t;
t = tmp(i,j); tmp(i,j) = tmp(ind,j); tmp(ind,j) = t;
}
}
// Check for singularity
if (fabs(val) <= SGLimits<T>::min())
return false;
T ival = 1/val;
for (unsigned j = 0; j < 4; ++j) {
tmp(i,j) *= ival;
dst(i,j) *= ival;
}
for (unsigned j = 0; j < 4; ++j) {
if (j == i)
continue;
val = tmp(j,i);
for (unsigned k = 0; k < 4; ++k) {
tmp(j,k) -= tmp(i,k) * val;
dst(j,k) -= dst(i,k) * val;
}
}
}
return true;
}
/// The 1-norm of the matrix, this is the largest column sum of
/// the absolute values of A.
template<typename T>
inline
T
norm1(const SGMatrix<T>& m)
{
T nrm = 0;
for (unsigned i = 0; i < SGMatrix<T>::nRows; ++i) {
T sum = fabs(m(i, 0)) + fabs(m(i, 1)) + fabs(m(i, 2)) + fabs(m(i, 3));
if (nrm < sum)
nrm = sum;
}
return nrm;
}
/// The inf-norm of the matrix, this is the largest row sum of
/// the absolute values of A.
template<typename T>
inline
T
normInf(const SGMatrix<T>& m)
{
T nrm = 0;
for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
T sum = fabs(m(0, i)) + fabs(m(1, i)) + fabs(m(2, i)) + fabs(m(3, i));
if (nrm < sum)
nrm = sum;
}
return nrm;
}
/// Return true if exactly the same
template<typename T>
inline
bool
operator==(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i)
if (m1[i] != m2[i])
return false;
return true;
}
/// Return true if not exactly the same
template<typename T>
inline
bool
operator!=(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{ return ! (m1 == m2); }
/// Return true if equal to the relative tolerance tol
template<typename T>
inline
bool
equivalent(const SGMatrix<T>& m1, const SGMatrix<T>& m2, T rtol, T atol)
{ return norm1(m1 - m2) < rtol*(norm1(m1) + norm1(m2)) + atol; }
/// Return true if equal to the relative tolerance tol
template<typename T>
inline
bool
equivalent(const SGMatrix<T>& m1, const SGMatrix<T>& m2, T rtol)
{ return norm1(m1 - m2) < rtol*(norm1(m1) + norm1(m2)); }
/// Return true if about equal to roundoff of the underlying type
template<typename T>
inline
bool
equivalent(const SGMatrix<T>& m1, const SGMatrix<T>& m2)
{
T tol = 100*SGLimits<T>::epsilon();
return equivalent(m1, m2, tol, tol);
}
#ifndef NDEBUG
template<typename T>
inline
bool
isNaN(const SGMatrix<T>& m)
{
for (unsigned i = 0; i < SGMatrix<T>::nEnts; ++i) {
if (SGMisc<T>::isNaN(m[i]))
return true;
}
return false;
}
#endif
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGMatrix<T>& m)
{
s << "[ " << m(0,0) << ", " << m(0,1) << ", " << m(0,2) << ", " << m(0,3) << "\n";
s << " " << m(1,0) << ", " << m(1,1) << ", " << m(1,2) << ", " << m(1,3) << "\n";
s << " " << m(2,0) << ", " << m(2,1) << ", " << m(2,2) << ", " << m(2,3) << "\n";
s << " " << m(3,0) << ", " << m(3,1) << ", " << m(3,2) << ", " << m(3,3) << " ]";
return s;
}
inline
SGMatrixf
toMatrixf(const SGMatrixd& m)
{
return SGMatrixf((float)m(0,0), (float)m(0,1), (float)m(0,2), (float)m(0,3),
(float)m(1,0), (float)m(1,1), (float)m(1,2), (float)m(1,3),
(float)m(2,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
(float)m(3,0), (float)m(3,1), (float)m(3,2), (float)m(3,3));
}
inline
SGMatrixd
toMatrixd(const SGMatrixf& m)
{
return SGMatrixd(m(0,0), m(0,1), m(0,2), m(0,3),
m(1,0), m(1,1), m(1,2), m(1,3),
m(2,0), m(2,1), m(2,2), m(2,3),
m(3,0), m(3,1), m(3,2), m(3,3));
}
#endif

110
simgear/math/SGMisc.hxx Normal file
View File

@@ -0,0 +1,110 @@
// 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 SGMisc_H
#define SGMisc_H
template<typename T>
class SGMisc {
public:
static T pi() { return T(3.1415926535897932384626433832795029L); }
static T twopi() { return 2*T(3.1415926535897932384626433832795029L); }
static T min(const T& a, const T& b)
{ return a < b ? a : b; }
static T min(const T& a, const T& b, const T& c)
{ return min(min(a, b), c); }
static T min(const T& a, const T& b, const T& c, const T& d)
{ return min(min(min(a, b), c), d); }
static T max(const T& a, const T& b)
{ return a > b ? a : b; }
static T max(const T& a, const T& b, const T& c)
{ return max(max(a, b), c); }
static T max(const T& a, const T& b, const T& c, const T& d)
{ return max(max(max(a, b), c), d); }
// clip the value of a to be in the range between and including _min and _max
static T clip(const T& a, const T& _min, const T& _max)
{ return max(_min, min(_max, a)); }
static int sign(const T& a)
{
if (a < -SGLimits<T>::min())
return -1;
else if (SGLimits<T>::min() < a)
return 1;
else
return 0;
}
static T rad2deg(const T& val)
{ return val*180/pi(); }
static T deg2rad(const T& val)
{ return val*pi()/180; }
// normalize the value to be in a range between [min, max[
static T
normalizePeriodic(const T& min, const T& max, const T& value)
{
T range = max - min;
if (range < SGLimits<T>::min())
return min;
T normalized = value - range*floor((value - min)/range);
// two security checks that can only happen due to roundoff
if (value <= min)
return min;
if (max <= normalized)
return min;
return normalized;
}
// normalize the angle to be in a range between [-pi, pi[
static T
normalizeAngle(const T& angle)
{ return normalizePeriodic(-pi(), pi(), angle); }
// normalize the angle to be in a range between [0, 2pi[
static T
normalizeAngle2(const T& angle)
{ return normalizePeriodic(0, twopi(), angle); }
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!
static bool isNaN(const T& v)
{
#ifdef HAVE_ISNAN
return isnan(v);
#elif defined HAVE_STD_ISNAN
return std::isnan(v);
#else
// Use that every compare involving a NaN returns false
// But be careful, some usual compiler switches like for example
// -fast-math from gcc might optimize that expression to v != v which
// behaves exactly like the opposite ...
return !(v == v);
#endif
}
#endif
};
#endif

59
simgear/math/SGPlane.hxx Normal file
View File

@@ -0,0 +1,59 @@
// 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 SGPlane_H
#define SGPlane_H
template<typename T>
class SGPlane {
public:
SGPlane()
{ }
SGPlane(const SGVec3<T>& normal, T dist) :
_normal(normal), _dist(dist)
{ }
SGPlane(const SGVec3<T> vertices[3]) :
_normal(normalize(cross(vertices[1] - vertices[0],
vertices[2] - vertices[0]))),
_dist(-dot(_normal, vertices[0]))
{ }
void setNormal(const SGVec3<T>& normal)
{ _normal = normal; }
const SGVec3<T>& getNormal() const
{ return _normal; }
void setDist(const T& dist)
{ _dist = dist; }
const T& getDist() const
{ return _dist; }
/// That is the distance where we measure positive in direction of the normal
T getPositiveDist() const
{ return -_dist; }
/// That is the distance where we measure positive in the oposite direction
/// of the normal.
const T& getNegativeDist() const
{ return _dist; }
private:
// That ordering is important because of one constructor
SGVec3<T> _normal;
T _dist;
};
#endif

793
simgear/math/SGQuat.hxx Normal file
View File

@@ -0,0 +1,793 @@
// 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 SGQuat_H
#define SGQuat_H
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#include <osg/Quat>
template<typename T>
struct SGQuatStorage {
/// Readonly raw storage interface
const T (&data(void) const)[4]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[4]
{ return _data; }
void osg() const
{ }
private:
T _data[4];
};
template<>
struct SGQuatStorage<double> : public osg::Quat {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[4]
{ return osg::Quat::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[4]
{ return osg::Quat::_v; }
const osg::Quat& osg() const
{ return *this; }
osg::Quat& osg()
{ return *this; }
};
/// 3D Vector Class
template<typename T>
class SGQuat : protected SGQuatStorage<T> {
public:
typedef T value_type;
/// Default constructor. Does not initialize at all.
/// If you need them zero initialized, SGQuat::zeros()
SGQuat(void)
{
/// Initialize with nans in the debug build, that will guarantee to have
/// a fast uninitialized default constructor in the release but shows up
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < 4; ++i)
data()[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the given values
SGQuat(T _x, T _y, T _z, T _w)
{ x() = _x; y() = _y; z() = _z; w() = _w; }
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 4 elements
explicit SGQuat(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGQuat(const osg::Quat& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
/// Return a unit quaternion
static SGQuat unit(void)
{ return fromRealImag(1, SGVec3<T>(0, 0, 0)); }
/// Return a quaternion from euler angles
static SGQuat fromEulerRad(T z, T y, T x)
{
SGQuat q;
T zd2 = T(0.5)*z; T yd2 = T(0.5)*y; T xd2 = T(0.5)*x;
T Szd2 = sin(zd2); T Syd2 = sin(yd2); T Sxd2 = sin(xd2);
T Czd2 = cos(zd2); T Cyd2 = cos(yd2); T Cxd2 = cos(xd2);
T Cxd2Czd2 = Cxd2*Czd2; T Cxd2Szd2 = Cxd2*Szd2;
T Sxd2Szd2 = Sxd2*Szd2; T Sxd2Czd2 = Sxd2*Czd2;
q.w() = Cxd2Czd2*Cyd2 + Sxd2Szd2*Syd2;
q.x() = Sxd2Czd2*Cyd2 - Cxd2Szd2*Syd2;
q.y() = Cxd2Czd2*Syd2 + Sxd2Szd2*Cyd2;
q.z() = Cxd2Szd2*Cyd2 - Sxd2Czd2*Syd2;
return q;
}
/// Return a quaternion from euler angles in degrees
static SGQuat fromEulerDeg(T z, T y, T x)
{
return fromEulerRad(SGMisc<T>::deg2rad(z), SGMisc<T>::deg2rad(y),
SGMisc<T>::deg2rad(x));
}
/// Return a quaternion from euler angles
static SGQuat fromYawPitchRoll(T y, T p, T r)
{ return fromEulerRad(y, p, r); }
/// Return a quaternion from euler angles
static SGQuat fromYawPitchRollDeg(T y, T p, T r)
{ return fromEulerDeg(y, p, r); }
/// Return a quaternion from euler angles
static SGQuat fromHeadAttBank(T h, T a, T b)
{ return fromEulerRad(h, a, b); }
/// Return a quaternion from euler angles
static SGQuat fromHeadAttBankDeg(T h, T a, T b)
{ return fromEulerDeg(h, a, b); }
/// Return a quaternion rotation from the earth centered to the
/// simulation usual horizontal local frame from given
/// longitude and latitude.
/// The horizontal local frame used in simulations is the frame with x-axis
/// pointing north, the y-axis pointing eastwards and the z axis
/// pointing downwards.
static SGQuat fromLonLatRad(T lon, T lat)
{
SGQuat q;
T zd2 = T(0.5)*lon;
T yd2 = T(-0.25)*SGMisc<T>::pi() - T(0.5)*lat;
T Szd2 = sin(zd2);
T Syd2 = sin(yd2);
T Czd2 = cos(zd2);
T Cyd2 = cos(yd2);
q.w() = Czd2*Cyd2;
q.x() = -Szd2*Syd2;
q.y() = Czd2*Syd2;
q.z() = Szd2*Cyd2;
return q;
}
/// Like the above provided for convenience
static SGQuat fromLonLatDeg(T lon, T lat)
{ return fromLonLatRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
/// Like the above provided for convenience
static SGQuat fromLonLat(const SGGeod& geod)
{ return fromLonLatRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
/// Return a quaternion rotation from the earth centered to the
/// OpenGL/viewer horizontal local frame from given longitude and latitude.
/// This frame matches the usual OpenGL axis directions. That is the target
/// frame has an x-axis pointing eastwards, y-axis pointing up and y z-axis
/// pointing south.
static SGQuat viewHLRad(T lon, T lat)
{
// That bails down to a 3-2-1 euler sequence lon+pi/2, 0, -lat-pi
// what is here is again the hand optimized version ...
SGQuat q;
T xd2 = -T(0.5)*lat - T(0.5)*SGMisc<T>::pi();
T zd2 = T(0.5)*lon + T(0.25)*SGMisc<T>::pi();
T Szd2 = sin(zd2);
T Sxd2 = sin(xd2);
T Czd2 = cos(zd2);
T Cxd2 = cos(xd2);
q.w() = Cxd2*Czd2;
q.x() = Sxd2*Czd2;
q.y() = Sxd2*Szd2;
q.z() = Cxd2*Szd2;
return q;
}
/// Like the above provided for convenience
static SGQuat viewHLDeg(T lon, T lat)
{ return viewHLRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
/// Like the above provided for convenience
static SGQuat viewHL(const SGGeod& geod)
{ return viewHLRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
/// Convert a quaternion rotation from the simulation frame
/// to the view (OpenGL) frame. That is it just swaps the axis part of
/// this current quaternion.
/// That proves useful when you want to use the euler 3-2-1 sequence
/// for the usual heading/pitch/roll sequence within the context of
/// OpenGL/viewer frames.
static SGQuat simToView(const SGQuat& q)
{ return SGQuat(q.y(), -q.z(), -q.x(), q.w()); }
/// Create a quaternion from the angle axis representation
static SGQuat fromAngleAxis(T angle, const SGVec3<T>& axis)
{
T angle2 = 0.5*angle;
return fromRealImag(cos(angle2), T(sin(angle2))*axis);
}
/// Create a quaternion from the angle axis representation
static SGQuat fromAngleAxisDeg(T angle, const SGVec3<T>& axis)
{ return fromAngleAxis(SGMisc<T>::deg2rad(angle), axis); }
/// Create a quaternion from the angle axis representation where the angle
/// is stored in the axis' length
static SGQuat fromAngleAxis(const SGVec3<T>& axis)
{
T nAxis = norm(axis);
if (nAxis <= SGLimits<T>::min())
return SGQuat(1, 0, 0, 0);
T angle2 = 0.5*nAxis;
return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis);
}
static SGQuat fromRotateTo(const SGVec3<T>& from, const SGVec3<T>& to)
{
T nfrom = norm(from);
T nto = norm(to);
if (nfrom < SGLimits<T>::min() || nto < SGLimits<T>::min())
return SGQuat::unit();
return SGQuat::fromRotateToNorm((1/nfrom)*from, (1/nto)*to);
}
// FIXME more finegrained error behavour.
static SGQuat fromRotateTo(const SGVec3<T>& v1, unsigned i1,
const SGVec3<T>& v2, unsigned i2)
{
T nrmv1 = norm(v1);
T nrmv2 = norm(v2);
if (nrmv1 < SGLimits<T>::min() || nrmv2 < SGLimits<T>::min())
return SGQuat::unit();
SGVec3<T> nv1 = (1/nrmv1)*v1;
SGVec3<T> nv2 = (1/nrmv2)*v2;
T dv1v2 = dot(nv1, nv2);
if (fabs(fabs(dv1v2)-1) < SGLimits<T>::epsilon())
return SGQuat::unit();
// The target vector for the first rotation
SGVec3<T> nto1 = SGVec3<T>::zeros();
SGVec3<T> nto2 = SGVec3<T>::zeros();
nto1[i1] = 1;
nto2[i2] = 1;
// The first rotation can be done with the usual routine.
SGQuat q = SGQuat::fromRotateToNorm(nv1, nto1);
// The rotation axis for the second rotation is the
// target for the first one, so the rotation axis is nto1
// We need to get the angle.
// Make nv2 exactly orthogonal to nv1.
nv2 = normalize(nv2 - dv1v2*nv1);
SGVec3<T> tnv2 = q.transform(nv2);
T cosang = dot(nto2, tnv2);
T cos05ang = T(0.5+0.5*cosang);
if (cos05ang <= 0)
cosang = T(0);
cos05ang = sqrt(cos05ang);
T sig = dot(nto1, cross(nto2, tnv2));
T sin05ang = T(0.5-0.5*cosang);
if (sin05ang <= 0)
sin05ang = 0;
sin05ang = copysign(sqrt(sin05ang), sig);
q *= SGQuat::fromRealImag(cos05ang, sin05ang*nto1);
return q;
}
// Return a quaternion which rotates the vector given by v
// to the vector -v. Other directions are *not* preserved.
static SGQuat fromChangeSign(const SGVec3<T>& v)
{
// The vector from points to the oposite direction than to.
// Find a vector perpendicular to the vector to.
T absv1 = fabs(v(0));
T absv2 = fabs(v(1));
T absv3 = fabs(v(2));
SGVec3<T> axis;
if (absv2 < absv1 && absv3 < absv1) {
T quot = v(1)/v(0);
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(quot, -1, 0);
} else if (absv1 < absv2 && absv3 < absv2) {
T quot = v(2)/v(1);
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(0, quot, -1);
} else if (absv1 < absv3 && absv2 < absv3) {
T quot = v(0)/v(2);
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(-1, 0, quot);
} else {
// The all zero case.
return SGQuat::unit();
}
return SGQuat::fromRealImag(0, axis);
}
/// Return a quaternion from real and imaginary part
static SGQuat fromRealImag(T r, const SGVec3<T>& i)
{
SGQuat q;
q.w() = r;
q.x() = i.x();
q.y() = i.y();
q.z() = i.z();
return q;
}
/// Return an all zero vector
static SGQuat zeros(void)
{ return SGQuat(0, 0, 0, 0); }
/// write the euler angles into the references
void getEulerRad(T& zRad, T& yRad, T& xRad) const
{
T sqrQW = w()*w();
T sqrQX = x()*x();
T sqrQY = y()*y();
T sqrQZ = z()*z();
T num = 2*(y()*z() + w()*x());
T den = sqrQW - sqrQX - sqrQY + sqrQZ;
if (fabs(den) < SGLimits<T>::min() &&
fabs(num) < SGLimits<T>::min())
xRad = 0;
else
xRad = atan2(num, den);
T tmp = 2*(x()*z() - w()*y());
if (tmp < -1)
yRad = 0.5*SGMisc<T>::pi();
else if (1 < tmp)
yRad = -0.5*SGMisc<T>::pi();
else
yRad = -asin(tmp);
num = 2*(x()*y() + w()*z());
den = sqrQW + sqrQX - sqrQY - sqrQZ;
if (fabs(den) < SGLimits<T>::min() &&
fabs(num) < SGLimits<T>::min())
zRad = 0;
else {
T psi = atan2(num, den);
if (psi < 0)
psi += 2*SGMisc<T>::pi();
zRad = psi;
}
}
/// write the euler angles in degrees into the references
void getEulerDeg(T& zDeg, T& yDeg, T& xDeg) const
{
getEulerRad(zDeg, yDeg, xDeg);
zDeg = SGMisc<T>::rad2deg(zDeg);
yDeg = SGMisc<T>::rad2deg(yDeg);
xDeg = SGMisc<T>::rad2deg(xDeg);
}
/// write the angle axis representation into the references
void getAngleAxis(T& angle, SGVec3<T>& axis) const
{
T nrm = norm(*this);
if (nrm < SGLimits<T>::min()) {
angle = 0;
axis = SGVec3<T>(0, 0, 0);
} else {
T rNrm = 1/nrm;
angle = acos(SGMisc<T>::max(-1, SGMisc<T>::min(1, rNrm*w())));
T sAng = sin(angle);
if (fabs(sAng) < SGLimits<T>::min())
axis = SGVec3<T>(1, 0, 0);
else
axis = (rNrm/sAng)*imag(*this);
angle *= 2;
}
}
/// write the angle axis representation into the references
void getAngleAxis(SGVec3<T>& axis) const
{
T angle;
getAngleAxis(angle, axis);
axis *= angle;
}
/// Access by index, the index is unchecked
const T& operator()(unsigned i) const
{ return data()[i]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i)
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
T& operator[](unsigned i)
{ return data()[i]; }
/// Access the x component
const T& x(void) const
{ return data()[0]; }
/// Access the x component
T& x(void)
{ return data()[0]; }
/// Access the y component
const T& y(void) const
{ return data()[1]; }
/// Access the y component
T& y(void)
{ return data()[1]; }
/// Access the z component
const T& z(void) const
{ return data()[2]; }
/// Access the z component
T& z(void)
{ return data()[2]; }
/// Access the w component
const T& w(void) const
{ return data()[3]; }
/// Access the w component
T& w(void)
{ return data()[3]; }
/// Get the data pointer
using SGQuatStorage<T>::data;
/// Readonly interface function to ssg's sgQuat/sgdQuat
const T (&sg(void) const)[4]
{ return data(); }
/// Interface function to ssg's sgQuat/sgdQuat
T (&sg(void))[4]
{ return data(); }
/// Interface function to osg's Quat*
using SGQuatStorage<T>::osg;
/// Inplace addition
SGQuat& operator+=(const SGQuat& v)
{ data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
/// Inplace subtraction
SGQuat& operator-=(const SGQuat& v)
{ data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
/// Inplace scalar multiplication
template<typename S>
SGQuat& operator*=(S s)
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGQuat& operator/=(S s)
{ return operator*=(1/T(s)); }
/// Inplace quaternion multiplication
SGQuat& operator*=(const SGQuat& v);
/// Transform a vector from the current coordinate frame to a coordinate
/// frame rotated with the quaternion
SGVec3<T> transform(const SGVec3<T>& v) const
{
T r = 2/dot(*this, *this);
SGVec3<T> qimag = imag(*this);
T qr = real(*this);
return (r*qr*qr - 1)*v + (r*dot(qimag, v))*qimag - (r*qr)*cross(qimag, v);
}
/// Transform a vector from the coordinate frame rotated with the quaternion
/// to the current coordinate frame
SGVec3<T> backTransform(const SGVec3<T>& v) const
{
T r = 2/dot(*this, *this);
SGVec3<T> qimag = imag(*this);
T qr = real(*this);
return (r*qr*qr - 1)*v + (r*dot(qimag, v))*qimag + (r*qr)*cross(qimag, v);
}
/// Rotate a given vector with the quaternion
SGVec3<T> rotate(const SGVec3<T>& v) const
{ return backTransform(v); }
/// Rotate a given vector with the inverse quaternion
SGVec3<T> rotateBack(const SGVec3<T>& v) const
{ return transform(v); }
/// Return the time derivative of the quaternion given the angular velocity
SGQuat
derivative(const SGVec3<T>& angVel) const
{
SGQuat deriv;
deriv.w() = 0.5*(-x()*angVel(0) - y()*angVel(1) - z()*angVel(2));
deriv.x() = 0.5*( w()*angVel(0) - z()*angVel(1) + y()*angVel(2));
deriv.y() = 0.5*( z()*angVel(0) + w()*angVel(1) - x()*angVel(2));
deriv.z() = 0.5*(-y()*angVel(0) + x()*angVel(1) + w()*angVel(2));
return deriv;
}
private:
// Private because it assumes normalized inputs.
static SGQuat
fromRotateToSmaller90Deg(T cosang,
const SGVec3<T>& from, const SGVec3<T>& to)
{
// In this function we assume that the angle required to rotate from
// the vector from to the vector to is <= 90 deg.
// That is done so because of possible instabilities when we rotate more
// then 90deg.
// Note that the next comment does actually cover a *more* *general* case
// than we need in this function. That shows that this formula is even
// valid for rotations up to 180deg.
// Because of the signs in the axis, it is sufficient to care for angles
// in the interval [-pi,pi]. That means that 0.5*angle is in the interval
// [-pi/2,pi/2]. But in that range the cosine is allways >= 0.
// So we do not need to care for egative roots in the following equation:
T cos05ang = sqrt(0.5+0.5*cosang);
// Now our assumption of angles <= 90 deg comes in play.
// For that reason, we know that cos05ang is not zero.
// It is even more, we can see from the above formula that
// sqrt(0.5) < cos05ang.
// Compute the rotation axis, that is
// sin(angle)*normalized rotation axis
SGVec3<T> axis = cross(to, from);
// We need sin(0.5*angle)*normalized rotation axis.
// So rescale with sin(0.5*x)/sin(x).
// To do that we use the equation:
// sin(x) = 2*sin(0.5*x)*cos(0.5*x)
return SGQuat::fromRealImag( cos05ang, (1/(2*cos05ang))*axis);
}
// Private because it assumes normalized inputs.
static SGQuat
fromRotateToNorm(const SGVec3<T>& from, const SGVec3<T>& to)
{
// To avoid instabilities with roundoff, we distinguish between rotations
// with more then 90deg and rotations with less than 90deg.
// Compute the cosine of the angle.
T cosang = dot(from, to);
// For the small ones do direct computation
if (T(-0.5) < cosang)
return SGQuat::fromRotateToSmaller90Deg(cosang, from, to);
// For larger rotations. first rotate from to -from.
// Past that we will have a smaller angle again.
SGQuat q1 = SGQuat::fromChangeSign(from);
SGQuat q2 = SGQuat::fromRotateToSmaller90Deg(-cosang, -from, to);
return q1*q2;
}
};
/// Unary +, do nothing ...
template<typename T>
inline
const SGQuat<T>&
operator+(const SGQuat<T>& v)
{ return v; }
/// Unary -, do nearly nothing
template<typename T>
inline
SGQuat<T>
operator-(const SGQuat<T>& v)
{ return SGQuat<T>(-v(0), -v(1), -v(2), -v(3)); }
/// Binary +
template<typename T>
inline
SGQuat<T>
operator+(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return SGQuat<T>(v1(0)+v2(0), v1(1)+v2(1), v1(2)+v2(2), v1(3)+v2(3)); }
/// Binary -
template<typename T>
inline
SGQuat<T>
operator-(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return SGQuat<T>(v1(0)-v2(0), v1(1)-v2(1), v1(2)-v2(2), v1(3)-v2(3)); }
/// Scalar multiplication
template<typename S, typename T>
inline
SGQuat<T>
operator*(S s, const SGQuat<T>& v)
{ return SGQuat<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
/// Scalar multiplication
template<typename S, typename T>
inline
SGQuat<T>
operator*(const SGQuat<T>& v, S s)
{ return SGQuat<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
/// Quaterion multiplication
template<typename T>
inline
SGQuat<T>
operator*(const SGQuat<T>& v1, const SGQuat<T>& v2)
{
SGQuat<T> v;
v.x() = v1.w()*v2.x() + v1.x()*v2.w() + v1.y()*v2.z() - v1.z()*v2.y();
v.y() = v1.w()*v2.y() - v1.x()*v2.z() + v1.y()*v2.w() + v1.z()*v2.x();
v.z() = v1.w()*v2.z() + v1.x()*v2.y() - v1.y()*v2.x() + v1.z()*v2.w();
v.w() = v1.w()*v2.w() - v1.x()*v2.x() - v1.y()*v2.y() - v1.z()*v2.z();
return v;
}
/// Now define the inplace multiplication
template<typename T>
inline
SGQuat<T>&
SGQuat<T>::operator*=(const SGQuat& v)
{ (*this) = (*this)*v; return *this; }
/// The conjugate of the quaternion, this is also the
/// inverse for normalized quaternions
template<typename T>
inline
SGQuat<T>
conj(const SGQuat<T>& v)
{ return SGQuat<T>(-v(0), -v(1), -v(2), v(3)); }
/// The conjugate of the quaternion, this is also the
/// inverse for normalized quaternions
template<typename T>
inline
SGQuat<T>
inverse(const SGQuat<T>& v)
{ return (1/dot(v, v))*SGQuat<T>(-v(0), -v(1), -v(2), v(3)); }
/// The imagniary part of the quaternion
template<typename T>
inline
T
real(const SGQuat<T>& v)
{ return v.w(); }
/// The imagniary part of the quaternion
template<typename T>
inline
SGVec3<T>
imag(const SGQuat<T>& v)
{ return SGVec3<T>(v.x(), v.y(), v.z()); }
/// Scalar dot product
template<typename T>
inline
T
dot(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
T
norm(const SGQuat<T>& v)
{ return sqrt(dot(v, v)); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
T
length(const SGQuat<T>& v)
{ return sqrt(dot(v, v)); }
/// The 1-norm of the vector, this one is the fastest length function we
/// can implement on modern cpu's
template<typename T>
inline
T
norm1(const SGQuat<T>& v)
{ return fabs(v(0)) + fabs(v(1)) + fabs(v(2)) + fabs(v(3)); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
SGQuat<T>
normalize(const SGQuat<T>& q)
{ return (1/norm(q))*q; }
/// Return true if exactly the same
template<typename T>
inline
bool
operator==(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return v1(0)==v2(0) && v1(1)==v2(1) && v1(2)==v2(2) && v1(3)==v2(3); }
/// Return true if not exactly the same
template<typename T>
inline
bool
operator!=(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return ! (v1 == v2); }
/// Return true if equal to the relative tolerance tol
/// Note that this is not the same than comparing quaternions to represent
/// the same rotation
template<typename T>
inline
bool
equivalent(const SGQuat<T>& v1, const SGQuat<T>& v2, T tol)
{ return norm1(v1 - v2) < tol*(norm1(v1) + norm1(v2)); }
/// Return true if about equal to roundoff of the underlying type
/// Note that this is not the same than comparing quaternions to represent
/// the same rotation
template<typename T>
inline
bool
equivalent(const SGQuat<T>& v1, const SGQuat<T>& v2)
{ return equivalent(v1, v2, 100*SGLimits<T>::epsilon()); }
#ifndef NDEBUG
template<typename T>
inline
bool
isNaN(const SGQuat<T>& v)
{
return SGMisc<T>::isNaN(v(0)) || SGMisc<T>::isNaN(v(1))
|| SGMisc<T>::isNaN(v(2)) || SGMisc<T>::isNaN(v(3));
}
#endif
/// quaternion interpolation for t in [0,1] interpolate between src (=0)
/// and dst (=1)
template<typename T>
inline
SGQuat<T>
interpolate(T t, const SGQuat<T>& src, const SGQuat<T>& dst)
{
T cosPhi = dot(src, dst);
// need to take the shorter way ...
int signCosPhi = SGMisc<T>::sign(cosPhi);
// cosPhi must be corrected for that sign
cosPhi = fabs(cosPhi);
// first opportunity to fail - make sure acos will succeed later -
// result is correct
if (1 <= cosPhi)
return dst;
// now the half angle between the orientations
T o = acos(cosPhi);
// need the scales now, if the angle is very small, do linear interpolation
// to avoid instabilities
T scale0, scale1;
if (fabs(o) < SGLimits<T>::epsilon()) {
scale0 = 1 - t;
scale1 = t;
} else {
// note that we can give a positive lower bound for sin(o) here
T sino = sin(o);
T so = 1/sino;
scale0 = sin((1 - t)*o)*so;
scale1 = sin(t*o)*so;
}
return scale0*src + signCosPhi*scale1*dst;
}
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
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) << " ]"; }
inline
SGQuatf
toQuatf(const SGQuatd& v)
{ return SGQuatf((float)v(0), (float)v(1), (float)v(2), (float)v(3)); }
inline
SGQuatd
toQuatd(const SGQuatf& v)
{ return SGQuatd(v(0), v(1), v(2), v(3)); }
#endif

62
simgear/math/SGRay.hxx Normal file
View File

@@ -0,0 +1,62 @@
// 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 SGRay_H
#define SGRay_H
template<typename T>
class SGRay {
public:
SGRay()
{ }
SGRay(const SGVec3<T>& origin, const SGVec3<T>& dir) :
_origin(origin), _direction(dir)
{ }
void set(const SGVec3<T>& origin, const SGVec3<T>& dir)
{ _origin = origin; _direction = dir; }
void setOrigin(const SGVec3<T>& origin)
{ _origin = origin; }
const SGVec3<T>& getOrigin() const
{ return _origin; }
void setDirection(const SGVec3<T>& direction)
{ _direction = direction; }
const SGVec3<T>& getDirection() const
{ return _direction; }
SGVec3<T> getNormalizedDirection() const
{ return normalize(getDirection()); }
private:
SGVec3<T> _origin;
SGVec3<T> _direction;
};
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s,
const SGRay<T>& ray)
{
return s << "ray: origin = " << ray.getOrigin()
<< ", direction = " << ray.getDirection();
}
#endif

87
simgear/math/SGSphere.hxx Normal file
View File

@@ -0,0 +1,87 @@
// 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 SGSphere_H
#define SGSphere_H
template<typename T>
class SGSphere {
public:
SGSphere() :
_radius(-1)
{ }
SGSphere(const SGVec3<T>& center, const T& radius) :
_center(center),
_radius(radius)
{ }
const SGVec3<T>& getCenter() const
{ return _center; }
void setCenter(const SGVec3<T>& center)
{ _center = center; }
const T& getRadius() const
{ return _radius; }
void setRadius(const T& radius)
{ _radius = radius; }
T getRadius2() const
{ return _radius*_radius; }
const bool empty() const
{ return !valid(); }
bool valid() const
{ return 0 <= _radius; }
void clear()
{ _radius = -1; }
void expandBy(const SGVec3<T>& v)
{
if (empty()) {
_center = v;
_radius = 0;
return;
}
T dist2 = distSqr(_center, v);
if (dist2 <= getRadius2())
return;
T dist = sqrt(dist2);
T newRadius = T(0.5)*(_radius + dist);
_center += ((newRadius - _radius)/dist)*(v - _center);
_radius = newRadius;
}
private:
SGVec3<T> _center;
T _radius;
};
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s,
const SGSphere<T>& sphere)
{
return s << "center = " << sphere.getCenter()
<< ", radius = " << sphere.getRadius();
}
#endif

101
simgear/math/SGTriangle.hxx Normal file
View File

@@ -0,0 +1,101 @@
// 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 SGTriangle_H
#define SGTrianlge_H
template<typename T>
class SGTriangle {
public:
SGTriangle()
{ }
SGTriangle(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2)
{ set(v0, v1, v2); }
SGTriangle(const SGVec3<T> v[3])
{ set(v); }
void set(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2)
{
_v0 = v0;
_d[0] = v1 - v0;
_d[1] = v2 - v0;
}
void set(const SGVec3<T> v[3])
{
_v0 = v[0];
_d[0] = v[1] - v[0];
_d[1] = v[2] - v[0];
}
SGVec3d getCenter() const
{
SGBoxd box;
box.expandBy(_v0);
box.expandBy(_v0 + _d[0]);
box.expandBy(_v0 + _d[1]);
return box.getCenter();
}
// note that the index is unchecked
SGVec3<T> getVertex(unsigned i) const
{
if (0 < i)
return _v0 + _d[i-1];
return _v0;
}
/// return the normalized surface normal
SGVec3<T> getNormal() const
{ return normalize(cross(_d[0], _d[1])); }
const SGVec3<T>& getBaseVertex() const
{ return _v0; }
void setBaseVertex(const SGVec3<T>& v)
{ _v0 = v; }
const SGVec3<T>& getEdge(unsigned i) const
{ return _d[i]; }
void setEdge(unsigned i, const SGVec3<T>& d)
{ _d[i] = d; }
// flip the positive side
void flip()
{
SGVec3<T> tmp = _d[0];
_d[0] = _d[1];
_d[1] = tmp;
}
private:
/// Store one vertex directly, _d is the offset of the other two
/// vertices wrt the base vertex
/// For fast intersection tests this format prooves usefull. For that same
/// purpose also cache the cross product of the _d[i].
SGVec3<T> _v0;
SGVec3<T> _d[2];
};
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s,
const SGTriangle<T>& triangle)
{
return s << "triangle: v0 = " << triangle.getVertex(0)
<< ", v1 = " << triangle.getVertex(1)
<< ", v2 = " << triangle.getVertex(2);
}
#endif

405
simgear/math/SGVec2.hxx Normal file
View File

@@ -0,0 +1,405 @@
// 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 SGVec2_H
#define SGVec2_H
#include <osg/Vec2f>
#include <osg/Vec2d>
template<typename T>
struct SGVec2Storage {
/// Readonly raw storage interface
const T (&data(void) const)[2]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[2]
{ return _data; }
void osg() const
{ }
private:
T _data[2];
};
template<>
struct SGVec2Storage<float> : public osg::Vec2f {
/// Access raw data by index, the index is unchecked
const float (&data(void) const)[2]
{ return osg::Vec2f::_v; }
/// Access raw data by index, the index is unchecked
float (&data(void))[2]
{ return osg::Vec2f::_v; }
const osg::Vec2f& osg() const
{ return *this; }
osg::Vec2f& osg()
{ return *this; }
};
template<>
struct SGVec2Storage<double> : public osg::Vec2d {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[2]
{ return osg::Vec2d::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[2]
{ return osg::Vec2d::_v; }
const osg::Vec2d& osg() const
{ return *this; }
osg::Vec2d& osg()
{ return *this; }
};
/// 2D Vector Class
template<typename T>
class SGVec2 : protected SGVec2Storage<T> {
public:
typedef T value_type;
/// Default constructor. Does not initialize at all.
/// If you need them zero initialized, use SGVec2::zeros()
SGVec2(void)
{
/// Initialize with nans in the debug build, that will guarantee to have
/// a fast uninitialized default constructor in the release but shows up
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < 2; ++i)
data()[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the given values
SGVec2(T x, T y)
{ data()[0] = x; data()[1] = y; }
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 2 elements
explicit SGVec2(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; }
explicit SGVec2(const osg::Vec2f& d)
{ data()[0] = d[0]; data()[1] = d[1]; }
explicit SGVec2(const osg::Vec2d& d)
{ data()[0] = d[0]; data()[1] = d[1]; }
/// Access by index, the index is unchecked
const T& operator()(unsigned i) const
{ return data()[i]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i)
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
T& operator[](unsigned i)
{ return data()[i]; }
/// Access the x component
const T& x(void) const
{ return data()[0]; }
/// Access the x component
T& x(void)
{ return data()[0]; }
/// Access the y component
const T& y(void) const
{ return data()[1]; }
/// Access the y component
T& y(void)
{ return data()[1]; }
/// Get the data pointer
using SGVec2Storage<T>::data;
/// Readonly interface function to ssg's sgVec2/sgdVec2
const T (&sg(void) const)[2]
{ return data(); }
/// Interface function to ssg's sgVec2/sgdVec2
T (&sg(void))[2]
{ return data(); }
/// Interface function to osg's Vec2*
using SGVec2Storage<T>::osg;
/// Inplace addition
SGVec2& operator+=(const SGVec2& v)
{ data()[0] += v(0); data()[1] += v(1); return *this; }
/// Inplace subtraction
SGVec2& operator-=(const SGVec2& v)
{ data()[0] -= v(0); data()[1] -= v(1); return *this; }
/// Inplace scalar multiplication
template<typename S>
SGVec2& operator*=(S s)
{ data()[0] *= s; data()[1] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGVec2& operator/=(S s)
{ return operator*=(1/T(s)); }
/// Return an all zero vector
static SGVec2 zeros(void)
{ return SGVec2(0, 0); }
/// Return unit vectors
static SGVec2 e1(void)
{ return SGVec2(1, 0); }
static SGVec2 e2(void)
{ return SGVec2(0, 1); }
};
/// Unary +, do nothing ...
template<typename T>
inline
const SGVec2<T>&
operator+(const SGVec2<T>& v)
{ return v; }
/// Unary -, do nearly nothing
template<typename T>
inline
SGVec2<T>
operator-(const SGVec2<T>& v)
{ return SGVec2<T>(-v(0), -v(1)); }
/// Binary +
template<typename T>
inline
SGVec2<T>
operator+(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return SGVec2<T>(v1(0)+v2(0), v1(1)+v2(1)); }
/// Binary -
template<typename T>
inline
SGVec2<T>
operator-(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return SGVec2<T>(v1(0)-v2(0), v1(1)-v2(1)); }
/// Scalar multiplication
template<typename S, typename T>
inline
SGVec2<T>
operator*(S s, const SGVec2<T>& v)
{ return SGVec2<T>(s*v(0), s*v(1)); }
/// Scalar multiplication
template<typename S, typename T>
inline
SGVec2<T>
operator*(const SGVec2<T>& v, S s)
{ return SGVec2<T>(s*v(0), s*v(1)); }
/// multiplication as a multiplicator, that is assume that the first vector
/// represents a 2x2 diagonal matrix with the diagonal elements in the vector.
/// Then the result is the product of that matrix times the second vector.
template<typename T>
inline
SGVec2<T>
mult(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return SGVec2<T>(v1(0)*v2(0), v1(1)*v2(1)); }
/// component wise min
template<typename T>
inline
SGVec2<T>
min(const SGVec2<T>& v1, const SGVec2<T>& v2)
{return SGVec2<T>(SGMisc<T>::min(v1(0), v2(0)), SGMisc<T>::min(v1(1), v2(1)));}
template<typename S, typename T>
inline
SGVec2<T>
min(const SGVec2<T>& v, S s)
{ return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
template<typename S, typename T>
inline
SGVec2<T>
min(S s, const SGVec2<T>& v)
{ return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
/// component wise max
template<typename T>
inline
SGVec2<T>
max(const SGVec2<T>& v1, const SGVec2<T>& v2)
{return SGVec2<T>(SGMisc<T>::max(v1(0), v2(0)), SGMisc<T>::max(v1(1), v2(1)));}
template<typename S, typename T>
inline
SGVec2<T>
max(const SGVec2<T>& v, S s)
{ return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
template<typename S, typename T>
inline
SGVec2<T>
max(S s, const SGVec2<T>& v)
{ return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
/// Scalar dot product
template<typename T>
inline
T
dot(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return v1(0)*v2(0) + v1(1)*v2(1); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
T
norm(const SGVec2<T>& v)
{ return sqrt(dot(v, v)); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
T
length(const SGVec2<T>& v)
{ return sqrt(dot(v, v)); }
/// The 1-norm of the vector, this one is the fastest length function we
/// can implement on modern cpu's
template<typename T>
inline
T
norm1(const SGVec2<T>& v)
{ return fabs(v(0)) + fabs(v(1)); }
/// The inf-norm of the vector
template<typename T>
inline
T
normI(const SGVec2<T>& v)
{ return SGMisc<T>::max(fabs(v(0)), fabs(v(1))); }
/// The euclidean norm of the vector, that is what most people call length
template<typename T>
inline
SGVec2<T>
normalize(const SGVec2<T>& v)
{ return (1/norm(v))*v; }
/// Return true if exactly the same
template<typename T>
inline
bool
operator==(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return v1(0) == v2(0) && v1(1) == v2(1); }
/// Return true if not exactly the same
template<typename T>
inline
bool
operator!=(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return ! (v1 == v2); }
/// Return true if smaller, good for putting that into a std::map
template<typename T>
inline
bool
operator<(const SGVec2<T>& v1, const SGVec2<T>& v2)
{
if (v1(0) < v2(0)) return true;
else if (v2(0) < v1(0)) return false;
else return (v1(1) < v2(1));
}
template<typename T>
inline
bool
operator<=(const SGVec2<T>& v1, const SGVec2<T>& v2)
{
if (v1(0) < v2(0)) return true;
else if (v2(0) < v1(0)) return false;
else return (v1(1) <= v2(1));
}
template<typename T>
inline
bool
operator>(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return operator<(v2, v1); }
template<typename T>
inline
bool
operator>=(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return operator<=(v2, v1); }
/// Return true if equal to the relative tolerance tol
template<typename T>
inline
bool
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol, T atol)
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
/// Return true if equal to the relative tolerance tol
template<typename T>
inline
bool
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol)
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
/// Return true if about equal to roundoff of the underlying type
template<typename T>
inline
bool
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2)
{
T tol = 100*SGLimits<T>::epsilon();
return equivalent(v1, v2, tol, tol);
}
/// The euclidean distance of the two vectors
template<typename T>
inline
T
dist(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ return norm(v1 - v2); }
/// The squared euclidean distance of the two vectors
template<typename T>
inline
T
distSqr(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ SGVec2<T> tmp = v1 - v2; return dot(tmp, tmp); }
#ifndef NDEBUG
template<typename T>
inline
bool
isNaN(const SGVec2<T>& v)
{
return SGMisc<T>::isNaN(v(0)) || SGMisc<T>::isNaN(v(1));
}
#endif
/// Output to an ostream
template<typename char_type, typename traits_type, typename T>
inline
std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec2<T>& v)
{ return s << "[ " << v(0) << ", " << v(1) << " ]"; }
inline
SGVec2f
toVec2f(const SGVec2d& v)
{ return SGVec2f((float)v(0), (float)v(1)); }
inline
SGVec2d
toVec2d(const SGVec2f& v)
{ return SGVec2d(v(0), v(1)); }
#endif

Some files were not shown because too many files have changed in this diff Show More