Compare commits

...
Author SHA1 Message Date
Tim Moore 11479cd8c3 Merge branch 'ehofman/sound' 2010-01-16 23:49:36 +01:00
ehofman 176e760de1 test for an AL or ALC error before calling an ALUT function. 2010-01-16 15:50:29 +01:00
Tim Moore 430c60ed1a Merge branch 'ehofman/sound' 2010-01-13 07:57:35 +01:00
Tim Moore dfea3623f6 Merge branch 'tat/framework' 2010-01-13 07:57:30 +01:00
Tim Moore b38783e4cb Merge branch 'ehofman/subsys' 2010-01-11 07:15:11 +01:00
Tim Moore 9382a4c21b Merge branch 'jester/aptsign' 2010-01-11 07:14:51 +01:00
Tim Moore 3cd4c5566f Merge branch 'timoore/effects' 2010-01-11 07:14:23 +01:00
Tim Moore 601c0977df Merge branch 'jmt/geodistance' 2010-01-11 07:10:46 +01:00
ehofman c56f036bab Tatsuhiro Nishioka:
These patches fixes minor bug in addition to providing --with-openal-framework and --with-cocoa-framework.
Now you can use your own version of OpenAL.framework for selecting various audio output device.
Plus, you can build FG/SG on Snow Leopard with cocoa configuration.
2010-01-05 22:12:37 +01:00
torsten 44dd50c0ef Csaba Halasz:
Fix airport signs by reverting to rev 1.22 of apt_sign.cxx. Tweaked a little to handle missing materials better.
2010-01-05 22:11:57 +01:00
ehofman 56919ae45f MacOS returns an unsopported AL error when a file is not found, work around this. 2010-01-05 22:10:22 +01:00
jmt 578af00b0d Allow geocentric distance computations to return radians. 2010-01-03 10:10:02 +01:00
Tim Moore d6c0bf69b6 fix up some merge weirdness 2010-01-01 13:32:03 +01:00
ehofman e8884b4ec0 Also unbind subsystem groups in reverse order and destruct them in reverse order to be consistent. 2009-12-31 19:42:53 +01:00
ehofman 5e79609955 unbind in reverse order to try to prevent order dependency problems. 2009-12-30 00:20:08 +01:00
ehofman 4950c96f1c Rearrange alut error checking a bit 2009-12-30 00:05:01 +01:00
jmt 51b0cf535e XML encodings: support 'ASCII' as an alias for 'US-ASCII' 2009-12-29 23:53:28 +01:00
ehofman 4cc17a7f6e keep a pointer to the OpenAL vendor and renderer for reference 2009-12-27 09:24:24 +01:00
Tim Moore dca07c5634 Merge branch 'timoore/effects'
Conflicts:
	simgear/scene/model/model.cxx
	simgear/scene/sky/newcloud.cxx
2009-12-20 16:07:00 +01:00
Tim Moore fd42294faf Merge branch 'ehofman/sound'
Changed include of SGQuat.hxx to SGMath.hxx in
sound/sample_openal.cxx; somehow this happened in a merge commit when
the sound branch was merged to next.
2009-12-20 11:46:28 +01:00
ehofman c1246e8c4e proper typecasting 2009-12-14 22:46:22 +01:00
Tim Moore 59fc902cfb don't render an EffectGeode if there is no valid technique
Normal geometry has a default effect; geometry with no default effect
is unlikely to look correct with no state set applied. This fixes the
problem of clouds being displayed as multi-colored rectangles when
shader effects are turned off.
2009-12-14 06:52:00 +01:00
ehofman 1fe9755d01 fix a typo. 2009-12-12 00:03:41 +01:00
ehofman 1da09a4706 Don't assign the buffer data to the sample in case it is a file. Test for result when calling load() 2009-12-12 00:03:40 +01:00
ehofman f3c591469b Fix crash in SGSoundMgr::stop(): do not try to erase buffer items one at a time 2009-12-12 00:03:40 +01:00
ehofman b1200f9f59 add alcSuspendContext and alcProcessContext again to prevent sound artifacts on hardware accelerated soundcards. 2009-12-06 23:55:08 +01:00
ehofman 47617d6c04 check if suspend, resume and volume changed much from the previous value before setting them. 2009-12-03 06:38:23 +01:00
ehofman 4794ab6095 Fix runtime switching of sound devices. 2009-12-03 06:38:12 +01:00
ehofman bc85767f19 Updates to allow runtime chaning of the sound device 2009-11-30 22:41:14 +01:00
Tim Moore e37c218c2a take locks out of ModelRegistry
They should be unnecessary and were causing deadlock with Effects that
load images.
2009-11-29 22:54:02 +01:00
ehofman a0aaa23904 Add a function to retreive all available playback devices. 2009-11-29 13:04:39 +01:00
ehofman 27a6c72091 initialize volume to a proper value 2009-11-29 13:04:39 +01:00
ehofman 2dcc66f03e Small bugfix 2009-11-29 13:04:38 +01:00
ehofman d70a05a088 Make it possible to specify a different device name 2009-11-29 13:04:38 +01:00
Tim Moore c2317edf8a Revert boost requirement to 1.37
I don't want to get into testing for tr1::unordered_map, and the
boost compatibility doesn't exist in 1.34.
2009-11-29 12:42:10 +01:00
Tim Moore cb7ac404d9 Merge branch 'ehofman/sky' 2009-11-26 23:28:34 +01:00
Tim Moore 5abc6c995f fix a memory leak in newcloud.cxx 2009-11-26 16:30:46 +01:00
ehofman 0f21c39e49 a slightly more readable version of the test 2009-11-26 16:05:46 +01:00
ehofman f6513127ce Also test for older versions of OpenAL-Sample 2009-11-26 16:05:45 +01:00
Tim Moore ddd72b2b37 Use an effect for 3d clouds 2009-11-26 11:40:41 +01:00
Tim Moore 7f5df1fb66 Support for shader program attributes in effects
Also, use a hash table for the effect shader program cache.
2009-11-26 11:39:34 +01:00
Tim Moore 2e71b64de1 Better error reporting for effects
Throw an exception when an undefine attribute value is found in an effect.

Also, fix a typo in TexEnvCombine operand attributes.
2009-11-26 11:32:00 +01:00
Tim Moore 45f1f9263f add a property debugging function 2009-11-26 10:38:31 +01:00
ehofman 878288f06a Don't forget to apply the doppler adjustment factor to the listener velocity also 2009-11-24 14:17:54 +01:00
ehofman 406cdf8d16 test for implementations with 'bad' doppler effects and adjust for it. 2009-11-24 14:17:54 +01:00
ehofman 5b28b024ae fix test programs 2009-11-24 14:17:54 +01:00
ehofman 7c693d8107 proper listener velocity calculation, this has no effect yet but is required when other models start emitting sounds. 2009-11-24 14:17:54 +01:00
Tim Moore b8a6d1ac4d add depth attribute to Effect 2009-11-23 09:15:47 +01:00
Tim Moore 40533f50df Drop required Boost version from 1.37 to 1.34
Use boost/tr1 to bring in std::tr1::unordered_map instead of the Boost
version.
2009-11-22 23:05:11 +01:00
Tim Moore 539ced191b Move tree shaders to an effect
Also, improve effect hash keys.
2009-11-22 00:32:51 +01:00
Tim Moore 1a400b890b Effect file support for GL_VERTEX_PROGRAM_TWO_SIDE and POINT_SIZE 2009-11-22 00:27:53 +01:00
Tim Moore ebe5a5579c shader language predicate 2009-11-20 22:59:15 +01:00
ehofman afb18ca75b the wrong name also mislead me: rotate velocity to the proper quat 2009-11-19 23:01:49 +01:00
ehofman 01c62932bd make the relative positions fixed against the body again. 2009-11-18 23:25:55 +01:00
ehofman 6cd8db7b28 Set to default distance attenuation function but change the parameters a but for better sound effects (and most of all quieter sounds at greta distance 2009-11-18 23:25:51 +01:00
ehofman bb46d91bc6 What do you know, the real problem turned out to be the distance attenuation function.. 2009-11-17 06:43:41 +01:00
Tim Moore 3cd5322496 descend into Effects to find default material animation values 2009-11-16 22:43:41 +01:00
Tim Moore cadecdcab7 add a transparent texture for effects
This is used as a default texture for the chrome animation.

Also, fix a typo in creating combiners.
2009-11-16 22:42:46 +01:00
Tim Moore cd4030b7db Make MultiChangeListener derive publicly from SGPropertyChangeListener
Otherwise it doesn't work as a listener!
2009-11-16 22:39:56 +01:00
Tim Moore 0a2264cad4 When instantiating effects, copy user data of any created nodes.
This bug was the cause of the huge memory consumption / death reported at some places:
the BVH data on "raw" .ac models (random objects) was dropped on the floor.
2009-11-15 23:51:08 +01:00
Tim Moore bb2a02daa8 Bump boost version to 1.37 2009-11-15 01:17:34 +01:00
Tim Moore 5991195062 optimize creation and sharing of effects
Implement equality test and hash for for property trees.  In an
Effect, make a hash table of Effects that inherit from it keyed on
their unmerged property tree. Using that, makeEffect() should return a
single Effect for given property tree description. Animations may
change that in the future...
2009-11-13 22:41:11 +01:00
Tim Moore 54c4055af3 Effects in models working for transparent materials and chrome animation
Implementation of animated effect values via the property system.

Add names for TexEnvCombine attributes
2009-11-13 22:41:11 +01:00
Tim Moore cb07210bc7 Move Texture unit builder into TexBuilder.cxx
Do the refactoring necessary to make that work.
2009-11-13 22:41:11 +01:00
Tim Moore 3e40d624a8 Effects for models
Basically working, at last. Among other things, create effects in
 models loaded directly from .ac files; this can happen, for example,
with the random models from the materials library.
2009-11-13 22:41:11 +01:00
Tim Moore 63ce675914 Splicing visitor for rewriting scene graphs with a minimum of copying 2009-11-13 22:41:11 +01:00
Tim Moore 14e5e87a4d Dump texture attributes of StateSet into effect property tree
Also, decode blend function.
2009-11-13 22:41:11 +01:00
Tim Moore e7e81c6639 getStateAttribute utility function
This provides a concise, typesafe way to get attributes from osg::StateSet.

Also, blew away BackRefInserter.
2009-11-13 22:41:11 +01:00
Tim Moore 23d0601d82 Add support for blend functions and alpha test functions in effects 2009-11-13 22:41:11 +01:00
Tim Moore 6db9138eeb wip for effects in models
multi-index for effect attributes
2009-11-13 22:41:10 +01:00
Tim Moore 6a7c200002 remove CopyPolicy from ModelRegistry
Put the responsibility for copying a loaded model directly in
SGReaderWriterXML.
2009-11-13 22:41:10 +01:00
ehofman e3f70b7125 temporarily remove listener (viewer) and source offsets. they mess things up 2009-11-12 22:59:43 +01:00
Tim Moore a25e859fa7 fix typo 2009-11-10 22:10:57 +01:00
ehofman 5b2af1f6b3 also recalculate the velocity in update_pos_and_orienation, so pass the north-east-down velocity directly and orientate position, orientation and velocity to OpenGL/OpenAL frames (x-right, y-up and z-back) 2009-11-10 16:29:16 +01:00
ehofman 59df72c4b0 allow sound effects in the configuration file to be added to the 'avionics' sample group by setting '<type>avionics</type>'. 2009-11-10 06:42:26 +01:00
Tim Moore 4e2eb2f24c Move propertyExpression code from flightgear to simgear
Also add a function (possibly redundant) to access the global property
root.
2009-11-09 15:53:10 +01:00
Tim Moore b905f4b8aa Property system optimizations
Profiling startup with the new effects code exposed some performance
gotchas. The objective is to reduce allocation of std::string
temporaries, especially when looking up node path names. Also, I
changed some paths to initialize strings with strings instead of char *;
this causes less allocation, at least with glibc. Also, eliminate
the old version of find_node and its helper functions by writing the
template version of find_node_aux to handle an explicit index
parameter.

Also, add const char[] as an internal property type

This doesn't actually add a new type to the property system, but allows using
character arrays as arguments to certain templates.
2009-11-09 15:52:54 +01:00
ehofman fefe87ed1e Remove old MSVC6.0 files that doen't work anymore 2009-11-09 10:45:15 +01:00
ehofman b66905c2f6 Oops, it was the scenery up vector, not the viewer up vector 2009-11-07 08:52:16 +01:00
ehofman 39472e4d81 Save a costly SGVec3d::fromGeod() calculation 2009-11-07 08:52:16 +01:00
ehofman 85fba1325a pass the geodetic position and view orientation to the sky reposition function 2009-11-05 16:17:29 +01:00
ehofman 0f39f05fa1 small fixes 2009-11-04 23:05:22 +01:00
ehofman 8d551c2664 fix directional sound orientation 2009-11-04 23:05:21 +01:00
ehofman 346a22f684 adjust to recent changes 2009-11-04 23:05:21 +01:00
ehofman b1571e4437 some small fixes 2009-11-04 23:05:21 +01:00
ehofman 5ac2abe3ab Remove more unneeded code and properly set relative position and sound direction 2009-11-02 23:20:59 +01:00
ehofman 5b15426cc6 Small code reorganization, mostly removing unneeded code 2009-11-02 23:20:59 +01:00
ehofman 1ac944b7c1 Position and orientation fixes thanks to Tim Moore (finaly). Code optimizations by moving code over from SGSoundSample to SGSampleGroup which means it will only run once for every sample group instead of once for every sample. 2009-11-02 23:20:58 +01:00
ehofman fd90dbb123 silently clip pitch and gain to their maximum values 2009-11-01 21:52:37 +01:00
ehofman 6ccad91537 proper orientation(?) and comment out relative position and direction code since it messes with OpenAL in such a way that volume doesn't work properly anymore 2009-11-01 21:52:37 +01:00
ehofman c89db53ebf another attempt at getting something useful without any result. 2009-10-31 22:55:32 +01:00
ehofman 4ffd70a42a fix a typo 2009-10-31 22:55:26 +01:00
ehofman bbeb48a60d fix a gcc version test 2009-10-31 22:55:18 +01:00
ehofman aefe9bc116 MacOS X fix 2009-10-31 22:54:46 +01:00
ehofman bcb95f647d add relative pos back in 2009-10-31 00:03:27 +01:00
ehofman 145a7fa146 pass the float pointer to the isNaN function instead of the SGVec3 type 2009-10-29 23:04:17 +01:00
ehofman 06f0b6030a multiply quats in the right order 2009-10-29 23:04:17 +01:00
ehofman 191ee3a0ed Commit the current state of affairs to see if it fixes the position code for others 2009-10-29 23:04:17 +01:00
ehofman f6358694ae another test program, using real world locations 2009-10-29 23:04:17 +01:00
ehofman af14d65a98 Fix a bug where a sample was removed from the sample list before it was stopped. Proper listener orientation when inside the airplane (need to find a good solution for outside view). 2009-10-28 23:16:19 +01:00
ehofman 9fe75dc521 also test for NaN in listener code 2009-10-27 22:15:11 +01:00
ehofman 0051bea034 small code reorganization and addition of debugging tests. 2009-10-27 22:15:11 +01:00
ehofman 76c79dba8e FGViewer::recalcLookFrom turned out to be an excellent source of information for prosition and orientation 2009-10-26 23:07:47 +01:00
ehofman 84dc82506a re-enable sound positioning and velocity, test for NaN's and print a message when it happens (debugging, should be removed later on). 2009-10-26 18:50:00 +01:00
ehofman ae1625734c move all isnan() declarations from sample_group.cxx to compiler.h since it's too important not to have available everywhere. 2009-10-26 18:49:57 +01:00
Tim Moore e2ce4c0fa9 More include SGMath.hxx to keep MSVC happy 2009-10-26 18:37:27 +01:00
ehofman a06a15e769 Use shared pointers for any reference to SGSoundSample, fix the constructor of SGSoundSample where data is supplied by the calling program. 2009-10-24 19:29:41 +02:00
ehofman 7c5de29b61 get rid of aut_ptr, it only works with objects that can destroyed with delete (and not even delete[]) which is too limited. take drastic actions to find the sound-not-playing-bug: set all positions and orientations to default all the time. 2009-10-24 19:29:41 +02:00
ehofman 5f9befebae .. and remove some debugging code 2009-10-22 22:52:05 +02:00
ehofman 6a7b885891 revert some test code 2009-10-22 22:52:05 +02:00
ehofman cd8e7bbdca should use free instead of delete for malloced data. 2009-10-22 22:52:05 +02:00
ehofman 5d731ad8c3 a few more temporarty debugging statements 2009-10-22 22:52:05 +02:00
ehofman 7964270929 fix a memory leak and add some temporary debugging statements. 2009-10-22 22:52:05 +02:00
ehofman ea513d392e Updates to the test utilies. 2009-10-22 22:52:05 +02:00
ehofman feba9024eb Fix a pause situation where more code was executed than expected. Unbind an OpenAL buffer from an OpenAL source when requested to stop playing. 2009-10-21 16:25:29 +02:00
ehofman b3e16ce8e0 use auto_ptr instead 2009-10-19 23:50:17 +02:00
ehofman 31dd77c694 do not yet add the relative sound position to the absolute position, it's generating NaN's at the moment. Fix a bunch of other small bugs 2009-10-19 23:50:17 +02:00
ehofman ae58f89fbf sigh, forgot another alut* at the wrong place. 2009-10-19 23:50:17 +02:00
ehofman b3bc36b253 restore some part of the code to prevent an untwanted segmentationf fault. 2009-10-18 18:07:19 +02:00
ehofman 7287509fef Start the sound manager in a deactived state. This means the code now has to activate it explicitly when desired. A non active state means the update function will no be executed. 2009-10-18 18:06:55 +02:00
Tim Moore b1c49045a8 forward declare Point3D in sg_types.hxx
This avoids sucking in SGMath.hxx -- and therefore a bunch of OSG headers --
into many compilation units.
2009-10-18 12:11:13 +02:00
ehofman 0d5634475c Don't delete the sample data if it wasn't constructed as a file. It's now deleted when calling free_data() by the owner or in the destructor. 2009-10-18 12:07:38 +02:00
ehofman e6bfe7d40c revert to previous version 2009-10-18 12:07:25 +02:00
ehofman 811cd0653f make sure update_late isn't executed when dt=0 2009-10-17 23:47:20 +02:00
ehofman e2b8a21ff5 documentation, licensing, copyright and small api updates. 2009-10-17 23:47:06 +02:00
ehofman 24c7941f65 convert _relative_pos to a vector of doubles and set the relative offset 2009-10-17 13:39:34 +02:00
ehofman 600a9ee4c5 _data is not an array of pointer 2009-10-17 13:39:34 +02:00
ehofman fdfdfedf01 Alut < 1.0 fixes and finaly fix the sound orientation 2009-10-17 13:39:33 +02:00
ehofman a67688322d Initialization was done much earlier than expected resulting in some sample
groups not being activated (and sample loading using OpenAL/ALUT functions to
be scheduled before OpenAL was initilialized).

fix alutInit counter
remove left over static declaration fro SGSoundMgr::load
2009-10-16 11:14:05 +02:00
ehofman 6fe057e277 add a debugging statement 2009-10-16 11:14:05 +02:00
ehofman f23e8bfb02 fix for latest changes 2009-10-16 11:14:05 +02:00
ehofman eab9da98f2 give the sample class as much info as possible to properly position and orientate the sounds. unfortunately at this time orientation seems to be from straight behind which means that sounds that have outer-gain set to 0.0 will not be heard yet. 2009-10-16 11:14:05 +02:00
ehofman f161992836 Alex Buzin:
I got an error with the Sunday CVS - FG crashed while exiting .
gdb reports SIGSEGV error at file soundmgr_openal.cxx, line 159.

Error was fixed by changing lines 157-159 from:
        buffer_map_iterator buffers_current = _buffers.begin();
        buffer_map_iterator buffers_end = _buffers.end();
        for ( ; buffers_current != buffers_end; ++buffers_current ) {
to :
        buffer_map_iterator buffers_current;
        while(_buffers.size()){
            buffers_current = _buffers.begin();
2009-10-14 00:34:39 +02:00
Tim Moore 40e13b91fe Merge branches 'toresten/geofix', 'jmt/lcase', 'stuart/clouds' and 'jmt/dump' 2009-10-12 10:03:00 +02:00
ehofman af6824605b proper naming is everything 2009-10-12 00:01:42 +02:00
ehofman babf58f8d2 Correct (and verrified) position, orientation and velocity vector. Todo: proper sound orientation (the all face forward using the airplane orientation now) and disabling doppler effect when tied to the listener 2009-10-12 00:01:07 +02:00
ehofman 968f5d7693 OpenAL buffer management; add a buffer cache to prevent loading the same sample in memory twice. Especially useful to save memory for multi-aircraft configurations and (later) for AI models. 2009-10-12 00:00:53 +02:00
ehofman 4cc6bd69ae add the option to tie a SampleGroup to the listener position and orientation 2009-10-08 10:17:11 +02:00
ehofman 199437e859 alut pre-1.0 doesn't support aletGetError but then again, this function doesn't get called in that case either so just comment it out at build time 2009-10-08 10:17:11 +02:00
jmt e5fac0a01d Update the screen-dump code to use osgDB, and hence write out files in more common formats (PNG, JPEG, etc). The PPM writing code is retained for the moment, in case someone other than FG is relying upon it. 2009-10-07 08:20:50 +02:00
ehofman 5d14b84969 fix a typo 2009-10-07 08:19:47 +02:00
ehofman bcccd06cee (try to) properly align model and viewer 2009-10-07 08:19:33 +02:00
ehofman 6b0ab9a49a default listener (master volume) default to 0.0 to save some ugly code in FlightGear 2009-10-06 07:22:06 +02:00
ehofman 023002ae73 add the alc.h header file vor OpenAL context related code 2009-10-06 07:22:06 +02:00
ehofman 579d384c04 Rename update() to update_late() for the sound manager to be able to initialize it before any other class that uses it. This will allow the SoundManager to be safely accessed in the constructor of those classes. 2009-10-06 07:22:06 +02:00
ehofman e2e1524454 Initial commit of the new sound system, expect more updates to follow 2009-10-06 07:22:06 +02:00
durk 4a5853c1c2 Stuart Buchanan:
Improvements to the cloudsystem:
        - A new xml format
        - Texture indexing based on the position of the sprite in the cloud
          mass, allowing more control over the texture set.
        - Improved fog and shading
        - Better sprite distribution
        - A more natural distribution of clouds, so no more obvious grids.
2009-10-04 01:41:21 +02:00
Tim Moore 64756d14d0 Back out convertToLowerCase function
It brought in an OSG dependency; we'll just use boost::to_lower_copy instead.
2009-10-01 00:31:36 +02:00
Tim Moore bac2ef601d Merge branch 'jmt/lcase' into next 2009-09-28 23:51:07 +02:00
Tim Moore cf3bab89f9 Merge branch 'master' into next 2009-09-28 23:50:56 +02:00
jmt dfe41ad984 Extend simgear::strutils with convertToLowerCase helper - currently a proxy for osgDB helper of the same name. 2009-09-28 23:50:08 +02:00
ehofman b784bebaa9 just small fixes 2009-09-28 23:40:06 +02:00
torsten bcf727cf58 Catch a possible floating point error in SGGeodesy::SGCartToGeod() for cartesian coordinates close to the geocenter region. 2009-09-22 22:44:38 +02:00
Tim Moore ecd0a53412 Add writeLocalData functions for internal scenegraph classes
This makes the scenegraph dump more complete and therefore more useful.
2009-09-22 12:56:28 +02:00
Tim Moore 3456434e37 check for null effect in EffectCullVisitor
An EffectGeode might not have any effect.
2009-09-18 15:43:46 +02:00
Tim Moore 454c5b1ed2 Merge branch 'tat/configure' into next 2009-09-17 12:25:19 +02:00
torsten dc2c437a1a Tatsuhiro Nishioka:
Patches for configure.ac and Makefile.am files in FG/SG so Mac developers can build these in a unix way.
These also enables Mac developers to choose either PLIB framework or PLIB static libs.
2009-09-17 12:24:56 +02:00
Tim Moore 819d3f5ded Merge branch 'topic/projection' into next 2009-09-17 12:22:06 +02:00
frohlich 4f802689f2 Correct finite precision issues.
Use consistent function names.
Implement changes consistently over the different vector sizes.

Modified Files:
	SGVec2.hxx SGVec3.hxx SGVec4.hxx
2009-09-17 12:21:42 +02:00
Tim Moore 9cbbe55598 Merge branch 'frohlich/weak' into next 2009-09-17 12:18:33 +02:00
frohlich 7e2dafdcb8 Make the weak pointer work. Some bits were left when importing.
Modified Files:
	SGSharedPtr.hxx SGWeakPtr.hxx
2009-09-17 12:18:07 +02:00
jmt c7873d68f7 Logging:less verbose sound loading. 2009-09-17 12:13:47 +02:00
jmt 939ec526a8 Logging: quiet down STG parsing. 2009-09-17 12:13:47 +02:00
jmt b20a635db0 Logging: quiet down model/image loading policy. 2009-09-17 12:13:47 +02:00
jmt a656bee0df Logging: quiet the BVH building policy. 2009-09-17 12:13:47 +02:00
jmt 42f07e3f14 Logging: quiet material loading. 2009-09-17 12:13:47 +02:00
jmt 5803b05bd5 Logging - downgrade play/stop messages to debug. 2009-09-17 12:13:47 +02:00
John Denker ccf0ba50c4 Implement vector _projection_ functions. 2009-09-09 23:28:16 +02:00
John Denker f3bc977d32 Make "repeat" start slower on pick-animation mouse events;
otherwise it is unusable.
2009-09-09 22:54:13 +02:00
ehofman 80609e0816 Dont execute code in case the soundmanager isn't properly initialized 2009-09-09 08:39:56 +02:00
frohlich 795d481ca6 Switch to new vector conversion functions.
Modified Files:
	simgear/math/SGGeod.cxx simgear/math/SGQuat.hxx
	simgear/math/SGVec2.hxx simgear/math/SGVec3.hxx
	simgear/math/SGVec4.hxx simgear/scene/material/Effect.cxx
	simgear/scene/model/SGInteractionAnimation.cxx
	simgear/scene/model/SGMaterialAnimation.cxx
	simgear/scene/model/SGRotateTransform.cxx
	simgear/scene/model/SGScaleTransform.cxx
	simgear/scene/model/SGTranslateTransform.cxx
	simgear/scene/model/animation.cxx
	simgear/scene/model/particles.cxx
	simgear/scene/model/placement.cxx
	simgear/scene/model/shadanim.cxx
	simgear/scene/sky/CloudShaderGeometry.cxx
	simgear/scene/sky/cloud.cxx simgear/scene/sky/cloudfield.cxx
	simgear/scene/sky/dome.cxx simgear/scene/sky/sky.cxx
	simgear/scene/tgdb/GroundLightManager.cxx
	simgear/scene/tgdb/SGOceanTile.cxx
	simgear/scene/tgdb/SGTexturedTriangleBin.hxx
	simgear/scene/tgdb/SGVasiDrawable.cxx
	simgear/scene/tgdb/TreeBin.cxx simgear/scene/tgdb/obj.cxx
 	simgear/scene/tgdb/pt_lights.cxx
	simgear/scene/util/SGUpdateVisitor.hxx
2009-09-09 08:39:55 +02:00
frohlich 1b936b9af8 Fix problem with ocean files not recognized as water.
Move dynamic casts to EffectGeode into the findMaterial method.

Modified Files:
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx
	simgear/scene/model/BoundingVolumeBuildVisitor.hxx
2009-09-09 08:39:55 +02:00
frohlich f141cc28b0 Add some comments.
Make sure floating point constants do not introduce useless upcasts.
Remove now unused and not really usefull method.

Modified Files:
	simgear/math/SGQuat.hxx
2009-09-05 17:01:58 +02:00
ehofman 4cb64b58be Also install coremag.hxx since it is being used by JSBSim now 2009-09-05 17:01:58 +02:00
frohlich 028af34d3d Remove unused member.
Modified Files:
	simgear/scene/util/SGSceneFeatures.hxx
2009-09-05 17:01:58 +02:00
frohlich ce54997be5 Should be now more easy to make use of SGMath without having osg.
Modified Files:
	simgear/scene/sky/dome.cxx simgear/math/SGGeod.cxx
	simgear/math/SGGeod.hxx simgear/math/SGQuat.hxx
	simgear/math/SGVec2.hxx simgear/math/SGVec3.hxx
	simgear/math/SGVec4.hxx
2009-09-05 17:01:58 +02:00
frohlich 3d213fa713 Return a osg::Vec value instead of a non const reference.
Modified Files:
 	scene/model/SGMaterialAnimation.cxx
2009-09-05 17:01:58 +02:00
frohlich e71f3790ce Avoid the non const SGVec*::osg() method.
Modified Files:
 	SGTranslateTransform.cxx SGScaleTransform.cxx
 	SGRotateTransform.cxx
2009-09-05 17:01:58 +02:00
frohlich 67b9cba4d3 Use const refs for const data.
Modified Files:
 	simgear/scene/model/CheckSceneryVisitor.hxx
	simgear/scene/model/CheckSceneryVisitor.cxx
2009-09-05 17:01:58 +02:00
torsten 78a471f684 Spare one node in the scenegraph if there is no <offsets> 2009-09-02 23:43:13 +02:00
timoore d4289c5d54 Change trees code to use a faster OpenGL path
The (random) dimensions of a large number of trees is stored in an
array shared by all the tree geodes. The coordinates of the origin of
each tree are replicated in an another array. This allows an entire
block of trees to be rendered with a few OpenGL calls, instead of one
function call per tree.
2009-08-25 16:14:13 +02:00
torsten 0c17c5440a support osgText in models 2009-08-25 09:11:27 +02:00
torsten c4116da564 support osgText in models. See docs/README.osgtext for details 2009-08-25 09:11:27 +02:00
torsten d0821953bb Don't load materials without a name 2009-08-23 21:37:03 +02:00
torsten e782adef94 Avoid NAN due to floating point rounding errors 2009-08-23 21:37:03 +02:00
ehofman d3572c2562 prevent division by zero 2009-08-23 21:37:03 +02:00
torsten 1f3838b155 Alan Teeder: fix incomplete dbg_printf for non-gcc. 2009-08-23 21:37:03 +02:00
torsten 6aa459073e don't build tabbed_value_test, swap_test, openal_test1 and openal_test2 by default. 2009-08-23 21:37:03 +02:00
torsten 0932c33185 warning fix: unused variables 2009-08-23 21:37:03 +02:00
torsten 5e542aa841 extinguish many warnings (at least for gcc) 2009-08-23 21:37:03 +02:00
torsten 6d53abd5af warning fix: initializing members in the order they are declared keeps gcc happy 2009-08-23 21:37:03 +02:00
torsten 3ea58bf8db warning fixes 2009-08-23 21:37:03 +02:00
torsten 71a4c2c3d2 extinguish many warnings (at least for gcc) 2009-08-23 21:37:03 +02:00
torsten a3e391a523 warning fix: abort program and spit out a message if getNumPrims() is called with unknown mode. (Shouldn't happen anyway) 2009-08-23 21:37:02 +02:00
torsten 9cb15b302c warning fix: unused variable 2009-08-23 21:37:02 +02:00
torsten 15c1a28d37 warning fix, unused code 2009-08-23 21:37:02 +02:00
torsten d3a500e54e don't use uninitialized variables 2009-08-23 21:37:02 +02:00
torsten a0a5eb8aef warning fixes 2009-08-23 21:37:02 +02:00
torsten a92955eade warning fixes 2009-08-23 21:37:02 +02:00
torsten f043f3d4f9 warning fixes 2009-08-23 21:37:02 +02:00
torsten 992a057a1b warning fix (multiline comment) 2009-08-23 21:37:02 +02:00
torsten 07da1e7e1a warning fix 2009-08-23 21:37:02 +02:00
torsten 2c07222ef6 warning fixes 2009-08-23 21:37:02 +02:00
torsten 918e315d47 Warning fix: array subscript is above array bounds 2009-08-23 21:37:02 +02:00
ehofman c824731bc6 Expose the color of the sun (which is not the scene specular color anymore) 2009-08-23 21:37:02 +02:00
ehofman 0c39caa622 Differentiate between sun color (based in visibility) and scene color (based on humidity) 2009-08-23 21:37:02 +02:00
torsten 1f1e28baf8 Stuart Buchanan: I've been working on a small patch to allow trees to be grouped together into woods. This allows what seems to me to be a more realistic grouping of trees for farmland in particular. 2009-08-09 23:56:10 +02:00
fredb 0c303389d6 Compile under MSVC9 2009-08-09 23:56:10 +02:00
timoore 01a896ef5b New effects from Till Busch: crops, water, landmass
As shown at LinuxTag, with modifications from Tim Moore: the base
landmass texture is mixed with the steepness and snow effects. Till's
new syntax for textures in effect files was also added. syntax for
textures. Also, syntax for accessing internal textures, such as Till's
3D noise texture, was added.

Several bugs in the effect inheritance algorithm were fixed.
2009-08-09 23:56:10 +02:00
torsten 0e5e760135 Allow multiple <button> elements for <action> elements in pick animations. Nice to have to have a single action for mouse-button and mouse-wheel. 2009-08-08 00:49:40 +02:00
fredb 7e7d877874 Fix case typo 2009-07-27 23:47:15 +02:00
fredb 57ccb6fd6b Suppress warnings 2009-07-27 23:47:15 +02:00
fredb efa2876e29 Compile latest SimGear under MSVC9 2009-07-27 23:47:15 +02:00
Tim Moore 59ef7d8fd1 Create a singleton for the parser table 2009-07-19 23:05:04 +02:00
Tim Moore 1f308c9ec3 Move definition of SGRawBase<...>::printOn out of simgear namespace
They are declared in the global namespace, and MSVC insists that they be
defined there.
2009-07-19 22:39:16 +02:00
Tim Moore 4943d3aa53 Add missing return statements 2009-07-18 10:12:59 +02:00
Tim Moore 828d561113 Store material data with Effect
Somehow this got left out, which broke ground intersection queries.
2009-07-17 16:18:12 +02:00
Tim Moore fcf72a7123 Change references to property types
BOOL, FLOAT etc. conflict with typedefs in windows.h, so these types
are referred to using the props:: namespace.
2009-07-17 14:52:58 +02:00
Tim Moore d3f5bc6e2d Changed SGRawValue::DefaultValue to an inline function.
This avoids MSVC bugs in declaring templated specializations of static members.
2009-07-17 11:40:36 +02:00
Tim Moore f525a05be8 Use SGAtomic's compareAndExchange instead of a new SGSwappable class
Also, eliminate the __declspec(32) of that class which is causing problems
in osg::buffered_object.
2009-07-17 00:29:48 +02:00
Tim Moore fc7ec4299e include file change to make simgear work with OSG 2.9.X again 2009-07-16 23:09:10 +02:00
Tim Moore 21d053b1b6 Fix effects code to work with OSG 2.8.2-rc4 2009-07-16 18:33:27 +02:00
Tim Moore 68e64a5aa7 Use std::back_inserter instead of my local hack
BackRefInsertIterator is probably broken and may not be needed at all.
2009-07-16 13:02:07 +02:00
timoore 8e718fe288 Add new Effects files to vcproj 2009-07-16 12:09:45 +02:00
timoore efec9070e1 Fixes for technique predicates
Get tests based on properties and OpenGL extensions working.
2009-07-16 12:09:44 +02:00
timoore e3646d4d4a more effects features
Materials can specify an effect.

Add support for PolygonMode and initial support for Uniform.
2009-07-16 12:09:44 +02:00
timoore 4219f16f61 Construct effects from property lists
The material code constructs a property list from its input parameters.

Enable dumping of Pass and Technique objects to a file.

Default effect now uses texture node instead of texture0
2009-07-16 12:09:44 +02:00
timoore c3b1802e95 materials use only simgear::Effect
Eliminate SGMaterial::get_state function.

Use Effect in BVH visitor, ocean tile generation, and airport signs.
2009-07-16 12:09:44 +02:00
timoore 40fe078021 Use Effect to implement point lights
This allows different OpenGL features (point sprites, point attenuation) to
be used depending on hardware support.
2009-07-16 12:09:44 +02:00
timoore a5a6600e74 Use SGExpressions for evaluating a Technique's validity 2009-07-16 12:09:44 +02:00
timoore 03b9303f22 Overhaul of SGExpression
Polymorphic additions to expressions: Add an expression base class
with a method for dynamically determining the type of an expression.

Add variables, predicates and boolian expressions.

Support for parsing trees of expressions
2009-07-16 12:09:44 +02:00
timoore b5a59ea6f9 Work in progress for Technique validation 2009-07-16 12:09:44 +02:00
timoore c6b2124129 Use Effects in materials library, and therefore in scenery 2009-07-16 12:09:44 +02:00
timoore d320a6facb Effects framework 2009-07-16 12:09:43 +02:00
timoore 0793c2cb8c Blow away unused SGMaterialLib::add_item functions 2009-07-16 12:09:43 +02:00
timoore d14755abb8 cleanup
Add support for boost::mem_fn to SGSharedPtr.

Remove a couple of "using" declarations from scene/model/model.hxx
2009-07-16 12:09:43 +02:00
timoore abd4aa2e6b Add PropertyList typedef for vectors of property list nodes. 2009-07-16 12:09:43 +02:00
timoore 58417e78e5 Add a method to setStringValue that takes a std::string argument 2009-07-16 12:09:43 +02:00
timoore 390eb1c6e9 Don't cache results of getDisplayName
Return a std::string result instead of char *.
2009-07-16 12:09:43 +02:00
timoore d4c6530a72 Add VEC3D and VEC4D property types
Add "extended" argument to readProperties, which controls whether the vector
 property types are accepted by the XML reader.
2009-07-16 12:09:43 +02:00
timoore ff17b44a41 Extend properties to support new property types.
An SGRawBase class has been added as a base class to the SGRawValue
hierarchy so that SGPropertyValue functions don't necessarily need to
know the type of the value stored in the node.

A new SGRawValueContainer class stores properties that shouldn't be
stored in the node itself. PropertyTraits indicates if a type is
stored in the property node or externally.

Add getValue and SetValue template member functions to SGPropertyNode.

Read and write new extended properties.

Rearrange props.hxx a bit so that the template magic actually works.

Split out extended raw value virtual functions into a seperate base class.

SGRawExtended is chosen as a base class of SGRawValue for extended property
types.
2009-07-16 12:09:43 +02:00
timoore 5bd2d47571 Cleanup of properties
Change most uses of the SGPropertyNode _value union to use static_cast.

Move SGPropertyNode::Type out of the class into simgear::props namespace. Add
a PropertyTraits class so that templates can calculate the property type tag
based on a C++ type.

In destructor, delete _value.val if it is not 0 (and the property is not
aliased).
2009-07-16 12:09:43 +02:00
fredb f8e475cd34 Refactor GLX only debug code 2009-07-15 12:50:49 +02:00
fredb a05e063949 Compile when not GLX 2009-07-12 00:52:07 +02:00
ehofman eb06a90109 Geoff McLane:
add a bunch of debugging code to find a persistant bug for Atlas/Map and fix them one by one.
2009-07-12 00:52:07 +02:00
fredb e2f6632fee Support MSVC 64-bit architecture 2009-07-02 08:51:12 +02:00
fredb 5c5c583dcc Add MSVC90 (VS2008) project files 2009-07-02 08:51:12 +02:00
fredb 0d8d5c02d0 Update MSVC 7.1 projects - Put PLIB and FLTK in 3rdParty 2009-07-02 08:51:12 +02:00
frohlich 382e0c6ad2 Remove unneeded explicit scenegraph deletion.
Modified Files:
	simgear/scene/tgdb/TileCache.cxx
 	simgear/scene/tgdb/TileEntry.cxx
	simgear/scene/tgdb/TileEntry.hxx
2009-07-02 08:51:12 +02:00
fredb a8d1c44408 Remove unmaintained, outdated and misleading project files. Use VC7.1 projects instead 2009-07-02 08:51:12 +02:00
fredb 78b4318c34 Suppress warnings 2009-07-02 08:51:12 +02:00
fredb b47031a099 Win32 fix 2009-07-02 08:51:12 +02:00
frohlich 0f7b65a921 Provide a thread safe SGWeakPtr implementation.
Extend SGAtomic with atomic exchange and add.
Import updates from the original implementation of that in OpenFDM.

Modified Files:
 	Makefile.am SGAtomic.cxx SGAtomic.hxx SGReferenced.hxx
 	SGSharedPtr.hxx
Added Files:
 	SGWeakPtr.hxx SGWeakReferenced.hxx
2009-06-25 10:13:03 +02:00
fredb 33f7903aeb Update MSVC 7.1 projects 2009-06-25 10:13:02 +02:00
fredb f3c2740917 Win32 fix 2009-06-25 10:13:02 +02:00
frohlich 09a57c7a52 No observed_ptr needed.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
2009-06-25 10:13:02 +02:00
frohlich 9068f0606e Remove unused headers.
Modified Files:
	simgear/scene/tgdb/TileEntry.cxx
2009-06-25 10:13:02 +02:00
frohlich c577b7e369 Propagate the lanel loader through the options.
Modified Files:
	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-25 10:13:02 +02:00
frohlich 5850464ba7 Move the carrier interactive geometry configuration into the model files.
Modified Files:
	Makefile.am animation.cxx
Added Files:
	SGInteractionAnimation.hxx SGInteractionAnimation.cxx
2009-06-23 10:42:42 +02:00
ehofman 50e240d5e4 Move the texture code to FlightGear/utils/Modeller 2009-06-23 10:42:42 +02:00
frohlich 75c2a45b25 Add some trailing spaces ...
Modified Files:
 	./simgear/math/SGIntersect.hxx
2009-06-23 10:42:42 +02:00
jmt c958d63897 Fix a warning from GCC - 'ALIAS' was unhandled in the switch stmt. 2009-06-23 10:42:42 +02:00
Tim Moore b633b8d0d3 change MAX_PATH to max_path to avoid Windows compilation problems 2009-06-17 11:37:21 +02:00
Tim Moore 76948416a9 overhaul sg_throwable to behave like a proper exception
Make sg_throwable inherit from std::exception.

change exception objects to contain C strings: exception objects should not
include objects, like std::string, whose copy constructor could throw.
2009-06-16 11:11:13 +02:00
fredb f4a527c57c Add a simple class to subdivide Bezier curves 2009-06-15 10:23:22 +02:00
fredb c491baff0e Remove unused variable 2009-06-15 10:23:21 +02:00
frohlich 6d05fc6f57 Finally get rid of that member in the SGModelData callback.
Move call of SGModelData::modelLoaded directly into the xml reader.

Modified Files:
 	simgear/scene/model/SGPagedLOD.cxx
 	simgear/scene/model/modellib.hxx
 	simgear/scene/model/modellib.cxx
 	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-15 10:23:21 +02:00
frohlich ca53add820 Mark static transforms as static.
Modified Files:
	simgear/scene/tgdb/TileEntry.cxx
2009-06-15 10:23:21 +02:00
frohlich 6fe3099ab4 Revert a change from 2009/06/07.
Should make the Nasal code for some xml models work again.

Modified Files:
 	simgear/scene/model/SGPagedLOD.cxx
	simgear/scene/model/SGReaderWriterXML.cxx
 	simgear/scene/model/modellib.cxx
	simgear/scene/model/modellib.hxx
2009-06-15 10:23:21 +02:00
frohlich a34eceb327 Also handle PagedLOD nodes frame count in the update visitor.
Modified Files:
 	simgear/scene/util/SGUpdateVisitor.hxx
2009-06-11 15:55:12 +02:00
frohlich c9042c3186 Also test against bounds when updating the scene.
Modified Files:
	simgear/scene/util/SGUpdateVisitor.hxx
2009-06-11 15:55:12 +02:00
jmt b46fe0d51c Fix waypoint test, thanks Martin. 2009-06-11 15:55:12 +02:00
jmt 6d1d3173fe Extend SGWaypoint with track and speed data, and compute tracks with the
distance in SGRoute.
2009-06-11 15:55:12 +02:00
fredb 030d044d03 Win32 fix 2009-06-11 15:55:12 +02:00
jmt 29fb8e0f74 Fix bad interaction between CourseAndDistance overloads and use of implicit
SGWaypoint construction from SGGeod.
2009-06-11 15:55:11 +02:00
jmt 6e326976d5 Update route/waypoint tests for revised API 2009-06-11 15:55:11 +02:00
jmt 03a7d72a62 Change SGWaypoint to use SGGeod internally. Remove some unused code, to
support cartesian waypoints and compute distance off a cartesian route.
Add a helper to access the total route distance.

Should not cause any visible functionality change.
2009-06-11 15:55:11 +02:00
frohlich f913febd71 More cleanup.
Modified Files:
	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-11 15:55:11 +02:00
frohlich daa0fbdc6b Do not modify danymically generated textures.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
2009-06-11 15:55:11 +02:00
frohlich d4c52b599d Provide something more sensible for the properties root
for the modelLoaded call. MAy be this needs to be revisited, but in any
case better than constant zero.

Modified Files:
 	simgear/scene/model/SGPagedLOD.cxx
	simgear/scene/model/modellib.cxx
2009-06-11 15:55:11 +02:00
frohlich ec88373eb7 Cleanup.
Modified Files:
	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-11 15:55:11 +02:00
frohlich 4286cafdeb Doing the compilers job: constant propagation.
This variable is nowhere set except to zero.

Modified Files:
	model/SGPagedLOD.cxx model/SGReaderWriterXML.cxx
	model/modellib.cxx model/modellib.hxx
2009-06-11 15:55:11 +02:00
frohlich 3880d8e2f2 Slight cleanup.
Remive last reference to plibs file utility library.

Modified Files:
 	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-11 15:55:11 +02:00
frohlich 671c84ad44 Remove unused header.
Modified Files:
	simgear/scene/tgdb/TileEntry.cxx
2009-06-11 15:55:11 +02:00
frohlich a0d687bb24 Use osgDB::FileUtils instead of plib file utils.
Modified Files:
 	simgear/scene/material/mat.cxx
2009-06-11 15:55:10 +02:00
frohlich 704385ff0a Replace SGPlacementTrans usage with osg::PositionAttitueTransform.
Remove SGPlacementTrans.
Update build system.

Modified Files:
	SimGear.dsp projects/VC7.1/SimGear.vcproj
	projects/VC8/SimGear.vcproj simgear/scene/model/Makefile.am
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
	simgear/scene/tgdb/TileEntry.cxx
	simgear/scene/tgdb/TileEntry.hxx
Removed Files:
 	simgear/scene/model/placementtrans.cxx
 	simgear/scene/model/placementtrans.hxx
2009-06-11 15:55:10 +02:00
frohlich 81a657edec Use osg's builtin mechanisms to traverse only in range nodes with the
update visitor.

Modified Files:
	simgear/scene/util/SGUpdateVisitor.hxx
 	simgear/scene/tgdb/TileEntry.cxx
 	simgear/scene/model/placementtrans.cxx
2009-06-11 15:55:10 +02:00
frohlich 9d0bad29c0 Invent a property root if not given in the options struct.
Modified Files:
	simgear/scene/model/SGReaderWriterXML.cxx
2009-06-03 23:43:45 +02:00
ehofman 2fb8e32104 test for addChild also 2009-06-03 00:08:05 +02:00
ehofman c522e499b2 find the last index instead of the last pos for addChild 2009-06-03 00:08:05 +02:00
frohlich 4700955480 Avoid empty search path extensions for the case that only the bucket index
number is given.

Modified Files:
	scene/tgdb/TileEntry.cxx
2009-06-03 00:08:05 +02:00
frohlich 2c66081fa4 When loading stg files honour the original path if given.
Modified Files:
	simgear/scene/tgdb/ReaderWriterSTG.cxx
	simgear/scene/tgdb/TileEntry.cxx
	simgear/scene/tgdb/TileEntry.hxx
2009-06-03 00:08:05 +02:00
frohlich 855e88da43 Enable stg loading by filename.
Modified Files:
	simgear/scene/tgdb/ReaderWriterSTG.cxx
2009-06-03 00:08:05 +02:00
mfranz ad302db9a8 segfault-- 2009-06-03 00:08:04 +02:00
frohlich bfa5fff500 Cleanup.
Additional null pointer checks.
Simplify redundant interface arguments.

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/ReaderWriterSTG.cxx
	simgear/scene/tgdb/SGReaderWriterBTG.cxx
	simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx
	simgear/scene/tgdb/TileEntry.cxx
	simgear/scene/tgdb/TileEntry.hxx simgear/scene/tgdb/obj.cxx
2009-06-03 00:08:04 +02:00
frohlich 01c64fd554 Give the models properties as an argument to the init callback.
Modified Files:
 	SGPagedLOD.cxx
2009-06-03 00:08:04 +02:00
mfranz 13a2b92a32 remove duplicated header entry 2009-05-19 23:53:25 +02:00
frohlich 29e79f8f61 Also note the btg reader header in the build system.
Modified Files:
	scene/tgdb/Makefile.am
2009-05-19 23:53:24 +02:00
frohlich 8f7527ede0 Restore the special capability of the btg reader to read compressed files.
Modified Files:
 	scene/tgdb/SGReaderWriterBTG.cxx
 	scene/tgdb/SGReaderWriterBTG.hxx
2009-05-19 23:53:24 +02:00
frohlich 7cd149a4d8 Implement current osgDB::ReaderWriters supportsExtension interface instead
of the previous one.

Modified Files:
 	model/SGReaderWriterXML.cxx model/SGReaderWriterXML.hxx
 	tgdb/ReaderWriterSTG.cxx tgdb/ReaderWriterSTG.hxx
 	tgdb/SGReaderWriterBTG.cxx tgdb/SGReaderWriterBTG.hxx
2009-05-19 23:53:24 +02:00
frohlich e45912fd8a Attach the ModelData to the options instead of the userdata field.
Modified Files:
	simgear/scene/model/SGPagedLOD.cxx
	simgear/scene/model/SGReaderWriterXML.cxx
2009-05-19 23:53:24 +02:00
ehofman 56c4ba67c6 * Add a function to create a node after the laste node with the same name
(this frees the xml property loader from keeping track of the number of
    nodes with the same name that have already been added to the property
    tree).
 * make some small code cleanups at the core of the property tree.
2009-05-18 00:36:46 +02:00
Tim Moore 7e7ce2f38e Merge branch 'maint' into next 2009-05-18 00:34:06 +02:00
frohlich 7dc9eba2d0 Make SimGear compile with osg trunk
Modified Files:
	simgear/scene/model/SGPagedLOD.cxx
 	simgear/scene/model/SGPagedLOD.hxx
 	simgear/scene/sky/cloud.cxx simgear/scene/sky/moon.cxx
	simgear/structure/OSGVersion.hxx
2009-05-16 16:18:54 +02:00
mfranz f91d96b51a - fix one broken #include path (in a not usually compiled test app)
- turn four #include paths from the "foo" form to <foo>

The quotes form is normally only used for headers with path relative
to the including file's path, though the standard doesn't strictly
mandate this. This is consistent with the rest of sg, it makes the
code's intent clearer and helps to find headers. (And it's a few
milliseconds faster, too.)
2009-05-16 16:18:37 +02:00
mfranz bc19609147 tcpserver: typo 2009-05-16 16:17:39 +02:00
mfranz 1ccaf3a0bd fix leaks 2009-05-16 16:17:39 +02:00
ehofman 03bfd829da add a bit of comment 2009-05-02 00:40:09 +02:00
fredb e1f7a1e0a0 Stuart Buchanan :
This patch changes the shader so the diffuse light element is applied based on the co-linearity of the light vector and the viewing vector. I think this makes sense, as the tree textures don't represent a surface themselves.
2009-05-02 00:40:09 +02:00
ehofman ceeac0ecf0 Revert most of the previous patch, it didn't improve the dome since it wat adjusting the wrong bads 2009-04-15 23:03:07 +02:00
frohlich c9d0eac739 Put some annotations into the loaded models names.
Modified Files:
	simgear/scene/model/modellib.cxx
2009-04-15 23:03:07 +02:00
frohlich 8f24d924ee Remove a newline printf, probably left over from development.
Modified Files:
	dome.cxx
2009-04-15 23:03:07 +02:00
ehofman 8537cc9edf Let the fog color transition into the sky dome to give a more natural effect 2009-04-15 23:03:07 +02:00
ehofman 58f3985567 Fix a NaN at higher altitudes: sin_beta could become greater than 1.0 which is hard to understand for asin. 2009-04-15 23:03:07 +02:00
frohlich 872db67f21 Remove unused variables.
Modified Files:
	simgear/bucket/newbucket.hxx
2009-04-15 23:03:07 +02:00
Tim Moore 006f90997a Merge branch 'maint' into next 2009-03-31 00:04:30 +02:00
torsten 26b4776394 fix wrong bucket calculation for western hemisphere, close to poles, full-degree-longitude calculations.
set_bucket computed false left border, if the span was greater than 1, longitudes were less than zero
and longitudes were within SG_EPSILON on a full degree. Example: -179.0, +87.5 returned -176, 87
but should return -180, 87.
Discovered by Brian Schack
2009-03-30 18:43:39 +02:00
frohlich 66c64459e6 Makes more sense to process the orientation in this order.
Modified Files:
	simgear/scene/model/placement.cxx
2009-03-30 18:42:45 +02:00
frohlich dc8657f57f Clean up placementtrans a bit.
Modified Files:
 	simgear/scene/model/placement.cxx
 	simgear/scene/model/placementtrans.cxx
	simgear/scene/model/placementtrans.hxx
2009-03-30 18:42:45 +02:00
frohlich 9d647b90e0 Zap aliasing compiler warnings.
Modified Files:
 	simgear/io/lowlevel.cxx
2009-03-30 18:42:45 +02:00
frohlich f5730c950b Remove second, identical to the first one license header.
Modified Files:
 	simgear/scene/model/SGScaleTransform.cxx
2009-03-30 18:42:45 +02:00
frohlich 15d37daebd Remove unused header.
Modified Files:
	simgear/scene/tgdb/TileEntry.cxx
2009-03-30 18:42:45 +02:00
frohlich 795c9876af Make it compile with gcc-4.4.
Modified Files:
	simgear/debug/logstream.hxx
2009-03-30 18:42:45 +02:00
frohlich 45f653167d Make use of optimized matrix multiplication routines in osg.
Modified Files:
	simgear/scene/model/SGTranslateTransform.cxx
2009-03-30 18:42:45 +02:00
frohlich 403d9b6ac1 No longer change the material properties for ac models on the fly.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
2009-03-30 18:42:45 +02:00
frohlich 722af5f659 Cleanup. Use already structured data instead of copying stuff. 2009-03-18 07:53:51 +01:00
frohlich 471b9f02ec Add const accessors.
Modified Files:
	simgear/ephemeris/ephemeris.hxx
2009-03-18 07:53:51 +01:00
frohlich fd294b6f98 Make sure the boundingvolumes for the btg files are as high as possible
in the scenegraph.

Modified Files:
	simgear/scene/tgdb/SGReaderWriterBTG.cxx
2009-03-18 07:53:51 +01:00
frohlich 88baaa72be Use triangle sphere intersection directly.
Modified Files:
	simgear/scene/bvh/BVHSubTreeCollector.cxx
2009-03-18 07:53:50 +01:00
frohlich 61084cf1ba Make triangle sphere intersection tests usable with mixes types.
Modified Files:
	simgear/math/SGIntersect.hxx
2009-03-18 07:53:50 +01:00
frohlich 5b63f0755a Preparations for improoved timing behaviour.
Modified Files:
	simgear/scene/bvh/BVHMotionTransform.cxx
	simgear/scene/bvh/BVHMotionTransform.hxx
	simgear/scene/bvh/BVHSubTreeCollector.cxx
2009-03-18 07:53:50 +01:00
frohlich 9eb5cf6c98 Add a reference time to the velocity stuff.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
	simgear/scene/util/SGSceneUserData.hxx
2009-03-18 07:53:50 +01:00
frohlich 679db5a22b The chunked stuff is no longer needed for the ground tiles.
... I (Mathias Froehlich), believe that it is more performant (for the GPU) to
build the biggest indexed sets possible at the expense of tight culling.
I (Mathias Froehlich) also know that the CPU is more performant on smaller chunks
building the old flat groundcache on such tiles. :)
So this code *was* to balance these two contrary requirements to some degree.

Now we have optimized datastructures for drawing and differently optimized
datastructures for intersection tests.


Modified Files:
	simgear/scene/tgdb/obj.cxx
2009-03-18 07:53:50 +01:00
frohlich 0e35168bdb Also align the ocean tiles with some horizontal axis.
This way the bounding boxes for this geometry is slightly smaller.
Helps ground intersection stuff to avoid the ocean triangles earlier.

Modified Files:
	simgear/scene/tgdb/SGOceanTile.cxx
2009-03-18 07:53:50 +01:00
frohlich 035dcc7ab7 Improove bounding volume building in the scenery loading process.
Refactor common code in the BoundingVolumeBuildVisitor.hxx.

Modified Files:
	simgear/scene/model/BoundingVolumeBuildVisitor.hxx
	simgear/scene/model/ModelRegistry.cxx
	simgear/scene/model/ModelRegistry.hxx
2009-03-18 07:53:50 +01:00
frohlich 252deed5b9 Make the debug geometry stuff work with a time argument.
Modified Files:
	simgear/scene/bvh/BVHDebugCollectVisitor.hxx
2009-03-18 07:53:50 +01:00
fredb c2c4cad753 Compile under windows 2009-03-18 07:53:50 +01:00
frohlich 42e76477cf Make sure each carrier gets its own valocity.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
2009-03-18 07:53:50 +01:00
mfranz 1eade74e5a warning-- 2009-03-18 07:53:50 +01:00
frohlich f1f0fa0aa9 Make use of posix clocks if available.
Have a more general timestamp implementation.
Very useful for higher accuracy timings.

Modified Files:
	simgear/structure/subsystem_mgr.cxx
	simgear/structure/subsystem_mgr.hxx
	simgear/timing/testtimestamp.cxx simgear/timing/timestamp.cxx
	simgear/timing/timestamp.hxx
2009-03-18 07:53:49 +01:00
frohlich deef158822 Use a reference counted pointer for the condition.
Modified Files:
	simgear/sound/xmlsound.hxx simgear/sound/xmlsound.cxx
2009-03-11 20:06:57 +01:00
frohlich fef2006663 Remove unused methods.
Modified Files:
	material/matmodel.hxx material/matmodel.cxx
2009-03-11 20:06:57 +01:00
frohlich 5c97fd576a Make local functions static.
Modified Files:
	model/SGReaderWriterXML.cxx
2009-03-11 20:06:56 +01:00
frohlich c4eb6b7b65 Remove unused functions/includes ...
Modified Files:
	simgear/scene/tgdb/userdata.hxx
	simgear/scene/tgdb/userdata.cxx
2009-03-11 20:06:56 +01:00
frohlich 31324761cc Zap SGLocation.
Modified Files:
 	projects/VC7.1/SimGear.vcproj projects/VC8/SimGear.vcproj
 	simgear/scene/model/Makefile.am
	simgear/scene/model/placement.cxx
 	simgear/scene/model/placement.hxx
Removed Files:
 	simgear/scene/model/location.cxx
	simgear/scene/model/location.hxx
2009-03-11 20:06:56 +01:00
frohlich e495f03ee9 Ignore winding order since it is ignored later anyway.
Only emit fully defined primitives.

Modified Files:
	simgear/scene/model/BoundingVolumeBuildVisitor.hxx
2009-03-11 20:06:56 +01:00
frohlich f5769627e4 Use SGGeod in the model placement.
Modified Files:
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
2009-03-11 20:06:56 +01:00
frohlich 06ad73f85b Add convenience function to keep position with just an other elevation.
Modified Files:
	simgear/math/SGGeod.hxx
2009-03-11 20:06:56 +01:00
frohlich fa20363853 First step for something doing static friction stuff.
Add an id field to identify BVHMotionTransforms.
Provide a factory for ids.
Use that to identify velocity data.
Track the lowermost id in the visitors.

Modified Files:
	simgear/scene/bvh/BVHLineSegmentVisitor.cxx
	simgear/scene/bvh/BVHLineSegmentVisitor.hxx
 	simgear/scene/bvh/BVHMotionTransform.cxx
	simgear/scene/bvh/BVHMotionTransform.hxx
	simgear/scene/bvh/BVHNearestPointVisitor.hxx
	simgear/scene/bvh/BVHNode.cxx simgear/scene/bvh/BVHNode.hxx
	simgear/scene/util/SGSceneUserData.cxx
	simgear/scene/util/SGSceneUserData.hxx
2009-03-05 10:32:06 +01:00
frohlich 2564432e71 Avoid duplicate triangles.
Modified Files:
	simgear/scene/bvh/BVHStaticGeometryBuilder.hxx
2009-03-05 10:32:06 +01:00
frohlich addf47600d Remove the StaticLeaf visitor slot.
Add a nearest point visitor.

Modified Files:
	BVHBoundingBoxVisitor.hxx BVHDebugCollectVisitor.hxx
	BVHLineSegmentVisitor.cxx BVHLineSegmentVisitor.hxx
	BVHStaticGeometryBuilder.hxx BVHStaticLeaf.cxx
	BVHStaticLeaf.hxx BVHSubTreeCollector.cxx
	BVHSubTreeCollector.hxx BVHVisitor.hxx Makefile.am bvhtest.cxx
Added Files:
	BVHNearestPointVisitor.hxx
2009-03-05 10:32:06 +01:00
frohlich 7f534a7966 Crude hack to work around my today introduced collision tree sharing problem.
Modified Files:
	simgear/scene/model/ModelRegistry.cxx
2009-03-05 10:32:06 +01:00
frohlich eabffece1f Don't waste space with too huge stl containers.
Modified Files:
	simgear/scene/bvh/BVHStaticGeometryBuilder.hxx
2009-03-05 10:32:06 +01:00
frohlich afed842ad1 Don't waste space with too huge stl containers.
Modified Files:
	simgear/scene/bvh/BVHStaticData.hxx
2009-03-05 10:32:06 +01:00
fredb c46cfb5d47 Win32 fix 2009-03-05 10:32:06 +01:00
frohlich 34fe42bbd9 Build boundingvolumes in the model loading phase.
Modified Files:
	ModelRegistry.hxx ModelRegistry.cxx
Added Files:
	BoundingVolumeBuildVisitor.hxx
2009-03-05 10:32:06 +01:00
fredb 0c1d96b749 Update MSVC 7.1 projects - Add the BVH library 2009-03-05 10:32:06 +01:00
fredb 9b67f52d56 SGMatrix<T>::preMultTranslate should return self ( as postMultTranslate do ) 2009-03-05 10:32:06 +01:00
fredb d37907d35d BVHLineSegmentVisitor::setLineSegmentEnd doesn't return anything 2009-03-05 10:32:05 +01:00
frohlich fee8d0cf78 Implement setters for velocity notes in the model placement code.
Modified Files:
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
2009-03-05 10:32:05 +01:00
frohlich f5f9c6b81f More data to attach to the user data field.
Modified Files:
 	simgear/scene/util/SGSceneUserData.hxx
2009-03-05 10:32:05 +01:00
frohlich 4e3460a34b Include the bounding volume tree on the build system.
Modified Files:
 	configure.ac simgear/scene/Makefile.am
2009-03-05 10:32:05 +01:00
frohlich 8545b6ce6b Initial commit of the bounding volume tree implementation.
The aim is to prove a better collion model in plenty ways.

Added Files:
 	.cvsignore BVHBoundingBoxVisitor.hxx
	BVHDebugCollectVisitor.hxx BVHGroup.cxx BVHGroup.hxx
	BVHLineGeometry.cxx BVHLineGeometry.hxx
	BVHLineSegmentVisitor.cxx BVHLineSegmentVisitor.hxx
	BVHMotionTransform.cxx BVHMotionTransform.hxx BVHNode.cxx
	BVHNode.hxx BVHStaticBinary.cxx BVHStaticBinary.hxx
	BVHStaticData.hxx BVHStaticGeometry.cxx BVHStaticGeometry.hxx
	BVHStaticGeometryBuilder.hxx BVHStaticLeaf.cxx
	BVHStaticLeaf.hxx BVHStaticNode.cxx BVHStaticNode.hxx
	BVHStaticTriangle.cxx BVHStaticTriangle.hxx
 	BVHSubTreeCollector.cxx BVHSubTreeCollector.hxx
	BVHTransform.cxx BVHTransform.hxx BVHVisitor.hxx Makefile.am
	bvhtest.cxx
2009-03-05 10:32:05 +01:00
frohlich e417903c23 Additions for the boundingvolumes
Modified Files:
	SGGeometryTest.cxx SGIntersect.hxx SGLineSegment.hxx
	SGTriangle.hxx
2009-03-05 10:32:05 +01:00
frohlich 81eae3fa48 Rotate the scenery tiles so that the horizont is axis aligned.
This might help culling and much more the upcomming collision tree.

Modified Files:
	simgear/scene/tgdb/obj.cxx
2009-02-27 23:34:15 +01:00
frohlich 90c58087e8 Make material get helper function static.
Modified Files:
 	simgear/scene/material/matlib.cxx
 	simgear/scene/material/matlib.hxx
2009-02-27 23:34:15 +01:00
frohlich 19bc1e6313 Initialize random number for the tests.
Define the triangles center by the weighted sum of the vertices.

Modified Files:
	SGGeometryTest.cxx SGTriangle.hxx
2009-02-27 23:34:15 +01:00
frohlich 4a4e8c87b8 Use template arguments instead of hard coded double.
Modified Files:
	simgear/math/SGTriangle.hxx
2009-02-27 23:34:15 +01:00
frohlich f04e559dc2 Initialize uninitialized variables.
Adapt the precision bounds to what matches the expectations of IEEE math.

Modified Files:
	SGMathTest.cxx
2009-02-27 23:34:15 +01:00
frohlich 8e5e657344 Fix problem in unit quaternion return.
Modified Files:
	SGQuat.hxx
2009-02-27 23:34:15 +01:00
frohlich a4f1f62068 Make make check link again.
Modified Files:
	simgear/math/Makefile.am
2009-02-27 23:34:15 +01:00
frohlich a3e279f06f The scenery center is history for a long time now.
Remove that from the transforms.

Modified Files:
	simgear/scene/model/placement.hxx
	simgear/scene/model/placementtrans.cxx
	simgear/scene/model/placementtrans.hxx
2009-02-22 23:49:45 +01:00
frohlich d11954e80c Small cleanups, bug fixes and improovements to the geometry/math stuff.
Modified Files:
	simgear/math/SGBox.hxx simgear/math/SGIntersect.hxx
	simgear/math/SGLineSegment.hxx simgear/math/SGMatrix.hxx
	simgear/math/SGPlane.hxx simgear/math/SGRay.hxx
	simgear/math/SGSphere.hxx simgear/math/SGVec2.hxx
	simgear/math/SGVec3.hxx simgear/math/SGVec4.hxx
2009-02-22 23:49:45 +01:00
durk 812170ebce Torsten Dreyer: the rotate animation has two ways to define a axis
1. by using center/x-m and axis/[xyz]
2. by using axis/[xyz]1-m and axis/[xyz]2-m

The translate animation only supports method 1. and here comes a patch that
enables method 2 for this animations, too.
2009-02-22 23:49:45 +01:00
fredb fdd3c77298 Fix to compile with MSC 2009-02-22 23:49:45 +01:00
Tim Moore 342de209a2 Merge branch 'topic/nasal' into next 2009-02-16 00:48:00 +01:00
mfranz caeb32488e "io.flush() implementation from Melchior. Also add a final filetype
element to the io.stat() array, which has been sitting around on my
box for a while and doesn't seem to have broken anything."  -- Andy

(forward port from nasal/cvs)
2009-02-16 00:46:29 +01:00
Tim Moore ff7e70f4d5 Merge branch 'topic/gcintersect' into next 2009-02-13 10:07:15 +01:00
Tim Moore 950f51909c New getPrimitive function.
This searches for the primitive found in an OSG intersection query.
2009-02-13 09:40:05 +01:00
Tim Moore f86e6d344c Make SGSubsystemGroup::Member copy constructor private.
The copy constructor wouldn't make any sense and would confuse ownership of
the subsystem pointer. Problem noted by John Denker.
2009-02-07 00:37:47 +01:00
Tim Moore 08581282dd Merge branch 'topic/cloudz' into next 2009-02-06 19:16:19 +01:00
Tim Moore e1e47e76ec Turn off z buffer writes for clouds.
This is standard practice for semi-transparent objects and should cut down
on the flickering and other sorting artifacts.
2009-02-06 17:48:23 +01:00
fredb 3ff059848c Update MSVC 7.1 projects - Remove pthreads dependency 2009-02-04 11:07:27 +01:00
Tim Moore 22c7df5936 Merge branch 'maint' into next 2009-02-04 11:03:20 +01:00
Tim Moore 81a44d1340 Merge branch 'releng/1.9.1' into maint 2009-02-04 11:02:30 +01:00
durk 2c089e6166 Synchronize the version number with our mainantance release. 2009-02-04 11:01:39 +01:00
Tim Moore 589dae7b0c Build trees under a transform note that is rotated to Z-up.
This allows the tree geometry to be shared across the entire scene because it
doesn't need to be rotated for each scenery tile.
2009-01-30 11:18:08 +01:00
Tim Moore 3ff13189aa Don't expand all the trees into display lists.
This can chew up large amounts of memory for questionable gains. We do
let the tree model geometry be in a display list if OSG chooses to put
it there.

Various renaming and cleanup. Save some memory by reverting
ShaderGeometry's base class back to osg::Drawable.
2009-01-30 11:17:02 +01:00
Tim Moore 7151c3fac1 Merge branch 'topic/yontree' into next 2009-01-28 07:53:38 +01:00
Tim Moore 3e023b77dd Merge branch 'maint' into next 2009-01-28 07:53:31 +01:00
durk e3fc89890c For the first time (no pun intended) in almost ten years time (again no
pun intended) that I'm touching the time library.

 Brian Schack reported that the traffic scheduler messes up the timestamps
 of the atlas network output. As it turns out, the c library functions
 asctime, and gmtime use a static copy of the tm struct to do the internal
 formatting. Our linux port of the SGTime class, incidentally, also stored
 it's master time stamp in this very same struct. Thus, formatting an
 arbitrary time value, would have the unwanted side effect of time travel.
 Usually, this would go unnoticed, because the actual time parameters would
 be updated before any damage could be done. But unwanted side effects, as
 in Brian's example could occur.

 On the MSVC port this appears to not have been a problem. Since that port
 used a copy of the tm struct to store it's master time stamps. Since the
 MSVC code also compiles cleanly on linux, it seems to be the way to go to
 use that approach. In addition, it also removes some conditional compile
 directives.

 I've only run a short test, but didn't see any undesirable side effects.
2009-01-28 07:46:55 +01:00
mfranz ce2a6cfe5c Csaba HALASZ: set _arg even if there's no <command> (crash fix) 2009-01-28 07:46:31 +01:00
Tim Moore 31d9eaf54c Use osg::Geometry code to draw trees ourselves.
This reverts back in the direction of Yon's original patch: the model is
drawn within ShaderGeometry::drawImplementation. This saves a lot of memory
over the previous approach of creating a PrimitiveSet for each model.
2009-01-28 07:43:09 +01:00
Tim Moore 781c445d14 Merge branch 'topic/modelopt' into next 2009-01-23 23:27:48 +01:00
Tim Moore 26a416399f Merge branch 'topic/yontree' into next 2009-01-23 23:27:37 +01:00
Tim Moore f7dc7f039e QuadTreeBuilder: create leaves on demand
This avoids lots of empty leaves.
2009-01-23 19:30:29 +01:00
Tim Moore 3c74fea087 Rewrite ShaderGeometry to use display lists and OSG primitives.
Based on a patch from Yon Uriarte.

Eliminate _trees list from ShaderGeometry

Use the position and scale values that are already available.
2009-01-23 19:29:18 +01:00
Tim Moore be0635bfd3 Optimize empty groups from .ac models
The OSG optimizer seems to have changed since this work was originally done.
2009-01-23 16:11:23 +01:00
Tim Moore 6723ef95c2 Merge branch 'maint' into next 2009-01-19 00:13:07 +01:00
Tim Moore 1a8fd62680 Protect against division by zero in QuadTreeBuilder
This could only happen when there's one leaf in the tree, or all the objects
happen to have the same position. Noticed by Csaba Halaz
2009-01-19 00:04:59 +01:00
Tim Moore 8b57ed46b1 Sort cloud sprites using std::sort, based on projected Z.
A "cleanup" of cloud sorting.
2009-01-16 00:37:40 +01:00
Tim Moore 25c08e56c2 Merge branch 'foo' into next 2009-01-15 22:52:11 +01:00
jmt 0f148b6ab6 Fix linkage of test programs with OpenThreads. 2009-01-15 22:49:00 +01:00
jmt 47575fe357 Commit Benoit Laniel's patch which converts more SimGear pieces to use
OpenThreads primitives directly.
2009-01-15 22:49:00 +01:00
jmt 7c14453b5a Since we're now sure 1.9.1 will not be released from trunk, here's Yon
Uriarte's patch to convert SGReferenced over to OpenThread's atomic int.
2009-01-15 22:49:00 +01:00
Tim Moore a47d5536fa Merge branch 'maint' into next 2009-01-14 22:34:20 +01:00
Tim Moore db8f7f21e8 Remove OptionsPusher and manipulation of osgDB dataFilePathList.
The bug it worked around has been fixed in the OSG ac3d loader, and changing
the path list has unpleasant multithreading implications.
2009-01-14 22:13:12 +01:00
Tim Moore 3c312c55f1 Merge branch 'maint' into next 2009-01-14 12:13:44 +01:00
Tim Moore 2d11419cba SGPropertyNode must increment / decrement the reference counter in an aliased
node.

From Csaba Halász.
2009-01-14 12:10:23 +01:00
Tim Moore 07a4508944 Merge branch 'topic/mat-anim' into next 2009-01-13 22:58:45 +01:00
Tim Moore 62913739bb Merge branch 'maint' into next 2009-01-13 22:52:19 +01:00
Tim Moore 55e9d8d944 SGMaterialAnimation: Don't install an update callback if values are static 2009-01-13 15:35:15 +01:00
Tim Moore a9439d58c7 SGMaterialAnimation: factor out update of osg::Material 2009-01-13 13:15:34 +01:00
fredb 800ad40c4c Csaba/Jester : fix the material animation and display night textures 2009-01-13 10:37:38 +01:00
Tim Moore 62864637a3 Merge branch 'maint' into next 2009-01-12 13:14:31 +01:00
fredb 4d4ac7ea24 fix end of file 2009-01-12 13:13:04 +01:00
fredb 119651482d ignore generated files 2009-01-12 13:12:50 +01:00
timoore ecf0a1a736 Fix include path 2009-01-08 23:06:23 +01:00
jmt 94942d1ac4 Add some syntactic helpers to allow distance/course to be queried between
two geodetic points. This still entails a full _geo_inverse_wgs_84 call,
but makes call sites neater.
2009-01-08 23:05:12 +01:00
jmt b0a5b54949 Fix test-program linkage now sgmath depends on sgstructure. 2009-01-02 23:52:46 +01:00
jmt ac57eab8ac Fix a potential crash when OSG is misconfigured, and an appropriate image
loading plugin cannot be found.
2008-12-26 11:42:04 +00:00
mfranz 74a4144193 compilation fix: <cstring> for strcmp() 2008-12-22 18:01:34 +00:00
mfranz 5c44cb0f01 - shininess is in the rage 0..128
- restore fg/plib compatibility (there is/was no <shininess> group)
  (we may want to change that in the (near?) future, though)
2008-12-21 15:01:11 +00:00
286 changed files with 22417 additions and 12053 deletions
-2720
View File
File diff suppressed because it is too large Load Diff
-29
View File
@@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "SimGear"=".\SimGear.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
+1 -1
View File
@@ -671,7 +671,7 @@ if test "x$want_boost" = "xyes"; then
if test "$_version" = "0" ; then if test "$_version" = "0" ; then
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]]) AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else else
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) AC_MSG_ERROR([Your boost libraries seems to old (version $_version).])
fi fi
else else
AC_SUBST(BOOST_CPPFLAGS) AC_SUBST(BOOST_CPPFLAGS)
+119 -6
View File
@@ -8,7 +8,7 @@ dnl Require at least automake 2.52
AC_PREREQ(2.52) AC_PREREQ(2.52)
dnl Initialize the automake stuff dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 1.9.0) AM_INIT_AUTOMAKE(SimGear, 1.9.1)
dnl Specify KAI C++ compiler and flags. dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution. dnl Borrowed with slight modification from blitz distribution.
@@ -37,7 +37,7 @@ AC_PROG_CXX
AC_PROG_RANLIB AC_PROG_RANLIB
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AX_BOOST_BASE([1.34.0]) AX_BOOST_BASE([1.37.0])
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
@@ -126,6 +126,12 @@ if test "x$with_plib" != "x" ; then
EXTRA_DIRS="${EXTRA_DIRS} $with_plib" EXTRA_DIRS="${EXTRA_DIRS} $with_plib"
fi fi
AC_ARG_WITH(plib_framework, [ --with-plib-framework=PREFIX Specify the prefix path to PLIB.framework ])
if test "x$with_plib_framework" != "x"; then
echo "plib framework prefix is $with_plib_framework"
fi
# specify the osg location # specify the osg location
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg]) AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
@@ -134,6 +140,21 @@ if test "x$with_osg" != "x" ; then
EXTRA_DIRS="${EXTRA_DIRS} $with_osg" EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi fi
AC_ARG_WITH(osg_framework, [ --with-osg-framework=PREFIX Specify the prefix path to OSG.framework ])
if test "x$with_osg_framework" != "x"; then
echo "osg framework prefix is $with_osg_framework"
CPPFLAGS = "$CPPFLAGS -F$with-osg-framework"
export DYLD_FRAMEWORK_PATH="$DYLD_FRAMEWORK_PATH:$with_osg_framework"
fi
dnl specifying OpenAL.framework (for user provided OpenAL.framework / ALUT)
AC_ARG_WITH(openal_framework, [ --with-openal-framework=PREFIX Speicfy the prefix path to OpenAL.framework ])
if test "x$with_openal_framework" != "x"; then
echo "OpenAL framework prefix is $with_openal_framework"
fi
dnl Determine an extra directories to add to include/lib search paths dnl Determine an extra directories to add to include/lib search paths
case "${host}" in case "${host}" in
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*) *-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
@@ -203,6 +224,7 @@ LIBS=""
dnl check for some default libraries dnl check for some default libraries
AC_SEARCH_LIBS(cos, m) AC_SEARCH_LIBS(cos, m)
AC_SEARCH_LIBS(clock_gettime, rt)
base_LIBS="$LIBS" base_LIBS="$LIBS"
@@ -292,9 +314,54 @@ case "${host}" in
LIBS="$LIBS -framework IOKit -framework OpenAL" LIBS="$LIBS -framework IOKit -framework OpenAL"
openal_LIBS="$LIBS" openal_LIBS="$LIBS"
# not sure how to test if OpenAL exists on MacOS (does it come by default?)
OPENAL_OK="yes" OPENAL_OK="yes"
ALUT_OK="yes" ALUT_OK="no"
if test "x$with_openal_lib" != "x"; then
echo "libopenal is not supported on Mac OS platform."
openal_LIBS=""
fi
OPENAL_OK="yes"
# Looking for alut.h, if found assume that it is a part of
# the OpenAL package.
AC_CHECK_HEADERS([OpenAL/alut.h],[ALUT_OK="yes"])
dnl Thank you Christian Bauer from SheepSaver
dnl Modified by Tatsuhiro Nishioka for accepting a given framework path
dnl AC_CHECK_FRAMEWORK($1=NAME, $2=INCLUDES, $3=FRAMEWORK_PATH) ; $3 is optional
AC_DEFUN([AC_CHECK_FRAMEWORK], [
AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1])dnl
AC_CACHE_CHECK([whether compiler supports framework $1],
ac_Framework, [
saved_LIBS="$LIBS"
FRAMEWORKS="$FRAMEWORKS -framework $1"
if test "$3" = ""; then
FRAMEWORKS="$FRAMEWORKS $ADD2LD"
elif test "`echo $FRAMEWORKS | grep -- -F$3`" = ""; then
FRAMEWORKS="$FRAMEWORKS -F$3"
CXXFLAGS="$CXXFLAGS -F$3"
CCFLAGS="$CCFLAGS -F$3"
dnl This is needed for AC_TRY_LINK when a framework path is specified
export DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH}:$3"
fi
AC_TRY_LINK(
[$2], [],
[AS_VAR_SET(ac_Framework, yes)], [AS_VAR_SET(ac_Framework, no); LIBS="$saved_LIBS"]
)
])
AS_IF([test AS_VAR_GET(ac_Framework) = yes],
[AC_DEFINE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 1, [Define if framework $1 is available.])]
)
AS_VAR_POPDEF([ac_Framework])dnl
])
dnl Check for OpenAL.framework when --with-openal-framework is specified
dnl Of cource OpenAL.framework needs to have alut.h
if test "x$with_openal_framework" != "x"; then
AC_CHECK_FRAMEWORK(OpenAL, [#include <OpenAL/alut.h>], $with_openal_framework)
fi
;; ;;
*) *)
@@ -351,9 +418,23 @@ AM_CONDITIONAL(EXTGL_NEEDED, test "x$ac_cv_header_windows_h" = "xyes")
# The following are C++ items that need to be tested for with the c++ # The following are C++ items that need to be tested for with the c++
# compiler # compiler
CXXCPP="g++ -E"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
dnl Check for "plib" without which we cannot go on dnl Check for "plib" without which we cannot go on
case ${host} in
*-apple-darwin*)
# Check PLIB framework availability when with-plib-framework is specified
if test "x$with_plib_framework" != "x"; then
AC_CHECK_FRAMEWORK(PLIB, [#include <plib/ul.h>], $with_plib_framework)
plib_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(plib_FRAMEWORK)
fi
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_PLIB, test "x$ac_cv_framework_PLIB" != "x")
AC_CHECK_HEADER(plib/ul.h) AC_CHECK_HEADER(plib/ul.h)
if test "x$ac_cv_header_plib_ul_h" != "xyes"; then if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
echo echo
@@ -373,8 +454,6 @@ AC_TRY_RUN([
#define MIN_PLIB_VERSION 185 #define MIN_PLIB_VERSION 185
int main() { int main() {
int major, minor, micro;
if ( PLIB_VERSION < MIN_PLIB_VERSION ) { if ( PLIB_VERSION < MIN_PLIB_VERSION ) {
return -1; return -1;
} }
@@ -391,8 +470,40 @@ int main() {
LIBS="$saved_LIBS" LIBS="$saved_LIBS"
# OpenSceneGraph
case "${host}" in
*-apple-darwin*)
if test "x$with_osg_framework" != "x"; then
AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
osg_FRAMEWORKS="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(osg_FRAMEWORKS)
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
openthreads_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(openthreads_FRAMEWORK)
else
dnl
dnl This is needed when osg dynamic libs are specified
dnl instead of OSG frameworks on Mac OS X
dnl
LDFLAGS="$LDFLAGS -L$with_osg"
fi
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
AC_CHECK_HEADER(osg/Version) AC_CHECK_HEADER(osg/Version)
if test "x$ac_cv_header_osg_Version" != "xyes"; then if test "x$ac_cv_header_osg_Version" != "xyes"; then
if test "x$ac_cv_framework_osg" != "xyes"; then
echo echo
echo "You *must* have the OpenSceneGraph support library installed on your system" echo "You *must* have the OpenSceneGraph support library installed on your system"
echo "to build this version of SimGear!" echo "to build this version of SimGear!"
@@ -401,6 +512,7 @@ if test "x$ac_cv_header_osg_Version" != "xyes"; then
echo echo
echo "configure aborted." echo "configure aborted."
exit exit
fi
fi fi
AC_CHECK_HEADER(boost/version.hpp) AC_CHECK_HEADER(boost/version.hpp)
@@ -480,6 +592,7 @@ AC_CONFIG_FILES([ \
simgear/props/Makefile \ simgear/props/Makefile \
simgear/route/Makefile \ simgear/route/Makefile \
simgear/scene/Makefile \ simgear/scene/Makefile \
simgear/scene/bvh/Makefile \
simgear/scene/material/Makefile \ simgear/scene/material/Makefile \
simgear/scene/model/Makefile \ simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \ simgear/scene/sky/Makefile \
+2 -1
View File
@@ -1,4 +1,5 @@
Debug Debug
Release Release
SimGear.ncb SimGear.ncb
SimGear.suo SimGear.suo
*.user
+194 -29
View File
@@ -23,7 +23,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;;..\..\..\boost_1_36_0" AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;..\..\..\boost_1_36_0"
PreprocessorDefinitions="HAVE_CONFIG_H,NDEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS" PreprocessorDefinitions="HAVE_CONFIG_H,NDEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="2" RuntimeLibrary="2"
@@ -75,7 +75,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;;..\..\..\boost_1_36_0" AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;..\..\..\boost_1_36_0"
PreprocessorDefinitions="HAVE_CONFIG_H,_DEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS" PreprocessorDefinitions="HAVE_CONFIG_H,_DEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="3" RuntimeLibrary="3"
@@ -287,6 +287,9 @@
<Filter <Filter
Name="Lib_sgmath" Name="Lib_sgmath"
Filter=""> Filter="">
<File
RelativePath="..\..\simgear\math\beziercurve.hxx">
</File>
<File <File
RelativePath="..\..\simgear\math\interpolater.cxx"> RelativePath="..\..\simgear\math\interpolater.cxx">
</File> </File>
@@ -422,9 +425,6 @@
<File <File
RelativePath="..\..\simgear\screen\colors.hxx"> RelativePath="..\..\simgear\screen\colors.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\screen\colours.h">
</File>
<File <File
RelativePath="..\..\simgear\screen\extensions.cxx"> RelativePath="..\..\simgear\screen\extensions.cxx">
</File> </File>
@@ -461,12 +461,6 @@
<File <File
RelativePath="..\..\simgear\screen\shader.h"> RelativePath="..\..\simgear\screen\shader.h">
</File> </File>
<File
RelativePath="..\..\simgear\screen\texture.cxx">
</File>
<File
RelativePath="..\..\simgear\screen\texture.hxx">
</File>
<File <File
RelativePath="..\..\simgear\screen\tr.cxx"> RelativePath="..\..\simgear\screen\tr.cxx">
</File> </File>
@@ -649,6 +643,15 @@
<Filter <Filter
Name="Lib_sgprops" Name="Lib_sgprops"
Filter=""> Filter="">
<File
RelativePath="..\..\simgear\props\AtomicChangeListener.cxx">
</File>
<File
RelativePath="..\..\simgear\props\AtomicChangeListener.hxx">
</File>
<File
RelativePath="..\..\simgear\props\ExtendedPropertyAdapter.hxx">
</File>
<File <File
RelativePath="..\..\simgear\props\condition.cxx"> RelativePath="..\..\simgear\props\condition.cxx">
</File> </File>
@@ -683,12 +686,6 @@
<File <File
RelativePath="..\..\simgear\scene\model\CheckSceneryVisitor.hxx"> RelativePath="..\..\simgear\scene\model\CheckSceneryVisitor.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\model\location.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\location.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\model\model.cxx"> RelativePath="..\..\simgear\scene\model\model.cxx">
</File> </File>
@@ -725,18 +722,18 @@
<File <File
RelativePath="..\..\simgear\scene\model\placement.hxx"> RelativePath="..\..\simgear\scene\model\placement.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\model\placementtrans.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\placementtrans.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\model\SGClipGroup.cxx"> RelativePath="..\..\simgear\scene\model\SGClipGroup.cxx">
</File> </File>
<File <File
RelativePath="..\..\simgear\scene\model\SGClipGroup.hxx"> RelativePath="..\..\simgear\scene\model\SGClipGroup.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\model\SGInteractionAnimation.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGInteractionAnimation.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.cxx"> RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.cxx">
</File> </File>
@@ -811,6 +808,53 @@
<Filter <Filter
Name="Lib_sgmaterial" Name="Lib_sgmaterial"
Filter=""> Filter="">
<File
RelativePath="..\..\simgear\scene\material\Effect.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Effect.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectBuilder.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectBuilder.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectCullVisitor.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectCullVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectGeode.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\EffectGeode.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\GLPredicate.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\GLPredicate.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Noise.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Noise.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\TextureBuilder.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\TextureBuilder.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\makeEffect.cxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\material\mat.cxx"> RelativePath="..\..\simgear\scene\material\mat.cxx">
</File> </File>
@@ -829,6 +873,18 @@
<File <File
RelativePath="..\..\simgear\scene\material\matmodel.hxx"> RelativePath="..\..\simgear\scene\material\matmodel.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\material\Pass.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Pass.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Technique.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\material\Technique.hxx">
</File>
</Filter> </Filter>
<Filter <Filter
Name="Lib_sgtgdb" Name="Lib_sgtgdb"
@@ -924,12 +980,6 @@
<File <File
RelativePath="..\..\simgear\threads\SGQueue.hxx"> RelativePath="..\..\simgear\threads\SGQueue.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\threads\SGThread.cxx">
</File>
<File
RelativePath="..\..\simgear\threads\SGThread.hxx">
</File>
</Filter> </Filter>
<Filter <Filter
Name="Lib_sgstructure" Name="Lib_sgstructure"
@@ -1130,12 +1180,24 @@
<Filter <Filter
Name="Lib_sgutil" Name="Lib_sgutil"
Filter=""> Filter="">
<File
RelativePath="..\..\simgear\scene\util\CopyOp.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\CopyOp.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.cxx"> RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.cxx">
</File> </File>
<File <File
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx"> RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\PrimitiveUtils.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx"> RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx">
</File> </File>
@@ -1184,12 +1246,115 @@
<File <File
RelativePath="..\..\simgear\scene\util\SGUpdateVisitor.hxx"> RelativePath="..\..\simgear\scene\util\SGUpdateVisitor.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\util\SplicingVisitor.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\SplicingVisitor.hxx">
</File>
<File <File
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.cxx"> RelativePath="..\..\simgear\scene\util\StateAttributeFactory.cxx">
</File> </File>
<File <File
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.hxx"> RelativePath="..\..\simgear\scene\util\StateAttributeFactory.hxx">
</File> </File>
<File
RelativePath="..\..\simgear\scene\util\UpdateOnceCallback.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\UpdateOnceCallback.hxx">
</File>
</Filter>
<Filter
Name="Lib_sgbvh"
Filter="">
<File
RelativePath="..\..\simgear\scene\bvh\BVHBoundingBoxVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHDebugCollectVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHGroup.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHGroup.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHLineGeometry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHLineGeometry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHLineSegmentVisitor.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHLineSegmentVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHMotionTransform.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHMotionTransform.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHNode.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHNode.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticBinary.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticBinary.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticData.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticGeometry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticGeometry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticGeometryBuilder.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticLeaf.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticLeaf.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticNode.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticNode.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticTriangle.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHStaticTriangle.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHSubTreeCollector.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHSubTreeCollector.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHTransform.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHTransform.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\bvh\BVHVisitor.hxx">
</File>
</Filter> </Filter>
<File <File
RelativePath="..\..\simgear\simgear_config.h-msvc71"> RelativePath="..\..\simgear\simgear_config.h-msvc71">
-20
View File
@@ -1,20 +0,0 @@
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
+5
View File
@@ -0,0 +1,5 @@
SimGear.ncb
SimGear.suo
*.user
Win32
x64
+2001 -1420
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -106,7 +106,7 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
} else if ( span <= 1.0 ) { } else if ( span <= 1.0 ) {
x = (int)((dlon - lon) / span); x = (int)((dlon - lon) / span);
} else { } else {
if ( (dlon >= 0) || (fabs(diff) < SG_EPSILON) ) { if ( dlon >= 0 ) {
lon = (int)( (int)(lon / span) * span); lon = (int)( (int)(lon / span) * span);
} else { } else {
// cout << " lon = " << lon // cout << " lon = " << lon
-1
View File
@@ -95,7 +95,6 @@ static double sg_bucket_span( double l ) {
class SGBucket { class SGBucket {
private: private:
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
short lon; // longitude index (-180 to 179) short lon; // longitude index (-180 to 179)
short lat; // latitude index (-90 to 89) short lat; // latitude index (-90 to 89)
char x; // x subdivision (0 to 7) char x; // x subdivision (0 to 7)
+27 -1
View File
@@ -131,9 +131,35 @@
// //
#ifdef __APPLE__ #ifdef __APPLE__
# ifdef __GNUC__
# if ( __GNUC__ > 3 ) || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 3 )
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); } inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
#else # else
// any C++ header file undefines isinf and isnan
// so this should be included before <iostream>
// the functions are STILL in libm (libSystem on mac os x)
extern "C" int (isnan)(double);
extern "C" int (isinf)(double);
# endif
# else
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
# endif
#endif
#if defined (__FreeBSD__)
# if __FreeBSD_version < 500000
extern "C" {
inline int isnan(double r) { return !(r <= 0 || r >= 0); }
}
# endif
#endif
#if defined (__CYGWIN__)
# include <ieeefp.h> // isnan
#endif
#if defined(__MINGW32__)
# define isnan(x) _isnan(x)
#endif #endif
+5 -5
View File
@@ -118,10 +118,10 @@
/** Nautical Miles to Radians */ /** Nautical Miles to Radians */
#define SG_RAD_TO_NM 3437.7467707849392526 #define SG_RAD_TO_NM 3437.7467707849392526
/** Miles per second to Knots */ /** meters per second to Knots */
#define SG_MPS_TO_KT 1.9438444924406046432 #define SG_MPS_TO_KT 1.9438444924406046432
/** Knots to Miles per second */ /** Knots to meters per second */
#define SG_KT_TO_MPS 0.5144444444444444444 #define SG_KT_TO_MPS 0.5144444444444444444
/** Feet per second to Knots */ /** Feet per second to Knots */
@@ -130,16 +130,16 @@
/** Knots to Feet per second */ /** Knots to Feet per second */
#define SG_KT_TO_FPS 1.6878098571011956874 #define SG_KT_TO_FPS 1.6878098571011956874
/** Miles per second to Miles per hour */ /** meters per second to Miles per hour */
#define SG_MPS_TO_MPH 2.2369362920544020312 #define SG_MPS_TO_MPH 2.2369362920544020312
/** Miles per hour to Miles per second */ /** meetrs per hour to Miles per second */
#define SG_MPH_TO_MPS 0.44704 #define SG_MPH_TO_MPS 0.44704
/** Meters per second to Kilometers per hour */ /** Meters per second to Kilometers per hour */
#define SG_MPS_TO_KMH 3.6 #define SG_MPS_TO_KMH 3.6
/** Kilometers per hour to Miles per second */ /** Kilometers per hour to meters per second */
#define SG_KMH_TO_MPS 0.2777777777777777778 #define SG_KMH_TO_MPS 0.2777777777777777778
/** Pascal to Inch Mercury */ /** Pascal to Inch Mercury */
+1
View File
@@ -33,6 +33,7 @@
#include <streambuf> #include <streambuf>
#include <ostream> #include <ostream>
#include <cstdio>
#include <simgear/debug/debug_types.h> #include <simgear/debug/debug_types.h>
+1 -1
View File
@@ -1,5 +1,5 @@
#include <string> #include <string>
#include "Debug/logstream.hxx" #include <simgear/debug/logstream.hxx>
class Test { class Test {
+13 -10
View File
@@ -30,7 +30,7 @@
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/point3d.hxx> #include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx> #include <simgear/math/polar3d.hxx>
#include <simgear/sound/soundmgr_openal.hxx> #include <simgear/sound/sample_group.hxx>
#include <simgear/scene/sky/cloudfield.hxx> #include <simgear/scene/sky/cloudfield.hxx>
#include <simgear/scene/sky/newcloud.hxx> #include <simgear/scene/sky/newcloud.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
@@ -175,7 +175,7 @@ SGEnviro::SGEnviro() :
lightning_enable_state(false), lightning_enable_state(false),
elapsed_time(0.0), elapsed_time(0.0),
dt(0.0), dt(0.0),
soundMgr(NULL), sampleGroup(NULL),
snd_active(false), snd_active(false),
snd_dist(0.0), snd_dist(0.0),
min_time_before_lt(0.0), min_time_before_lt(0.0),
@@ -189,6 +189,8 @@ SGEnviro::SGEnviro() :
} }
SGEnviro::~SGEnviro(void) { SGEnviro::~SGEnviro(void) {
if (sampleGroup) delete sampleGroup;
// OSGFIXME // OSGFIXME
return; return;
list_of_lightning::iterator iLightning; list_of_lightning::iterator iLightning;
@@ -530,8 +532,8 @@ void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed
} }
void SGEnviro::set_soundMgr(SGSoundMgr *mgr) { void SGEnviro::set_sampleGroup(SGSampleGroup *sgr) {
soundMgr = mgr; sampleGroup = sgr;
} }
void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) { void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
@@ -616,7 +618,7 @@ void SGLightning::lt_build(void) {
top[PY] = alt; top[PY] = alt;
top[PZ] = 0; top[PZ] = 0;
lt_build_tree_branch(0, top, 1.0, 50, top[PY] / 8.0); lt_build_tree_branch(0, top, 1.0, 50, top[PY] / 8.0);
if( ! sgEnviro.soundMgr ) if( ! sgEnviro.sampleGroup )
return; return;
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 ); 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 ); Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
@@ -737,7 +739,7 @@ void SGEnviro::drawLightning(void) {
return; return;
list_of_lightning::iterator iLightning; list_of_lightning::iterator iLightning;
// play 'thunder' for lightning // play 'thunder' for lightning
if( snd_active ) if( snd_active ) {
if( !snd_playing ) { if( !snd_playing ) {
// wait until sound has reached us // wait until sound has reached us
snd_timer += dt; snd_timer += dt;
@@ -751,20 +753,21 @@ void SGEnviro::drawLightning(void) {
double ax = 0.0, ay = 0.0; double ax = 0.0, ay = 0.0;
ax = cos(course) * dist; ax = cos(course) * dist;
ay = sin(course) * dist; ay = sin(course) * dist;
SGSharedPtr<SGSoundSample> snd = soundMgr->find("thunder"); SGSharedPtr<SGSoundSample> snd = sampleGroup->find("thunder");
if( snd ) { if( snd ) {
ALfloat pos[3]={ax, ay, -sgEnviro.last_alt }; SGVec3d pos = SGVec3d(ax, ay, -sgEnviro.last_alt);
snd->set_source_pos(pos); snd->set_position(pos);
snd->play_once(); snd->play_once();
} }
} }
} else { } else {
if( !soundMgr->is_playing("thunder") ) { if( !sampleGroup->is_playing("thunder") ) {
snd_active = false; snd_active = false;
snd_playing = false; snd_playing = false;
} }
} }
}
if( ! lightning_enable_state ) if( ! lightning_enable_state )
return; return;
+3 -3
View File
@@ -32,7 +32,7 @@ using std::vector;
using std::string; using std::string;
class SGLightning; class SGLightning;
class SGSoundMgr; class SGSampleGroup;
/** /**
* Simulate some echo on a weather radar. * Simulate some echo on a weather radar.
@@ -84,7 +84,7 @@ private:
sgVec4 fog_color; sgVec4 fog_color;
sgMat4 transform; sgMat4 transform;
double last_lon, last_lat, last_alt; double last_lon, last_lat, last_alt;
SGSoundMgr *soundMgr; SGSampleGroup *sampleGroup;
bool snd_active, snd_playing; bool snd_active, snd_playing;
double snd_timer, snd_wait, snd_pos_lat, snd_pos_lon, snd_dist; double snd_timer, snd_wait, snd_pos_lat, snd_pos_lon, snd_dist;
double min_time_before_lt; double min_time_before_lt;
@@ -243,7 +243,7 @@ public:
* Forward the sound manager instance to be able to play samples. * Forward the sound manager instance to be able to play samples.
* @param mgr a running sound manager * @param mgr a running sound manager
*/ */
void set_soundMgr(SGSoundMgr *mgr); void set_sampleGroup(SGSampleGroup *sgr);
void setFOV( float w, float h ); void setFOV( float w, float h );
void getFOV( float &w, float &h ); void getFOV( float &w, float &h );
+2
View File
@@ -158,6 +158,7 @@ public:
* @return planets array * @return planets array
*/ */
inline SGVec3d *getPlanets() { return planets; } inline SGVec3d *getPlanets() { return planets; }
inline const SGVec3d *getPlanets() const { return planets; }
/** @return the numbers of defined stars. */ /** @return the numbers of defined stars. */
inline int getNumStars() const { return stars->getNumStars(); } inline int getNumStars() const { return stars->getNumStars(); }
@@ -170,6 +171,7 @@ public:
* @returns star array * @returns star array
*/ */
inline SGVec3d *getStars() { return stars->getStars(); } inline SGVec3d *getStars() { return stars->getStars(); }
inline const SGVec3d *getStars() const { return stars->getStars(); }
}; };
+22 -4
View File
@@ -26,36 +26,54 @@ noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
tcp_server_SOURCES = tcp_server.cxx tcp_server_SOURCES = tcp_server.cxx
if HAVE_FRAMEWORK_PLIB
tcp_server_LDFLAGS = $(plib_FRAMEWORK)
else
tcp_server_PLIB_LIBS = -lplibnet -lplibul
endif
tcp_server_LDADD = \ tcp_server_LDADD = \
libsgio.a \ libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \ $(top_builddir)/simgear/misc/libsgmisc.a \
-lplibnet -lplibul -lz \ $(tcp_server_PLIB_LIBS) -lz \
$(network_LIBS) \ $(network_LIBS) \
$(base_LIBS) $(base_LIBS)
tcp_client_SOURCES = tcp_client.cxx tcp_client_SOURCES = tcp_client.cxx
if HAVE_FRAMEWORK_PLIB
tcp_client_LDFLAGS = $(plib_FRAMEWORK)
else
tcp_client_PLIB_LIBS = -lplibnet -lplibul
endif
tcp_client_LDADD = \ tcp_client_LDADD = \
libsgio.a \ libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \ $(top_builddir)/simgear/misc/libsgmisc.a \
-lplibnet -lplibul -lz \ $(tcp_client_PLIB_LIBS) -lz \
$(network_LIBS) \ $(network_LIBS) \
$(base_LIBS) $(base_LIBS)
socktest_SOURCES = socktest.cxx socktest_SOURCES = socktest.cxx
if HAVE_FRAMEWORK_PLIB
socktest_LDFLAGS = $(plib_FRAMEWORK)
else
socktest_PLIB_LIBS = -lplibnet -lplibul
endif
socktest_LDADD = \ socktest_LDADD = \
libsgio.a \ libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \ $(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \ $(top_builddir)/simgear/misc/libsgmisc.a \
-lplibnet -lplibul -lz \ $(socktest_PLIB_LIBS) -lz
$(network_LIBS) \ $(network_LIBS) \
$(base_LIBS) $(base_LIBS)
lowtest_SOURCES = lowtest.cxx lowtest_SOURCES = lowtest.cxx
+16 -8
View File
@@ -55,21 +55,25 @@ void sgWriteChar ( gzFile fd, const char var )
void sgReadFloat ( gzFile fd, float *var ) void sgReadFloat ( gzFile fd, float *var )
{ {
if ( gzread ( fd, var, sizeof(float) ) != sizeof(float) ) { union { float v; uint32_t u; } buf;
if ( gzread ( fd, &buf.u, sizeof(float) ) != sizeof(float) ) {
read_error = true ; read_error = true ;
} }
if ( sgIsBigEndian() ) { if ( sgIsBigEndian() ) {
sgEndianSwap( (uint32_t *)var); sgEndianSwap( &buf.u );
} }
*var = buf.v;
} }
void sgWriteFloat ( gzFile fd, const float var ) void sgWriteFloat ( gzFile fd, const float var )
{ {
union { float v; uint32_t u; } buf;
buf.v = var;
if ( sgIsBigEndian() ) { if ( sgIsBigEndian() ) {
sgEndianSwap( (uint32_t *)&var); sgEndianSwap( &buf.u );
} }
if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) { if ( gzwrite ( fd, (void *)(&buf.u), sizeof(float) ) != sizeof(float) ) {
write_error = true ; write_error = true ;
} }
} }
@@ -77,21 +81,25 @@ void sgWriteFloat ( gzFile fd, const float var )
void sgReadDouble ( gzFile fd, double *var ) void sgReadDouble ( gzFile fd, double *var )
{ {
if ( gzread ( fd, var, sizeof(double) ) != sizeof(double) ) { union { double v; uint64_t u; } buf;
if ( gzread ( fd, &buf.u, sizeof(double) ) != sizeof(double) ) {
read_error = true ; read_error = true ;
} }
if ( sgIsBigEndian() ) { if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64_t *)var); sgEndianSwap( &buf.u );
} }
*var = buf.v;
} }
void sgWriteDouble ( gzFile fd, const double var ) void sgWriteDouble ( gzFile fd, const double var )
{ {
union { double v; uint64_t u; } buf;
buf.v = var;
if ( sgIsBigEndian() ) { if ( sgIsBigEndian() ) {
sgEndianSwap( (uint64_t *)&var); sgEndianSwap( &buf.u );
} }
if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) { if ( gzwrite ( fd, (void *)(&buf.u), sizeof(double) ) != sizeof(double) ) {
write_error = true ; write_error = true ;
} }
} }
+1
View File
@@ -33,6 +33,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/math/sg_types.hxx> #include <simgear/math/sg_types.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/bucket/newbucket.hxx> #include <simgear/bucket/newbucket.hxx>
#include <stdio.h> #include <stdio.h>
+6
View File
@@ -12,6 +12,7 @@ class TcpServer
{ {
public: public:
TcpServer(); TcpServer();
~TcpServer();
bool open(); bool open();
bool process(); bool process();
bool close(); bool close();
@@ -25,6 +26,11 @@ TcpServer::TcpServer()
channel = new SGSocket( "", "5500", "tcp" ); channel = new SGSocket( "", "5500", "tcp" );
} }
TcpServer::~TcpServer()
{
delete channel;
}
bool bool
TcpServer::open() TcpServer::open()
{ {
+2 -4
View File
@@ -2,11 +2,9 @@ includedir = @includedir@/magvar
lib_LIBRARIES = libsgmagvar.a lib_LIBRARIES = libsgmagvar.a
include_HEADERS = magvar.hxx include_HEADERS = magvar.hxx coremag.hxx
libsgmagvar_a_SOURCES = \ libsgmagvar_a_SOURCES = coremag.cxx magvar.cxx
coremag.hxx coremag.cxx \
magvar.cxx
noinst_PROGRAMS = testmagvar noinst_PROGRAMS = testmagvar
+4 -3
View File
@@ -4,10 +4,10 @@ check_PROGRAMS = SGMathTest SGGeometryTest
TESTS = $(check_PROGRAMS) TESTS = $(check_PROGRAMS)
SGMathTest_SOURCES = SGMathTest.cxx SGMathTest_SOURCES = SGMathTest.cxx
SGMathTest_LDADD = libsgmath.a $(base_LIBS) SGMathTest_LDADD = libsgmath.a -lsgstructure $(base_LIBS)
SGGeometryTest_SOURCES = SGGeometryTest.cxx SGGeometryTest_SOURCES = SGGeometryTest.cxx
SGGeometryTest_LDADD = libsgmath.a $(base_LIBS) SGGeometryTest_LDADD = libsgmath.a -lsgstructure $(base_LIBS)
lib_LIBRARIES = libsgmath.a lib_LIBRARIES = libsgmath.a
@@ -42,7 +42,8 @@ include_HEADERS = \
SGTriangle.hxx \ SGTriangle.hxx \
SGVec2.hxx \ SGVec2.hxx \
SGVec3.hxx \ SGVec3.hxx \
SGVec4.hxx SGVec4.hxx \
beziercurve.hxx
libsgmath_a_SOURCES = \ libsgmath_a_SOURCES = \
interpolater.cxx \ interpolater.cxx \
+52 -1
View File
@@ -25,6 +25,20 @@ public:
_min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()), _min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()),
_max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max()) _max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max())
{ } { }
SGBox(const SGVec3<T>& pt) :
_min(pt),
_max(pt)
{ }
SGBox(const SGVec3<T>& min, const SGVec3<T>& max) :
_min(min),
_max(max)
{ }
template<typename S>
explicit SGBox(const SGBox<S>& box) :
_min(box.getMin()),
_max(box.getMax())
{ }
void setMin(const SGVec3<T>& min) void setMin(const SGVec3<T>& min)
{ _min = min; } { _min = min; }
const SGVec3<T>& getMin() const const SGVec3<T>& getMin() const
@@ -35,6 +49,29 @@ public:
const SGVec3<T>& getMax() const const SGVec3<T>& getMax() const
{ return _max; } { return _max; }
SGVec3<T> getCorner(unsigned i) const
{ return SGVec3<T>((i&1) ? _min[0] : _max[0],
(i&2) ? _min[1] : _max[1],
(i&4) ? _min[2] : _max[2]); }
template<typename S>
SGVec3<T> getNearestCorner(const SGVec3<S>& pt) const
{
SGVec3<T> center = getCenter();
return SGVec3<T>((pt[0] <= center[0]) ? _min[0] : _max[0],
(pt[1] <= center[1]) ? _min[1] : _max[1],
(pt[2] <= center[2]) ? _min[2] : _max[2]);
}
template<typename S>
SGVec3<T> getFarestCorner(const SGVec3<S>& pt) const
{
SGVec3<T> center = getCenter();
return SGVec3<T>((pt[0] > center[0]) ? _min[0] : _max[0],
(pt[1] > center[1]) ? _min[1] : _max[1],
(pt[2] > center[2]) ? _min[2] : _max[2]);
}
// Only works for floating point types // Only works for floating point types
SGVec3<T> getCenter() const SGVec3<T> getCenter() const
{ return T(0.5)*(_min + _max); } { return T(0.5)*(_min + _max); }
@@ -42,6 +79,8 @@ public:
// Only valid for nonempty boxes // Only valid for nonempty boxes
SGVec3<T> getSize() const SGVec3<T> getSize() const
{ return _max - _min; } { return _max - _min; }
SGVec3<T> getHalfSize() const
{ return T(0.5)*getSize(); }
T getVolume() const T getVolume() const
{ {
@@ -83,7 +122,7 @@ public:
// Note that this only works if the box is nonmepty // Note that this only works if the box is nonmepty
unsigned getBroadestAxis() const unsigned getBroadestAxis() const
{ {
SGVec3d size = getSize(); SGVec3<T> size = getSize();
if (size[1] <= size[0] && size[2] <= size[0]) if (size[1] <= size[0] && size[2] <= size[0])
return 0; return 0;
else if (size[2] <= size[1]) else if (size[2] <= size[1])
@@ -92,6 +131,18 @@ public:
return 2; return 2;
} }
// Note that this only works if the box is nonmepty
unsigned getSmallestAxis() const
{
SGVec3<T> 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: private:
SGVec3<T> _min; SGVec3<T> _min;
SGVec3<T> _max; SGVec3<T> _max;
+11 -7
View File
@@ -17,22 +17,24 @@
#include "SGMath.hxx" #include "SGMath.hxx"
osg::Matrix SGGeod::makeSimulationFrameRelative() #ifndef NO_OPENSCENEGRAPH_INTERFACE
osg::Matrix SGGeod::makeSimulationFrameRelative() const
{ {
SGQuatd hlOr = SGQuatd::fromLonLat(*this); SGQuatd hlOr = SGQuatd::fromLonLat(*this);
return osg::Matrix(hlOr.osg()); return osg::Matrix(toOsg(hlOr));
} }
osg::Matrix SGGeod::makeSimulationFrame() osg::Matrix SGGeod::makeSimulationFrame() const
{ {
osg::Matrix result(makeSimulationFrameRelative()); osg::Matrix result(makeSimulationFrameRelative());
SGVec3d coord; SGVec3d coord;
SGGeodesy::SGGeodToCart(*this, coord); SGGeodesy::SGGeodToCart(*this, coord);
result.setTrans(coord.osg()); result.setTrans(toOsg(coord));
return result; return result;
} }
osg::Matrix SGGeod::makeZUpFrameRelative() osg::Matrix SGGeod::makeZUpFrameRelative() const
{ {
osg::Matrix result(makeSimulationFrameRelative()); osg::Matrix result(makeSimulationFrameRelative());
// 180 degree rotation around Y axis // 180 degree rotation around Y axis
@@ -41,11 +43,13 @@ osg::Matrix SGGeod::makeZUpFrameRelative()
return result; return result;
} }
osg::Matrix SGGeod::makeZUpFrame() osg::Matrix SGGeod::makeZUpFrame() const
{ {
osg::Matrix result(makeZUpFrameRelative()); osg::Matrix result(makeZUpFrameRelative());
SGVec3d coord; SGVec3d coord;
SGGeodesy::SGGeodToCart(*this, coord); SGGeodesy::SGGeodToCart(*this, coord);
result.setTrans(coord.osg()); result.setTrans(toOsg(coord));
return result; return result;
} }
#endif
+28 -6
View File
@@ -20,7 +20,9 @@
#include <simgear/constants.h> #include <simgear/constants.h>
#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include <osg/Matrix> #include <osg/Matrix>
#endif
// #define SG_GEOD_NATIVE_DEGREE // #define SG_GEOD_NATIVE_DEGREE
@@ -42,6 +44,10 @@ public:
static SGGeod fromRadM(double lon, double lat, double elevation); static SGGeod fromRadM(double lon, double lat, double elevation);
/// Factory from angular values in degrees and elevation in m /// Factory from angular values in degrees and elevation in m
static SGGeod fromDegM(double lon, double lat, double elevation); static SGGeod fromDegM(double lon, double lat, double elevation);
/// Factory from an other SGGeod and a different elevation in m
static SGGeod fromGeodM(const SGGeod& geod, double elevation);
/// Factory from an other SGGeod and a different elevation in ft
static SGGeod fromGeodFt(const SGGeod& geod, double elevation);
/// Factory to convert position from a cartesian position assumed to be /// Factory to convert position from a cartesian position assumed to be
/// in wgs84 measured in meters /// in wgs84 measured in meters
/// Note that this conversion is relatively expensive to compute /// Note that this conversion is relatively expensive to compute
@@ -80,25 +86,27 @@ public:
/// Set the geodetic elevation from the argument given in feet /// Set the geodetic elevation from the argument given in feet
void setElevationFt(double elevation); void setElevationFt(double elevation);
#ifndef NO_OPENSCENEGRAPH_INTERFACE
// Create a local coordinate frame in the earth-centered frame of // Create a local coordinate frame in the earth-centered frame of
// reference. X points north, Z points down. // reference. X points north, Z points down.
// makeSimulationFrameRelative() only includes rotation. // makeSimulationFrameRelative() only includes rotation.
osg::Matrix makeSimulationFrameRelative() const;
osg::Matrix makeSimulationFrameRelative(); osg::Matrix makeSimulationFrame() const;
osg::Matrix makeSimulationFrame();
// Create a Z-up local coordinate frame in the earth-centered frame // Create a Z-up local coordinate frame in the earth-centered frame
// of reference. This is what scenery models, etc. expect. // of reference. This is what scenery models, etc. expect.
// makeZUpFrameRelative() only includes rotation. // makeZUpFrameRelative() only includes rotation.
osg::Matrix makeZUpFrameRelative(); osg::Matrix makeZUpFrameRelative() const;
osg::Matrix makeZUpFrame(); osg::Matrix makeZUpFrame() const;
#endif
private: private:
/// This one is private since construction is not unique if you do /// This one is private since construction is not unique if you do
/// not know the units of the arguments. Use the factory methods for /// not know the units of the arguments. Use the factory methods for
/// that purpose /// that purpose
SGGeod(double lon, double lat, double elevation); SGGeod(double lon, double lat, double elevation);
/// The actual data, angles in degree, elevation in meters //// FIXME: wrong comment!
/// The actual data, angles in degrees, elevation in meters
/// The rationale for storing the values in degrees is that most code places /// 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. /// 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 /// The places where it makes sense to use radians is when we convert
@@ -192,6 +200,20 @@ SGGeod::fromDegM(double lon, double lat, double elevation)
#endif #endif
} }
inline
SGGeod
SGGeod::fromGeodM(const SGGeod& geod, double elevation)
{
return SGGeod(geod._lon, geod._lat, elevation);
}
inline
SGGeod
SGGeod::fromGeodFt(const SGGeod& geod, double elevation)
{
return SGGeod(geod._lon, geod._lat, elevation*SG_FEET_TO_METER);
}
inline inline
SGGeod SGGeod
SGGeod::fromCart(const SGVec3<double>& cart) SGGeod::fromCart(const SGVec3<double>& cart)
+65 -4
View File
@@ -21,6 +21,7 @@
#include <cmath> #include <cmath>
#include <simgear/structure/exception.hxx>
#include "SGMath.hxx" #include "SGMath.hxx"
// These are hard numbers from the WGS84 standard. DON'T MODIFY // These are hard numbers from the WGS84 standard. DON'T MODIFY
@@ -56,7 +57,7 @@ const double SGGeodesy::POLRAD = _POLRAD;
#define E2 fabs(1 - _SQUASH*_SQUASH) #define E2 fabs(1 - _SQUASH*_SQUASH)
static double a = _EQURAD; static double a = _EQURAD;
static double ra2 = 1/(_EQURAD*_EQURAD); static double ra2 = 1/(_EQURAD*_EQURAD);
static double e = sqrt(E2); //static double e = sqrt(E2);
static double e2 = E2; static double e2 = E2;
static double e4 = E2*E2; static double e4 = E2*E2;
@@ -78,11 +79,30 @@ SGGeodesy::SGCartToGeod(const SGVec3<double>& cart, SGGeod& geod)
double Y = cart(1); double Y = cart(1);
double Z = cart(2); double Z = cart(2);
double XXpYY = X*X+Y*Y; double XXpYY = X*X+Y*Y;
if( XXpYY + Z*Z < 25 ) {
// This function fails near the geocenter region, so catch that special case here.
// Define the innermost sphere of small radius as earth center and return the
// coordinates 0/0/-EQURAD. It may be any other place on geoide's surface,
// the Northpole, Hawaii or Wentorf. This one was easy to code ;-)
geod.setLongitudeRad( 0.0 );
geod.setLongitudeRad( 0.0 );
geod.setElevationM( -EQURAD );
return;
}
double sqrtXXpYY = sqrt(XXpYY); double sqrtXXpYY = sqrt(XXpYY);
double p = XXpYY*ra2; double p = XXpYY*ra2;
double q = Z*Z*(1-e2)*ra2; double q = Z*Z*(1-e2)*ra2;
double r = 1/6.0*(p+q-e4); double r = 1/6.0*(p+q-e4);
double s = e4*p*q/(4*r*r*r); double s = e4*p*q/(4*r*r*r);
/*
s*(2+s) is negative for s = [-2..0]
slightly negative values for s due to floating point rounding errors
cause nan for sqrt(s*(2+s))
We can probably clamp the resulting parable to positive numbers
*/
if( s >= -2.0 && s <= 0.0 )
s = 0.0;
double t = pow(1+s+sqrt(s*(2+s)), 1/3.0); double t = pow(1+s+sqrt(s*(2+s)), 1/3.0);
double u = r*(1+t+1/t); double u = r*(1+t+1/t);
double v = sqrt(u*u+e4*q); double v = sqrt(u*u+e4*q);
@@ -314,7 +334,7 @@ static int _geo_inverse_wgs_84( double lat1, double lon1, double lat2,
double sinphi2 = sin(phi2), cosphi2 = cos(phi2); double sinphi2 = sin(phi2), cosphi2 = cos(phi2);
if( (fabs(lat1-lat2) < testv && if( (fabs(lat1-lat2) < testv &&
( fabs(lon1-lon2) < testv) || fabs(lat1-90.0) < testv ) ) ( fabs(lon1-lon2) < testv)) || (fabs(lat1-90.0) < testv ) )
{ {
// TWO STATIONS ARE IDENTICAL : SET DISTANCE & AZIMUTHS TO ZERO */ // TWO STATIONS ARE IDENTICAL : SET DISTANCE & AZIMUTHS TO ZERO */
*az1 = 0.0; *az2 = 0.0; *s = 0.0; *az1 = 0.0; *az2 = 0.0; *s = 0.0;
@@ -423,6 +443,40 @@ SGGeodesy::inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
return ret == 0; return ret == 0;
} }
double
SGGeodesy::courseDeg(const SGGeod& p1, const SGGeod& p2)
{
double course1, course2, distance;
int r = _geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
&course1, &course2, &distance);
if (r != 0) {
throw sg_exception("SGGeodesy::courseDeg, unable to compute course");
}
return course1;
}
double
SGGeodesy::distanceM(const SGGeod& p1, const SGGeod& p2)
{
double course1, course2, distance;
int r = _geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
&course1, &course2, &distance);
if (r != 0) {
throw sg_exception("SGGeodesy::distanceM, unable to compute distance");
}
return distance;
}
double
SGGeodesy::distanceNm(const SGGeod& from, const SGGeod& to)
{
return distanceM(from, to) * SG_METER_TO_NM;
}
/// Geocentric routines /// Geocentric routines
void void
@@ -486,7 +540,7 @@ SGGeodesy::courseRad(const SGGeoc& from, const SGGeoc& to)
} }
double double
SGGeodesy::distanceM(const SGGeoc& from, const SGGeoc& to) SGGeodesy::distanceRad(const SGGeoc& from, const SGGeoc& to)
{ {
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 + // d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) // cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
@@ -496,5 +550,12 @@ SGGeodesy::distanceM(const SGGeoc& from, const SGGeoc& to)
double tmp2 = sin(0.5*(from.getLongitudeRad() - to.getLongitudeRad())); double tmp2 = sin(0.5*(from.getLongitudeRad() - to.getLongitudeRad()));
double square = tmp1*tmp1 + cosLatFrom*cosLatTo*tmp2*tmp2; double square = tmp1*tmp1 + cosLatFrom*cosLatTo*tmp2*tmp2;
double s = SGMiscd::min(sqrt(SGMiscd::max(square, 0)), 1); double s = SGMiscd::min(sqrt(SGMiscd::max(square, 0)), 1);
return 2 * asin(s) * SG_RAD_TO_NM * SG_NM_TO_METER; return 2 * asin(s);
}
double
SGGeodesy::distanceM(const SGGeoc& from, const SGGeoc& to)
{
return distanceRad(from, to) * SG_RAD_TO_NM * SG_NM_TO_METER;
} }
+5
View File
@@ -53,10 +53,15 @@ public:
static bool inverse(const SGGeod& p1, const SGGeod& p2, double& course1, static bool inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
double& course2, double& distance); double& course2, double& distance);
static double courseDeg(const SGGeod& from, const SGGeod& to);
static double distanceM(const SGGeod& from, const SGGeod& to);
static double distanceNm(const SGGeod& from, const SGGeod& to);
// Geocentric course/distance computation // Geocentric course/distance computation
static void advanceRadM(const SGGeoc& geoc, double course, double distance, static void advanceRadM(const SGGeoc& geoc, double course, double distance,
SGGeoc& result); SGGeoc& result);
static double courseRad(const SGGeoc& from, const SGGeoc& to); static double courseRad(const SGGeoc& from, const SGGeoc& to);
static double distanceRad(const SGGeoc& from, const SGGeoc& to);
static double distanceM(const SGGeoc& from, const SGGeoc& to); static double distanceM(const SGGeoc& from, const SGGeoc& to);
}; };
+107 -2
View File
@@ -31,6 +31,102 @@ SGVec3<T> rndVec3(void)
return SGVec3<T>(sg_random(), sg_random(), sg_random()); return SGVec3<T>(sg_random(), sg_random(), sg_random());
} }
template<typename T>
bool
TriangleClosestPointIntersectionTest(void)
{
unsigned nTests = 100000;
unsigned failedCount = 0;
for (unsigned i = 0; i < nTests; ++i) {
// test triangle
SGTriangle<T> triangle(rndVec3<T>(), rndVec3<T>(), rndVec3<T>());
T triangleEps = 100*SGLimits<T>::epsilon();
// generate random point in the triangle
T u = 4*sg_random() - 2;
T v = 4*sg_random() - 2;
if (1 < u + v) {
v = T(0.5)*(v + 1 - u);
u = 1 - v;
}
u = SGMisc<T>::clip(u, 0, 1);
v = SGMisc<T>::clip(v, 0, 1);
SGVec3<T> testClosest;
testClosest = triangle.getBaseVertex();
testClosest += u*triangle.getEdge(0) + v*triangle.getEdge(1);
SGVec3<T> n = triangle.getNormal();
SGVec3<T> e0 = triangle.getEdge(0);
SGVec3<T> e1 = triangle.getEdge(1);
// The normals to the edges
SGVec3<T> a0 = cross(e0, n);
SGVec3<T> a1 = cross(e1 - e0, n);
SGVec3<T> a2 = cross(n, e1);
SGVec3<T> testPoint = testClosest;
// Ok, if we are at some edge, go perpandicular to the triangle away
if (u == 0) {
if (v == 0) {
testPoint += sg_random()*a0 + sg_random()*a2;
} else if (v == 1) {
testPoint += sg_random()*a1 + sg_random()*a2;
} else {
testPoint += sg_random()*a2;
}
} else if (u == 1) {
testPoint += sg_random()*a0 + sg_random()*a1;
} else {
if (v == 0) {
testPoint += sg_random()*a0;
} else if (u + v == 1) {
testPoint += sg_random()*a1;
}
}
testPoint += (2*sg_random() - 1)*n;
// Test the closest point function
SGVec3<T> closest = closestPoint(triangle, testPoint);
if (!equivalent(closest, testClosest, triangleEps)) {
std::cout << "Failed closest point test #" << i
<< ": not equivalent!\nu = "
<< u << ", v = " << v
<< "\ntestPoint = " << testPoint
<< ", testClosest = " << testClosest
<< ", closest = " << closest << "\n"
<< triangle << std::endl;
++failedCount;
}
// Test the triangle sphere intersection
SGSphere<T> sphere(testPoint, sg_random());
bool exactIntersection = intersects(sphere, testClosest);
// bool exactIntersection = intersects(sphere, closest);
bool sphereTriangleIntersection = intersects(sphere, triangle);
if (sphereTriangleIntersection != exactIntersection) {
std::cout << "Failed triangle sphere intersection test #" << i
<< ": not equivalent!\nu = "
<< u << ", v = " << v
<< "\ntestPoint = " << testPoint
<< ", testClosest = " << testClosest
<< ", closest = " << closest << "\n"
<< triangle << 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;
}
template<typename T> template<typename T>
bool bool
TriangleLineIntersectionTest(void) TriangleLineIntersectionTest(void)
@@ -44,6 +140,8 @@ TriangleLineIntersectionTest(void)
SGTriangle<T> tri(v0, v1, v2); SGTriangle<T> tri(v0, v1, v2);
T triangleEps = 100*SGLimits<T>::epsilon();
// generate random coeficients // generate random coeficients
T u = 4*sg_random() - 2; T u = 4*sg_random() - 2;
T v = 4*sg_random() - 2; T v = 4*sg_random() - 2;
@@ -59,7 +157,7 @@ TriangleLineIntersectionTest(void)
if (intersects(isectres, tri, lineSegment)) { if (intersects(isectres, tri, lineSegment)) {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) { if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) {
if (!equivalent(isectres, isectpt)) { if (!equivalent(isectres, isectpt, triangleEps)) {
std::cout << "Failed line segment intersection test #" << i std::cout << "Failed line segment intersection test #" << i
<< ": not equivalent!\nu = " << ": not equivalent!\nu = "
<< u << ", v = " << v << ", t = " << t << u << ", v = " << v << ", t = " << t
@@ -87,7 +185,7 @@ TriangleLineIntersectionTest(void)
ray.set(isectpt - t*dir, dir); ray.set(isectpt - t*dir, dir);
if (intersects(isectres, tri, ray)) { if (intersects(isectres, tri, ray)) {
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) { if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) {
if (!equivalent(isectres, isectpt)) { if (!equivalent(isectres, isectpt, triangleEps)) {
std::cout << "Failed ray intersection test #" << i std::cout << "Failed ray intersection test #" << i
<< ": not equivalent!\nu = " << ": not equivalent!\nu = "
<< u << ", v = " << v << ", t = " << t << u << ", v = " << v << ", t = " << t
@@ -422,6 +520,13 @@ main(void)
<< "Some of these tests can fail due to roundoff problems...\n" << "Some of these tests can fail due to roundoff problems...\n"
<< "Dont worry if only a few of them fail..." << std::endl; << "Dont worry if only a few of them fail..." << std::endl;
sg_srandom(17);
if (!TriangleClosestPointIntersectionTest<float>())
return EXIT_FAILURE;
if (!TriangleClosestPointIntersectionTest<double>())
return EXIT_FAILURE;
if (!TriangleLineIntersectionTest<float>()) if (!TriangleLineIntersectionTest<float>())
return EXIT_FAILURE; return EXIT_FAILURE;
if (!TriangleLineIntersectionTest<double>()) if (!TriangleLineIntersectionTest<double>())
+461 -11
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de // Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -20,7 +20,21 @@
template<typename T> template<typename T>
inline bool inline bool
intersects(const SGBox<T>& box, const SGSphere<T>& sphere) intersects(const SGSphere<T>& s1, const SGSphere<T>& s2)
{
if (s1.empty())
return false;
if (s2.empty())
return false;
T dist = s1.getRadius() + s2.getRadius();
return distSqr(s1.getCenter(), s2.getCenter()) <= dist*dist;
}
template<typename T1, typename T2>
inline bool
intersects(const SGBox<T1>& box, const SGSphere<T2>& sphere)
{ {
if (sphere.empty()) if (sphere.empty())
return false; return false;
@@ -45,15 +59,15 @@ intersects(const SGBox<T>& box, const SGSphere<T>& sphere)
return true; return true;
} }
// make it symmetric // make it symmetric
template<typename T> template<typename T1, typename T2>
inline bool inline bool
intersects(const SGSphere<T>& sphere, const SGBox<T>& box) intersects(const SGSphere<T1>& sphere, const SGBox<T2>& box)
{ return intersects(box, sphere); } { return intersects(box, sphere); }
template<typename T> template<typename T1, typename T2>
inline bool inline bool
intersects(const SGVec3<T>& v, const SGBox<T>& box) intersects(const SGVec3<T1>& v, const SGBox<T2>& box)
{ {
if (v[0] < box.getMin()[0]) if (v[0] < box.getMin()[0])
return false; return false;
@@ -69,9 +83,9 @@ intersects(const SGVec3<T>& v, const SGBox<T>& box)
return false; return false;
return true; return true;
} }
template<typename T> template<typename T1, typename T2>
inline bool inline bool
intersects(const SGBox<T>& box, const SGVec3<T>& v) intersects(const SGBox<T1>& box, const SGVec3<T2>& v)
{ return intersects(v, box); } { return intersects(v, box); }
@@ -529,13 +543,427 @@ template<typename T>
inline bool inline bool
intersects(const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0) intersects(const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0)
{ {
// FIXME: for now just wrap the othr method. When that has prooven // FIXME: for now just wrap the other method. When that has prooven
// well optimized, implement that special case // well optimized, implement that special case
SGVec3<T> dummy; SGVec3<T> dummy;
return intersects(dummy, tri, lineSegment, eps); return intersects(dummy, tri, lineSegment, eps);
} }
template<typename T>
inline SGVec3<T>
closestPoint(const SGTriangle<T>& tri, const SGVec3<T>& p)
{
// This method minimizes the distance function Q(u, v) = || p - x ||
// where x is a point in the trialgle given by the vertices v_i
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
// The theoretical analysis is somehow too long for a comment.
// May be it is sufficient to see that this code passes all the tests.
SGVec3<T> off = tri.getBaseVertex() - p;
T a = dot(tri.getEdge(0), tri.getEdge(0));
T b = dot(tri.getEdge(0), tri.getEdge(1));
T c = dot(tri.getEdge(1), tri.getEdge(1));
T d = dot(tri.getEdge(0), off);
T e = dot(tri.getEdge(1), off);
T det = a*c - b*b;
T u = b*e - c*d;
T v = b*d - a*e;
/*
// Regions
// \2|
// \|
// |\
// 3 |0\ 1
//----------
// 4 | 5 \ 6
*/
if (u + v <= det) {
if (u < 0) {
if (v < 0) {
// region 4
if (d < 0) {
if (a <= -d) {
// u = 1;
// v = 0;
return tri.getBaseVertex() + tri.getEdge(0);
} else {
u = -d/a;
// v = 0;
return tri.getBaseVertex() + u*tri.getEdge(0);
}
} else {
if (0 < e) {
// u = 0;
// v = 0;
return tri.getBaseVertex();
} else if (c <= -e) {
// u = 0;
// v = 1;
return tri.getBaseVertex() + tri.getEdge(1);
} else {
// u = 0;
v = -e/c;
return tri.getBaseVertex() + v*tri.getEdge(1);
}
}
} else {
// region 3
if (0 <= e) {
// u = 0;
// v = 0;
return tri.getBaseVertex();
} else if (c <= -e) {
// u = 0;
// v = 1;
return tri.getBaseVertex() + tri.getEdge(1);
} else {
// u = 0;
v = -e/c;
return tri.getBaseVertex() + v*tri.getEdge(1);
}
}
} else if (v < 0) {
// region 5
if (0 <= d) {
// u = 0;
// v = 0;
return tri.getBaseVertex();
} else if (a <= -d) {
// u = 1;
// v = 0;
return tri.getBaseVertex() + tri.getEdge(0);
} else {
u = -d/a;
// v = 0;
return tri.getBaseVertex() + u*tri.getEdge(0);
}
} else {
// region 0
if (det <= SGLimits<T>::min()) {
u = 0;
v = 0;
return tri.getBaseVertex();
} else {
T invDet = 1/det;
u *= invDet;
v *= invDet;
return tri.getBaseVertex() + u*tri.getEdge(0) + v*tri.getEdge(1);
}
}
} else {
if (u < 0) {
// region 2
T tmp0 = b + d;
T tmp1 = c + e;
if (tmp0 < tmp1) {
T numer = tmp1 - tmp0;
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 1;
// v = 0;
return tri.getBaseVertex() + tri.getEdge(0);
} else {
u = numer/denom;
v = 1 - u;
return tri.getBaseVertex() + u*tri.getEdge(0) + v*tri.getEdge(1);
}
} else {
if (tmp1 <= 0) {
// u = 0;
// v = 1;
return tri.getBaseVertex() + tri.getEdge(1);
} else if (0 <= e) {
// u = 0;
// v = 0;
return tri.getBaseVertex();
} else {
// u = 0;
v = -e/c;
return tri.getBaseVertex() + v*tri.getEdge(1);
}
}
} else if (v < 0) {
// region 6
T tmp0 = b + e;
T tmp1 = a + d;
if (tmp0 < tmp1) {
T numer = tmp1 - tmp0;
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 0;
// v = 1;
return tri.getBaseVertex() + tri.getEdge(1);
} else {
v = numer/denom;
u = 1 - v;
return tri.getBaseVertex() + u*tri.getEdge(0) + v*tri.getEdge(1);
}
} else {
if (tmp1 < 0) {
// u = 1;
// v = 0;
return tri.getBaseVertex() + tri.getEdge(0);
} else if (0 <= d) {
// u = 0;
// v = 0;
return tri.getBaseVertex();
} else {
u = -d/a;
// v = 0;
return tri.getBaseVertex() + u*tri.getEdge(0);
}
}
} else {
// region 1
T numer = c + e - b - d;
if (numer <= 0) {
// u = 0;
// v = 1;
return tri.getVertex(2);
} else {
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 1;
// v = 0;
return tri.getBaseVertex() + tri.getEdge(0);
} else {
u = numer/denom;
v = 1 - u;
return tri.getBaseVertex() + u*tri.getEdge(0) + v*tri.getEdge(1);
}
}
}
}
}
template<typename T>
inline SGVec3<T>
closestPoint(const SGVec3<T>& p, const SGTriangle<T>& tri)
{ return closestPoint(tri, p); }
template<typename T, typename T2>
inline bool
intersects(const SGTriangle<T>& tri, const SGSphere<T2>& sphere)
{
// This method minimizes the distance function Q(u, v) = || p - x ||
// where x is a point in the trialgle given by the vertices v_i
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
// The theoretical analysis is somehow too long for a comment.
// May be it is sufficient to see that this code passes all the tests.
SGVec3<T> off = tri.getBaseVertex() - SGVec3<T>(sphere.getCenter());
T baseDist2 = dot(off, off);
T a = dot(tri.getEdge(0), tri.getEdge(0));
T b = dot(tri.getEdge(0), tri.getEdge(1));
T c = dot(tri.getEdge(1), tri.getEdge(1));
T d = dot(tri.getEdge(0), off);
T e = dot(tri.getEdge(1), off);
T det = a*c - b*b;
T u = b*e - c*d;
T v = b*d - a*e;
/*
// Regions
// \2|
// \|
// |\
// 3 |0\ 1
//----------
// 4 | 5 \ 6
*/
if (u + v <= det) {
if (u < 0) {
if (v < 0) {
// region 4
if (d < 0) {
if (a <= -d) {
// u = 1;
// v = 0;
T sqrDist = a + 2*d + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
u = -d/a;
// v = 0;
T sqrDist = d*u + baseDist2;
return sqrDist <= sphere.getRadius2();
}
} else {
if (0 < e) {
// u = 0;
// v = 0;
return baseDist2 <= sphere.getRadius2();
} else if (c <= -e) {
// u = 0;
// v = 1;
T sqrDist = c + 2*e + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
// u = 0;
v = -e/c;
T sqrDist = e*v + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
} else {
// region 3
if (0 <= e) {
// u = 0;
// v = 0;
return baseDist2 <= sphere.getRadius2();
} else if (c <= -e) {
// u = 0;
// v = 1;
T sqrDist = c + 2*e + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
// u = 0;
v = -e/c;
T sqrDist = e*v + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
} else if (v < 0) {
// region 5
if (0 <= d) {
// u = 0;
// v = 0;
return baseDist2 <= sphere.getRadius2();
} else if (a <= -d) {
// u = 1;
// v = 0;
T sqrDist = a + 2*d + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
u = -d/a;
// v = 0;
T sqrDist = d*u + baseDist2;
return sqrDist <= sphere.getRadius2();
}
} else {
// region 0
if (det <= SGLimits<T>::min()) {
// sqrDist = baseDist2;
u = 0;
v = 0;
return baseDist2 <= sphere.getRadius2();
} else {
T invDet = 1/det;
u *= invDet;
v *= invDet;
T sqrDist = u*(a*u + b*v + 2*d) + v*(b*u + c*v + 2*e) + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
} else {
if (u < 0) {
// region 2
T tmp0 = b + d;
T tmp1 = c + e;
if (tmp0 < tmp1) {
T numer = tmp1 - tmp0;
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 1;
// v = 0;
T sqrDist = a + 2*d + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
u = numer/denom;
v = 1 - u;
T sqrDist = u*(a*u + b*v + 2*d) + v*(b*u + c*v + 2*e) + baseDist2;
return sqrDist <= sphere.getRadius2();
}
} else {
if (tmp1 <= 0) {
// u = 0;
// v = 1;
T sqrDist = c + 2*e + baseDist2;
return sqrDist <= sphere.getRadius2();
} else if (0 <= e) {
// u = 0;
// v = 0;
return baseDist2 <= sphere.getRadius2();
} else {
// u = 0;
v = -e/c;
T sqrDist = e*v + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
} else if (v < 0) {
// region 6
T tmp0 = b + e;
T tmp1 = a + d;
if (tmp0 < tmp1) {
T numer = tmp1 - tmp0;
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 0;
// v = 1;
T sqrDist = c + 2*e + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
v = numer/denom;
u = 1 - v;
T sqrDist = u*(a*u + b*v + 2*d) + v*(b*u + c*v + 2*e)+baseDist2;
return sqrDist <= sphere.getRadius2();
}
} else {
if (tmp1 < 0) {
// u = 1;
// v = 0;
T sqrDist = a + 2*d + baseDist2;
return sqrDist <= sphere.getRadius2();
} else if (0 <= d) {
// sqrDist = baseDist2;
// u = 0;
// v = 0;
return baseDist2 <= sphere.getRadius2();
} else {
u = -d/a;
// v = 0;
T sqrDist = d*u + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
} else {
// region 1
T numer = c + e - b - d;
if (numer <= 0) {
// u = 0;
// v = 1;
T sqrDist = c + 2*e + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
T denom = a - 2*b + c;
if (denom <= numer) {
// u = 1;
// v = 0;
T sqrDist = a + 2*d + baseDist2;
return sqrDist <= sphere.getRadius2();
} else {
u = numer/denom;
v = 1 - u;
T sqrDist = u*(a*u + b*v + 2*d) + v*(b*u + c*v + 2*e) + baseDist2;
return sqrDist <= sphere.getRadius2();
}
}
}
}
}
template<typename T1, typename T2>
inline bool
intersects(const SGSphere<T1>& sphere, const SGTriangle<T2>& tri)
{ return intersects(tri, sphere); }
template<typename T> template<typename T>
inline bool inline bool
intersects(const SGVec3<T>& v, const SGSphere<T>& sphere) intersects(const SGVec3<T>& v, const SGSphere<T>& sphere)
@@ -557,9 +985,9 @@ intersects(const SGBox<T>& box, const SGLineSegment<T>& lineSegment)
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering // See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
SGVec3<T> c = lineSegment.getCenter() - box.getCenter(); SGVec3<T> c = lineSegment.getCenter() - box.getCenter();
SGVec3<T> w = 0.5*lineSegment.getDirection(); SGVec3<T> w = T(0.5)*lineSegment.getDirection();
SGVec3<T> v(fabs(w.x()), fabs(w.y()), fabs(w.z())); SGVec3<T> v(fabs(w.x()), fabs(w.y()), fabs(w.z()));
SGVec3<T> h = 0.5*box.getSize(); SGVec3<T> h = T(0.5)*box.getSize();
if (fabs(c[0]) > v[0] + h[0]) if (fabs(c[0]) > v[0] + h[0])
return false; return false;
@@ -624,4 +1052,26 @@ inline bool
intersects(const SGRay<T>& ray, const SGBox<T>& box) intersects(const SGRay<T>& ray, const SGBox<T>& box)
{ return intersects(box, ray); } { return intersects(box, ray); }
template<typename T1, typename T2>
inline bool
intersects(const SGBox<T1>& box1, const SGBox<T2>& box2)
{
if (box2.getMax()[0] < box1.getMin()[0])
return false;
if (box1.getMax()[0] < box2.getMin()[0])
return false;
if (box2.getMax()[1] < box1.getMin()[1])
return false;
if (box1.getMax()[1] < box2.getMin()[1])
return false;
if (box2.getMax()[2] < box1.getMin()[2])
return false;
if (box1.getMax()[2] < box2.getMin()[2])
return false;
return true;
}
#endif #endif
+13
View File
@@ -27,6 +27,11 @@ public:
_start(start), _start(start),
_direction(end - start) _direction(end - start)
{ } { }
template<typename S>
explicit SGLineSegment(const SGLineSegment<S>& lineSegment) :
_start(lineSegment.getStart()),
_direction(lineSegment.getDirection())
{ }
void set(const SGVec3<T>& start, const SGVec3<T>& end) void set(const SGVec3<T>& start, const SGVec3<T>& end)
{ _start = start; _direction = end - start; } { _start = start; _direction = end - start; }
@@ -43,6 +48,14 @@ public:
SGVec3<T> getCenter() const SGVec3<T> getCenter() const
{ return _start + T(0.5)*_direction; } { return _start + T(0.5)*_direction; }
SGLineSegment<T> transform(const SGMatrix<T>& matrix) const
{
SGLineSegment<T> lineSegment;
lineSegment._start = matrix.xformPt(_start);
lineSegment._direction = matrix.xformVec(_direction);
return lineSegment;
}
private: private:
SGVec3<T> _start; SGVec3<T> _start;
SGVec3<T> _direction; SGVec3<T> _direction;
+17 -7
View File
@@ -174,16 +174,22 @@ MatrixTest(void)
// Create some test matrix // Create some test matrix
SGVec3<T> v0(2, 7, 17); SGVec3<T> v0(2, 7, 17);
SGQuat<T> q0 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), normalize(v0)); SGQuat<T> q0 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), normalize(v0));
SGMatrix<T> m0; SGMatrix<T> m0 = SGMatrix<T>::unit();
m0.postMultTranslate(v0); m0.postMultTranslate(v0);
m0.postMultRotate(q0); m0.postMultRotate(q0);
// Check the tqo forms of the inverse for that kind of special matrix // Check the three forms of the inverse for that kind of special matrix
SGMatrix<T> m1, m2; SGMatrix<T> m1 = SGMatrix<T>::unit();
invert(m1, m0); m1.preMultTranslate(-v0);
m2 = transNeg(m0); m1.preMultRotate(inverse(q0));
SGMatrix<T> m2, m3;
invert(m2, m0);
m3 = transNeg(m0);
if (!equivalent(m1, m2)) if (!equivalent(m1, m2))
return false; return false;
if (!equivalent(m2, m3))
return false;
// Check matrix multiplication and inversion // Check matrix multiplication and inversion
if (!equivalent(m0*m1, SGMatrix<T>::unit())) if (!equivalent(m0*m1, SGMatrix<T>::unit()))
@@ -194,6 +200,10 @@ MatrixTest(void)
return false; return false;
if (!equivalent(m2*m0, SGMatrix<T>::unit())) if (!equivalent(m2*m0, SGMatrix<T>::unit()))
return false; return false;
if (!equivalent(m0*m3, SGMatrix<T>::unit()))
return false;
if (!equivalent(m3*m0, SGMatrix<T>::unit()))
return false;
return true; return true;
} }
@@ -202,10 +212,10 @@ bool
GeodesyTest(void) GeodesyTest(void)
{ {
// We know that the values are on the order of 1 // We know that the values are on the order of 1
double epsDeg = 10*SGLimits<double>::epsilon(); double epsDeg = 10*360*SGLimits<double>::epsilon();
// For the altitude values we need to tolerate relative errors in the order // For the altitude values we need to tolerate relative errors in the order
// of the radius // of the radius
double epsM = 1e6*SGLimits<double>::epsilon(); double epsM = 10*6e6*SGLimits<double>::epsilon();
SGVec3<double> cart0, cart1; SGVec3<double> cart0, cart1;
SGGeod geod0, geod1; SGGeod geod0, geod1;
+10 -3
View File
@@ -184,8 +184,15 @@ public:
template<typename S> template<typename S>
SGMatrix& preMultTranslate(const SGVec3<S>& t) SGMatrix& preMultTranslate(const SGVec3<S>& t)
{ {
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i) for (unsigned i = 0; i < 3; ++i) {
(*this)(i,3) += T(t(i)); T tmp = T(t(i));
if (tmp == 0)
continue;
(*this)(i,0) += tmp*(*this)(3,0);
(*this)(i,1) += tmp*(*this)(3,1);
(*this)(i,2) += tmp*(*this)(3,2);
(*this)(i,3) += tmp*(*this)(3,3);
}
return *this; return *this;
} }
template<typename S> template<typename S>
@@ -193,7 +200,7 @@ public:
{ {
SGVec4<T> col3((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3)); 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) { 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)); SGVec4<T> tmp((*this)(0,i), (*this)(1,i), (*this)(2,i), (*this)(3,i));
col3 += T(t(i))*tmp; col3 += T(t(i))*tmp;
} }
(*this)(0,3) = col3(0); (*this)(1,3) = col3(1); (*this)(0,3) = col3(0); (*this)(1,3) = col3(1);
+16 -1
View File
@@ -23,14 +23,25 @@ class SGPlane {
public: public:
SGPlane() SGPlane()
{ } { }
SGPlane(const SGVec3<T>& normal, T dist) : SGPlane(const SGVec3<T>& normal, const T& dist) :
_normal(normal), _dist(dist) _normal(normal), _dist(dist)
{ } { }
SGPlane(const SGVec3<T>& normal, const SGVec3<T>& point) :
_normal(normal), _dist(-dot(normal, point))
{ }
SGPlane(const SGVec3<T> vertices[3]) : SGPlane(const SGVec3<T> vertices[3]) :
_normal(normalize(cross(vertices[1] - vertices[0], _normal(normalize(cross(vertices[1] - vertices[0],
vertices[2] - vertices[0]))), vertices[2] - vertices[0]))),
_dist(-dot(_normal, vertices[0])) _dist(-dot(_normal, vertices[0]))
{ } { }
SGPlane(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2) :
_normal(normalize(cross(v1 - v0, v2 - v0))),
_dist(-dot(_normal, v0))
{ }
template<typename S>
explicit SGPlane(const SGPlane<S>& plane) :
_normal(plane.getNormal()), _dist(plane.getDist())
{ }
void setNormal(const SGVec3<T>& normal) void setNormal(const SGVec3<T>& normal)
{ _normal = normal; } { _normal = normal; }
@@ -42,6 +53,10 @@ public:
const T& getDist() const const T& getDist() const
{ return _dist; } { return _dist; }
/// Return a point on the plane
SGVec3<T> getPointOnPlane() const
{ return -_dist*_normal; }
/// That is the distance where we measure positive in direction of the normal /// That is the distance where we measure positive in direction of the normal
T getPositiveDist() const T getPositiveDist() const
{ return -_dist; } { return -_dist; }
+52 -110
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de // Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -26,42 +26,13 @@
#undef max #undef max
#endif #endif
#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include <osg/Quat> #include <osg/Quat>
#endif
/// Quaternion Class
template<typename T> template<typename T>
struct SGQuatStorage { class SGQuat {
/// 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: public:
typedef T value_type; typedef T value_type;
@@ -84,8 +55,6 @@ public:
/// make sure it has at least 4 elements /// make sure it has at least 4 elements
explicit SGQuat(const T* d) explicit SGQuat(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } { 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 /// Return a unit quaternion
static SGQuat unit(void) static SGQuat unit(void)
@@ -158,48 +127,11 @@ public:
static SGQuat fromLonLat(const SGGeod& geod) static SGQuat fromLonLat(const SGGeod& geod)
{ return fromLonLatRad(geod.getLongitudeRad(), geod.getLatitudeRad()); } { 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 /// Create a quaternion from the angle axis representation
static SGQuat fromAngleAxis(T angle, const SGVec3<T>& axis) static SGQuat fromAngleAxis(T angle, const SGVec3<T>& axis)
{ {
T angle2 = 0.5*angle; T angle2 = T(0.5)*angle;
return fromRealImag(cos(angle2), T(sin(angle2))*axis); return fromRealImag(cos(angle2), T(sin(angle2))*axis);
} }
@@ -213,34 +145,36 @@ public:
{ {
T nAxis = norm(axis); T nAxis = norm(axis);
if (nAxis <= SGLimits<T>::min()) if (nAxis <= SGLimits<T>::min())
return SGQuat(1, 0, 0, 0); return SGQuat::unit();
T angle2 = 0.5*nAxis; T angle2 = T(0.5)*nAxis;
return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis); return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis);
} }
/// Return a quaternion that rotates the from vector onto the to vector.
static SGQuat fromRotateTo(const SGVec3<T>& from, const SGVec3<T>& to) static SGQuat fromRotateTo(const SGVec3<T>& from, const SGVec3<T>& to)
{ {
T nfrom = norm(from); T nfrom = norm(from);
T nto = norm(to); T nto = norm(to);
if (nfrom < SGLimits<T>::min() || nto < SGLimits<T>::min()) if (nfrom <= SGLimits<T>::min() || nto <= SGLimits<T>::min())
return SGQuat::unit(); return SGQuat::unit();
return SGQuat::fromRotateToNorm((1/nfrom)*from, (1/nto)*to); return SGQuat::fromRotateToNorm((1/nfrom)*from, (1/nto)*to);
} }
// FIXME more finegrained error behavour. /// Return a quaternion that rotates v1 onto the i1-th unit vector
/// and v2 into a plane that is spanned by the i2-th and i1-th unit vector.
static SGQuat fromRotateTo(const SGVec3<T>& v1, unsigned i1, static SGQuat fromRotateTo(const SGVec3<T>& v1, unsigned i1,
const SGVec3<T>& v2, unsigned i2) const SGVec3<T>& v2, unsigned i2)
{ {
T nrmv1 = norm(v1); T nrmv1 = norm(v1);
T nrmv2 = norm(v2); T nrmv2 = norm(v2);
if (nrmv1 < SGLimits<T>::min() || nrmv2 < SGLimits<T>::min()) if (nrmv1 <= SGLimits<T>::min() || nrmv2 <= SGLimits<T>::min())
return SGQuat::unit(); return SGQuat::unit();
SGVec3<T> nv1 = (1/nrmv1)*v1; SGVec3<T> nv1 = (1/nrmv1)*v1;
SGVec3<T> nv2 = (1/nrmv2)*v2; SGVec3<T> nv2 = (1/nrmv2)*v2;
T dv1v2 = dot(nv1, nv2); T dv1v2 = dot(nv1, nv2);
if (fabs(fabs(dv1v2)-1) < SGLimits<T>::epsilon()) if (fabs(fabs(dv1v2)-1) <= SGLimits<T>::epsilon())
return SGQuat::unit(); return SGQuat::unit();
// The target vector for the first rotation // The target vector for the first rotation
@@ -261,12 +195,12 @@ public:
SGVec3<T> tnv2 = q.transform(nv2); SGVec3<T> tnv2 = q.transform(nv2);
T cosang = dot(nto2, tnv2); T cosang = dot(nto2, tnv2);
T cos05ang = T(0.5+0.5*cosang); T cos05ang = T(0.5)+T(0.5)*cosang;
if (cos05ang <= 0) if (cos05ang <= 0)
cosang = T(0); cosang = 0;
cos05ang = sqrt(cos05ang); cos05ang = sqrt(cos05ang);
T sig = dot(nto1, cross(nto2, tnv2)); T sig = dot(nto1, cross(nto2, tnv2));
T sin05ang = T(0.5-0.5*cosang); T sin05ang = T(0.5)-T(0.5)*cosang;
if (sin05ang <= 0) if (sin05ang <= 0)
sin05ang = 0; sin05ang = 0;
sin05ang = copysign(sqrt(sin05ang), sig); sin05ang = copysign(sqrt(sin05ang), sig);
@@ -329,24 +263,24 @@ public:
T num = 2*(y()*z() + w()*x()); T num = 2*(y()*z() + w()*x());
T den = sqrQW - sqrQX - sqrQY + sqrQZ; T den = sqrQW - sqrQX - sqrQY + sqrQZ;
if (fabs(den) < SGLimits<T>::min() && if (fabs(den) <= SGLimits<T>::min() &&
fabs(num) < SGLimits<T>::min()) fabs(num) <= SGLimits<T>::min())
xRad = 0; xRad = 0;
else else
xRad = atan2(num, den); xRad = atan2(num, den);
T tmp = 2*(x()*z() - w()*y()); T tmp = 2*(x()*z() - w()*y());
if (tmp < -1) if (tmp <= -1)
yRad = 0.5*SGMisc<T>::pi(); yRad = T(0.5)*SGMisc<T>::pi();
else if (1 < tmp) else if (1 <= tmp)
yRad = -0.5*SGMisc<T>::pi(); yRad = -T(0.5)*SGMisc<T>::pi();
else else
yRad = -asin(tmp); yRad = -asin(tmp);
num = 2*(x()*y() + w()*z()); num = 2*(x()*y() + w()*z());
den = sqrQW + sqrQX - sqrQY - sqrQZ; den = sqrQW + sqrQX - sqrQY - sqrQZ;
if (fabs(den) < SGLimits<T>::min() && if (fabs(den) <= SGLimits<T>::min() &&
fabs(num) < SGLimits<T>::min()) fabs(num) <= SGLimits<T>::min())
zRad = 0; zRad = 0;
else { else {
T psi = atan2(num, den); T psi = atan2(num, den);
@@ -369,14 +303,14 @@ public:
void getAngleAxis(T& angle, SGVec3<T>& axis) const void getAngleAxis(T& angle, SGVec3<T>& axis) const
{ {
T nrm = norm(*this); T nrm = norm(*this);
if (nrm < SGLimits<T>::min()) { if (nrm <= SGLimits<T>::min()) {
angle = 0; angle = 0;
axis = SGVec3<T>(0, 0, 0); axis = SGVec3<T>(0, 0, 0);
} else { } else {
T rNrm = 1/nrm; T rNrm = 1/nrm;
angle = acos(SGMisc<T>::max(-1, SGMisc<T>::min(1, rNrm*w()))); angle = acos(SGMisc<T>::max(-1, SGMisc<T>::min(1, rNrm*w())));
T sAng = sin(angle); T sAng = sin(angle);
if (fabs(sAng) < SGLimits<T>::min()) if (fabs(sAng) <= SGLimits<T>::min())
axis = SGVec3<T>(1, 0, 0); axis = SGVec3<T>(1, 0, 0);
else else
axis = (rNrm/sAng)*imag(*this); axis = (rNrm/sAng)*imag(*this);
@@ -432,17 +366,11 @@ public:
{ return data()[3]; } { return data()[3]; }
/// Get the data pointer /// Get the data pointer
using SGQuatStorage<T>::data; const T (&data(void) const)[4]
{ return _data; }
/// Readonly interface function to ssg's sgQuat/sgdQuat /// Get the data pointer
const T (&sg(void) const)[4] T (&data(void))[4]
{ return data(); } { 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 /// Inplace addition
SGQuat& operator+=(const SGQuat& v) SGQuat& operator+=(const SGQuat& v)
@@ -493,10 +421,10 @@ public:
{ {
SGQuat deriv; SGQuat deriv;
deriv.w() = 0.5*(-x()*angVel(0) - y()*angVel(1) - z()*angVel(2)); deriv.w() = T(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.x() = T(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.y() = T(0.5)*( z()*angVel(0) + w()*angVel(1) - x()*angVel(2));
deriv.z() = 0.5*(-y()*angVel(0) + x()*angVel(1) + w()*angVel(2)); deriv.z() = T(0.5)*(-y()*angVel(0) + x()*angVel(1) + w()*angVel(2));
return deriv; return deriv;
} }
@@ -521,7 +449,7 @@ private:
// in the interval [-pi,pi]. That means that 0.5*angle is in the interval // 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. // [-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: // So we do not need to care for egative roots in the following equation:
T cos05ang = sqrt(0.5+0.5*cosang); T cos05ang = sqrt(T(0.5)+T(0.5)*cosang);
// Now our assumption of angles <= 90 deg comes in play. // Now our assumption of angles <= 90 deg comes in play.
@@ -561,6 +489,8 @@ private:
SGQuat q2 = SGQuat::fromRotateToSmaller90Deg(-cosang, -from, to); SGQuat q2 = SGQuat::fromRotateToSmaller90Deg(-cosang, -from, to);
return q1*q2; return q1*q2;
} }
T _data[4];
}; };
/// Unary +, do nothing ... /// Unary +, do nothing ...
@@ -759,7 +689,7 @@ interpolate(T t, const SGQuat<T>& src, const SGQuat<T>& dst)
// need the scales now, if the angle is very small, do linear interpolation // need the scales now, if the angle is very small, do linear interpolation
// to avoid instabilities // to avoid instabilities
T scale0, scale1; T scale0, scale1;
if (fabs(o) < SGLimits<T>::epsilon()) { if (fabs(o) <= SGLimits<T>::epsilon()) {
scale0 = 1 - t; scale0 = 1 - t;
scale1 = t; scale1 = t;
} else { } else {
@@ -790,4 +720,16 @@ SGQuatd
toQuatd(const SGQuatf& v) toQuatd(const SGQuatf& v)
{ return SGQuatd(v(0), v(1), v(2), v(3)); } { return SGQuatd(v(0), v(1), v(2), v(3)); }
#ifndef NO_OPENSCENEGRAPH_INTERFACE
inline
SGQuatd
toSG(const osg::Quat& q)
{ return SGQuatd(q[0], q[1], q[2], q[3]); }
inline
osg::Quat
toOsg(const SGQuatd& q)
{ return osg::Quat(q[0], q[1], q[2], q[3]); }
#endif
#endif #endif
+4
View File
@@ -26,6 +26,10 @@ public:
SGRay(const SGVec3<T>& origin, const SGVec3<T>& dir) : SGRay(const SGVec3<T>& origin, const SGVec3<T>& dir) :
_origin(origin), _direction(dir) _origin(origin), _direction(dir)
{ } { }
template<typename S>
explicit SGRay(const SGRay<S>& ray) :
_origin(ray.getOrigin()), _direction(ray.getDirection())
{ }
void set(const SGVec3<T>& origin, const SGVec3<T>& dir) void set(const SGVec3<T>& origin, const SGVec3<T>& dir)
{ _origin = origin; _direction = dir; } { _origin = origin; _direction = dir; }
+65 -1
View File
@@ -28,6 +28,11 @@ public:
_center(center), _center(center),
_radius(radius) _radius(radius)
{ } { }
template<typename S>
explicit SGSphere(const SGSphere<S>& sphere) :
_center(sphere.getCenter()),
_radius(sphere.getRadius())
{ }
const SGVec3<T>& getCenter() const const SGVec3<T>& getCenter() const
{ return _center; } { return _center; }
@@ -41,7 +46,7 @@ public:
T getRadius2() const T getRadius2() const
{ return _radius*_radius; } { return _radius*_radius; }
const bool empty() const bool empty() const
{ return !valid(); } { return !valid(); }
bool valid() const bool valid() const
@@ -68,6 +73,65 @@ public:
_radius = newRadius; _radius = newRadius;
} }
void expandBy(const SGSphere<T>& s)
{
if (s.empty())
return;
if (empty()) {
_center = s.getCenter();
_radius = s.getRadius();
return;
}
T dist = length(_center - s.getCenter());
if (dist <= SGLimits<T>::min()) {
_radius = SGMisc<T>::max(_radius, s._radius);
return;
}
// already included
if (dist + s.getRadius() <= _radius)
return;
// new one includes all
if (dist + _radius <= s.getRadius()) {
_center = s.getCenter();
_radius = s.getRadius();
return;
}
T newRadius = T(0.5)*(_radius + dist + s.getRadius());
T ratio = (newRadius - _radius) / dist;
_radius = newRadius;
_center[0] += ratio*(s._center[0] - _center[0]);
_center[1] += ratio*(s._center[1] - _center[1]);
_center[2] += ratio*(s._center[2] - _center[2]);
}
void expandBy(const SGBox<T>& box)
{
if (box.empty())
return;
if (empty()) {
_center = box.getCenter();
_radius = T(0.5)*length(box.getSize());
return;
}
SGVec3<T> boxCenter = box.getCenter();
SGVec3<T> corner;
for (unsigned i = 0; i < 3; ++i) {
if (_center[i] < boxCenter[i])
corner[i] = box.getMax()[i];
else
corner[i] = box.getMin()[i];
}
expandBy(corner);
}
private: private:
SGVec3<T> _center; SGVec3<T> _center;
T _radius; T _radius;
+12 -8
View File
@@ -41,14 +41,8 @@ public:
_d[1] = v[2] - v[0]; _d[1] = v[2] - v[0];
} }
SGVec3d getCenter() const SGVec3<T> getCenter() const
{ { return _v0 + T(1)/T(3)*(_d[0] + _d[1]); }
SGBoxd box;
box.expandBy(_v0);
box.expandBy(_v0 + _d[0]);
box.expandBy(_v0 + _d[1]);
return box.getCenter();
}
// note that the index is unchecked // note that the index is unchecked
SGVec3<T> getVertex(unsigned i) const SGVec3<T> getVertex(unsigned i) const
@@ -77,6 +71,16 @@ public:
_d[0] = _d[1]; _d[0] = _d[1];
_d[1] = tmp; _d[1] = tmp;
} }
SGTriangle<T> transform(const SGMatrix<T>& matrix) const
{
SGTriangle<T> triangle;
triangle._v0 = matrix.xformPt(_v0);
triangle._d[0] = matrix.xformVec(_d[0]);
triangle._d[1] = matrix.xformVec(_d[1]);
return triangle;
}
private: private:
/// Store one vertex directly, _d is the offset of the other two /// Store one vertex directly, _d is the offset of the other two
/// vertices wrt the base vertex /// vertices wrt the base vertex
+56 -64
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de // Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -22,58 +22,14 @@
#include <ieeefp.h> #include <ieeefp.h>
#endif #endif
#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include <osg/Vec2f> #include <osg/Vec2f>
#include <osg/Vec2d> #include <osg/Vec2d>
#endif
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 /// 2D Vector Class
template<typename T> template<typename T>
class SGVec2 : protected SGVec2Storage<T> { class SGVec2 {
public: public:
typedef T value_type; typedef T value_type;
@@ -96,9 +52,8 @@ public:
/// make sure it has at least 2 elements /// make sure it has at least 2 elements
explicit SGVec2(const T* d) explicit SGVec2(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; } { data()[0] = d[0]; data()[1] = d[1]; }
explicit SGVec2(const osg::Vec2f& d) template<typename S>
{ data()[0] = d[0]; data()[1] = d[1]; } explicit SGVec2(const SGVec2<S>& d)
explicit SGVec2(const osg::Vec2d& d)
{ data()[0] = d[0]; data()[1] = d[1]; } { data()[0] = d[0]; data()[1] = d[1]; }
/// Access by index, the index is unchecked /// Access by index, the index is unchecked
@@ -128,18 +83,12 @@ public:
T& y(void) T& y(void)
{ return data()[1]; } { return data()[1]; }
/// Get the data pointer /// Access raw data
using SGVec2Storage<T>::data; const T (&data(void) const)[2]
{ return _data; }
/// Readonly interface function to ssg's sgVec2/sgdVec2 /// Access raw data
const T (&sg(void) const)[2] T (&data(void))[2]
{ return data(); } { 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 /// Inplace addition
SGVec2& operator+=(const SGVec2& v) SGVec2& operator+=(const SGVec2& v)
@@ -164,6 +113,9 @@ public:
{ return SGVec2(1, 0); } { return SGVec2(1, 0); }
static SGVec2 e2(void) static SGVec2 e2(void)
{ return SGVec2(0, 1); } { return SGVec2(0, 1); }
private:
T _data[2];
}; };
/// Unary +, do nothing ... /// Unary +, do nothing ...
@@ -292,7 +244,12 @@ template<typename T>
inline inline
SGVec2<T> SGVec2<T>
normalize(const SGVec2<T>& v) normalize(const SGVec2<T>& v)
{ return (1/norm(v))*v; } {
T normv = norm(v);
if (normv <= SGLimits<T>::min())
return SGVec2<T>::zeros();
return (1/normv)*v;
}
/// Return true if exactly the same /// Return true if exactly the same
template<typename T> template<typename T>
@@ -379,6 +336,18 @@ T
distSqr(const SGVec2<T>& v1, const SGVec2<T>& v2) distSqr(const SGVec2<T>& v1, const SGVec2<T>& v2)
{ SGVec2<T> tmp = v1 - v2; return dot(tmp, tmp); } { SGVec2<T> tmp = v1 - v2; return dot(tmp, tmp); }
// calculate the projection of u along the direction of d.
template<typename T>
inline
SGVec2<T>
projection(const SGVec2<T>& u, const SGVec2<T>& d)
{
T denom = dot(d, d);
T ud = dot(u, d);
if (SGLimits<T>::min() < denom) return u;
else return d * (dot(u, d) / denom);
}
#ifndef NDEBUG #ifndef NDEBUG
template<typename T> template<typename T>
inline inline
@@ -406,4 +375,27 @@ SGVec2d
toVec2d(const SGVec2f& v) toVec2d(const SGVec2f& v)
{ return SGVec2d(v(0), v(1)); } { return SGVec2d(v(0), v(1)); }
#ifndef NO_OPENSCENEGRAPH_INTERFACE
inline
SGVec2d
toSG(const osg::Vec2d& v)
{ return SGVec2d(v[0], v[1]); }
inline
SGVec2f
toSG(const osg::Vec2f& v)
{ return SGVec2f(v[0], v[1]); }
inline
osg::Vec2d
toOsg(const SGVec2d& v)
{ return osg::Vec2d(v[0], v[1]); }
inline
osg::Vec2f
toOsg(const SGVec2f& v)
{ return osg::Vec2f(v[0], v[1]); }
#endif
#endif #endif
+57 -65
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de // Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -18,58 +18,14 @@
#ifndef SGVec3_H #ifndef SGVec3_H
#define SGVec3_H #define SGVec3_H
#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/Vec3d> #include <osg/Vec3d>
#endif
template<typename T>
struct SGVec3Storage {
/// Readonly raw storage interface
const T (&data(void) const)[3]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[3]
{ return _data; }
void osg() const
{ }
private:
T _data[3];
};
template<>
struct SGVec3Storage<float> : public osg::Vec3f {
/// Access raw data by index, the index is unchecked
const float (&data(void) const)[3]
{ return osg::Vec3f::_v; }
/// Access raw data by index, the index is unchecked
float (&data(void))[3]
{ return osg::Vec3f::_v; }
const osg::Vec3f& osg() const
{ return *this; }
osg::Vec3f& osg()
{ return *this; }
};
template<>
struct SGVec3Storage<double> : public osg::Vec3d {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[3]
{ return osg::Vec3d::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[3]
{ return osg::Vec3d::_v; }
const osg::Vec3d& osg() const
{ return *this; }
osg::Vec3d& osg()
{ return *this; }
};
/// 3D Vector Class /// 3D Vector Class
template<typename T> template<typename T>
class SGVec3 : protected SGVec3Storage<T> { class SGVec3 {
public: public:
typedef T value_type; typedef T value_type;
@@ -92,9 +48,8 @@ public:
/// make sure it has at least 3 elements /// make sure it has at least 3 elements
explicit SGVec3(const T* d) explicit SGVec3(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
explicit SGVec3(const osg::Vec3f& d) template<typename S>
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } explicit SGVec3(const SGVec3<S>& d)
explicit SGVec3(const osg::Vec3d& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
explicit SGVec3(const SGVec2<T>& v2, const T& v3 = 0) explicit SGVec3(const SGVec2<T>& v2, const T& v3 = 0)
{ data()[0] = v2[0]; data()[1] = v2[1]; data()[2] = v3; } { data()[0] = v2[0]; data()[1] = v2[1]; data()[2] = v3; }
@@ -132,18 +87,12 @@ public:
T& z(void) T& z(void)
{ return data()[2]; } { return data()[2]; }
/// Get the data pointer /// Readonly raw storage interface
using SGVec3Storage<T>::data; const T (&data(void) const)[3]
{ return _data; }
/// Readonly interface function to ssg's sgVec3/sgdVec3 /// Readonly raw storage interface
const T (&sg(void) const)[3] T (&data(void))[3]
{ return data(); } { return _data; }
/// Interface function to ssg's sgVec3/sgdVec3
T (&sg(void))[3]
{ return data(); }
/// Interface function to osg's Vec3*
using SGVec3Storage<T>::osg;
/// Inplace addition /// Inplace addition
SGVec3& operator+=(const SGVec3& v) SGVec3& operator+=(const SGVec3& v)
@@ -177,6 +126,9 @@ public:
/// Constructor. Initialize by a geocentric coordinate /// Constructor. Initialize by a geocentric coordinate
/// Note that this conversion is relatively expensive to compute /// Note that this conversion is relatively expensive to compute
static SGVec3 fromGeoc(const SGGeoc& geoc); static SGVec3 fromGeoc(const SGGeoc& geoc);
private:
T _data[3];
}; };
template<> template<>
@@ -400,12 +352,18 @@ perpendicular(const SGVec3<T>& v)
} }
} }
/// The euclidean norm of the vector, that is what most people call length /// Construct a unit vector in the given direction.
/// or the zero vector if the input vector is zero.
template<typename T> template<typename T>
inline inline
SGVec3<T> SGVec3<T>
normalize(const SGVec3<T>& v) normalize(const SGVec3<T>& v)
{ return (1/norm(v))*v; } {
T normv = norm(v);
if (normv <= SGLimits<T>::min())
return SGVec3<T>::zeros();
return (1/normv)*v;
}
/// Return true if exactly the same /// Return true if exactly the same
template<typename T> template<typename T>
@@ -496,6 +454,18 @@ T
distSqr(const SGVec3<T>& v1, const SGVec3<T>& v2) distSqr(const SGVec3<T>& v1, const SGVec3<T>& v2)
{ SGVec3<T> tmp = v1 - v2; return dot(tmp, tmp); } { SGVec3<T> tmp = v1 - v2; return dot(tmp, tmp); }
// calculate the projection of u along the direction of d.
template<typename T>
inline
SGVec3<T>
projection(const SGVec3<T>& u, const SGVec3<T>& d)
{
T denom = dot(d, d);
T ud = dot(u, d);
if (SGLimits<T>::min() < denom) return u;
else return d * (dot(u, d) / denom);
}
#ifndef NDEBUG #ifndef NDEBUG
template<typename T> template<typename T>
inline inline
@@ -524,4 +494,26 @@ SGVec3d
toVec3d(const SGVec3f& v) toVec3d(const SGVec3f& v)
{ return SGVec3d(v(0), v(1), v(2)); } { return SGVec3d(v(0), v(1), v(2)); }
#ifndef NO_OPENSCENEGRAPH_INTERFACE
inline
SGVec3d
toSG(const osg::Vec3d& v)
{ return SGVec3d(v[0], v[1], v[2]); }
inline
SGVec3f
toSG(const osg::Vec3f& v)
{ return SGVec3f(v[0], v[1], v[2]); }
inline
osg::Vec3d
toOsg(const SGVec3d& v)
{ return osg::Vec3d(v[0], v[1], v[2]); }
inline
osg::Vec3f
toOsg(const SGVec3f& v)
{ return osg::Vec3f(v[0], v[1], v[2]); }
#endif
#endif #endif
+55 -65
View File
@@ -1,4 +1,4 @@
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de // Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -18,58 +18,14 @@
#ifndef SGVec4_H #ifndef SGVec4_H
#define SGVec4_H #define SGVec4_H
#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include <osg/Vec4f> #include <osg/Vec4f>
#include <osg/Vec4d> #include <osg/Vec4d>
#endif
template<typename T>
struct SGVec4Storage {
/// 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 SGVec4Storage<float> : public osg::Vec4f {
/// Access raw data by index, the index is unchecked
const float (&data(void) const)[4]
{ return osg::Vec4f::_v; }
/// Access raw data by index, the index is unchecked
float (&data(void))[4]
{ return osg::Vec4f::_v; }
const osg::Vec4f& osg() const
{ return *this; }
osg::Vec4f& osg()
{ return *this; }
};
template<>
struct SGVec4Storage<double> : public osg::Vec4d {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[4]
{ return osg::Vec4d::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[4]
{ return osg::Vec4d::_v; }
const osg::Vec4d& osg() const
{ return *this; }
osg::Vec4d& osg()
{ return *this; }
};
/// 4D Vector Class /// 4D Vector Class
template<typename T> template<typename T>
class SGVec4 : protected SGVec4Storage<T> { class SGVec4 {
public: public:
typedef T value_type; typedef T value_type;
@@ -92,14 +48,12 @@ public:
/// make sure it has at least 3 elements /// make sure it has at least 3 elements
explicit SGVec4(const T* d) explicit SGVec4(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGVec4(const osg::Vec4f& d) template<typename S>
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } explicit SGVec4(const SGVec4<S>& d)
explicit SGVec4(const osg::Vec4d& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGVec4(const SGVec3<T>& v3, const T& v4 = 0) explicit SGVec4(const SGVec3<T>& v3, const T& v4 = 0)
{ data()[0] = v3[0]; data()[1] = v3[1]; data()[2] = v3[2]; data()[3] = v4; } { data()[0] = v3[0]; data()[1] = v3[1]; data()[2] = v3[2]; data()[3] = v4; }
/// Access by index, the index is unchecked /// Access by index, the index is unchecked
const T& operator()(unsigned i) const const T& operator()(unsigned i) const
{ return data()[i]; } { return data()[i]; }
@@ -139,18 +93,12 @@ public:
T& w(void) T& w(void)
{ return data()[3]; } { return data()[3]; }
/// Get the data pointer /// Readonly raw storage interface
using SGVec4Storage<T>::data; const T (&data(void) const)[4]
{ return _data; }
/// Readonly interface function to ssg's sgVec4/sgdVec4 /// Readonly raw storage interface
const T (&sg(void) const)[4] T (&data(void))[4]
{ return data(); } { return _data; }
/// Interface function to ssg's sgVec4/sgdVec4
T (&sg(void))[4]
{ return data(); }
/// Interface function to osg's Vec4*
using SGVec4Storage<T>::osg;
/// Inplace addition /// Inplace addition
SGVec4& operator+=(const SGVec4& v) SGVec4& operator+=(const SGVec4& v)
@@ -179,6 +127,9 @@ public:
{ return SGVec4(0, 0, 1, 0); } { return SGVec4(0, 0, 1, 0); }
static SGVec4 e4(void) static SGVec4 e4(void)
{ return SGVec4(0, 0, 0, 1); } { return SGVec4(0, 0, 0, 1); }
private:
T _data[4];
}; };
/// Unary +, do nothing ... /// Unary +, do nothing ...
@@ -337,7 +288,12 @@ template<typename T>
inline inline
SGVec4<T> SGVec4<T>
normalize(const SGVec4<T>& v) normalize(const SGVec4<T>& v)
{ return (1/norm(v))*v; } {
T normv = norm(v);
if (normv <= SGLimits<T>::min())
return SGVec4<T>::zeros();
return (1/normv)*v;
}
/// Return true if exactly the same /// Return true if exactly the same
template<typename T> template<typename T>
@@ -432,6 +388,18 @@ T
distSqr(const SGVec4<T>& v1, const SGVec4<T>& v2) distSqr(const SGVec4<T>& v1, const SGVec4<T>& v2)
{ SGVec4<T> tmp = v1 - v2; return dot(tmp, tmp); } { SGVec4<T> tmp = v1 - v2; return dot(tmp, tmp); }
// calculate the projection of u along the direction of d.
template<typename T>
inline
SGVec4<T>
projection(const SGVec4<T>& u, const SGVec4<T>& d)
{
T denom = dot(d, d);
T ud = dot(u, d);
if (SGLimits<T>::min() < denom) return u;
else return d * (dot(u, d) / denom);
}
#ifndef NDEBUG #ifndef NDEBUG
template<typename T> template<typename T>
inline inline
@@ -460,4 +428,26 @@ SGVec4d
toVec4d(const SGVec4f& v) toVec4d(const SGVec4f& v)
{ return SGVec4d(v(0), v(1), v(2), v(3)); } { return SGVec4d(v(0), v(1), v(2), v(3)); }
#ifndef NO_OPENSCENEGRAPH_INTERFACE
inline
SGVec4d
toSG(const osg::Vec4d& v)
{ return SGVec4d(v[0], v[1], v[2], v[3]); }
inline
SGVec4f
toSG(const osg::Vec4f& v)
{ return SGVec4f(v[0], v[1], v[2], v[3]); }
inline
osg::Vec4d
toOsg(const SGVec4d& v)
{ return osg::Vec4d(v[0], v[1], v[2], v[3]); }
inline
osg::Vec4f
toOsg(const SGVec4f& v)
{ return osg::Vec4f(v[0], v[1], v[2], v[3]); }
#endif
#endif #endif
+105
View File
@@ -0,0 +1,105 @@
/* -*-c++-*-
*
* Copyright (C) 2009 Frederic Bouvier
*
* 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 SIMGEAR_BEZIERCURVE_HXX
#define SIMGEAR_BEZIERCURVE_HXX 1
#include <list>
using std::list;
namespace simgear
{
template<class T>
class BezierCurve {
public:
typedef list<T> PointList;
BezierCurve() : mMaxSubdiv( 3 ) {}
BezierCurve( size_t aMaxSubdiv )
: mMaxSubdiv( aMaxSubdiv ) {}
BezierCurve( const T &p1, const T &p2, const T &p3, size_t aMaxSubdiv = 3 )
: mMaxSubdiv( aMaxSubdiv ) {
subdivide( p1, p2, p3 );
}
BezierCurve( const T &p1, const T &p2, const T &p3, const T &p4, size_t aMaxSubdiv = 3 )
: mMaxSubdiv( aMaxSubdiv ) {
subdivide( p1, p2, p3, p4 );
}
void subdivide( const T &p1, const T &p2, const T &p3 ) {
mPointList.clear();
mPointList.push_back( p1 );
recursiveSubdivide( p1, p2, p3, 1 );
mPointList.push_back( p3 );
}
void subdivide( const T &p1, const T &p2, const T &p3, const T &p4 ) {
mPointList.clear();
mPointList.push_back( p1 );
recursiveSubdivide( p1, p2, p3, p4, 1 );
mPointList.push_back( p4 );
}
void setMaxSubdiv( size_t aMaxSubdiv ) { mMaxSubdiv = aMaxSubdiv; }
void getMaxSubdiv() const { return mMaxSubdiv; }
PointList &pointList() { return mPointList; }
const PointList &pointList() const { return mPointList; }
private:
T midPoint( const T &p1, const T &p2 ) {
return ( p1 + p2 ) / 2;
}
bool recursiveSubdivide( const T &p1, const T &p2, const T &p3, size_t l ) {
if ( l > mMaxSubdiv )
return false;
T p12 = midPoint( p1, p2 ),
p23 = midPoint( p2, p3 ),
p123 = midPoint( p12, p23 );
recursiveSubdivide( p1, p12, p123, l + 1 );
mPointList.push_back( p123 );
recursiveSubdivide( p123, p23, p3, l + 1 );
return true;
}
bool recursiveSubdivide( const T &p1, const T &p2, const T &p3, const T &p4, size_t l ) {
if ( l > mMaxSubdiv )
return false;
T p12 = midPoint( p1, p2 ),
p23 = midPoint( p2, p3 ),
p34 = midPoint( p3, p4 ),
p123 = midPoint( p12, p23 ),
p234 = midPoint( p23, p34 ),
p1234 = midPoint( p123, p234 );
recursiveSubdivide( p1, p12, p123, p1234, l + 1 );
mPointList.push_back( p1234 );
recursiveSubdivide( p1234, p234, p34, p4, l + 1 );
return true;
}
PointList mPointList;
size_t mMaxSubdiv;
};
}
#endif
+5
View File
@@ -22,6 +22,9 @@
// //
// $Id$ // $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h> #include <simgear/compiler.h>
@@ -33,6 +36,8 @@
#include "interpolater.hxx" #include "interpolater.hxx"
#include <simgear/math/SGMath.hxx>
using std::string; using std::string;
// Constructor -- starts with an empty table. // Constructor -- starts with an empty table.
+1 -1
View File
@@ -35,7 +35,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include "simgear/structure/SGReferenced.hxx" #include <simgear/structure/SGReferenced.hxx>
#include <map> #include <map>
+1 -1
View File
@@ -38,7 +38,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <simgear/math/point3d.hxx> class Point3D;
using std::vector; using std::vector;
using std::string; using std::string;
+18 -16
View File
@@ -29,6 +29,20 @@
#include "vector.hxx" #include "vector.hxx"
// calculate the projection, p, of u along the direction of d.
void sgProjection(sgVec3 p, const sgVec3 u, const sgVec3 d){
double denom = sgScalarProductVec3(d,d);
if (denom == 0.) sgCopyVec3(p, u);
else sgScaleVec3(p, d, sgScalarProductVec3(u,d) / denom);
}
// Same thing, except using double precision
void sgProjection(sgdVec3 p, const sgdVec3 u, const sgdVec3 d){
double denom = sgdScalarProductVec3(d,d);
if (denom == 0.) sgdCopyVec3(p, u);
else sgdScaleVec3(p, d, sgdScalarProductVec3(u,d) / denom);
}
// Given a point p, and a line through p0 with direction vector d, // Given a point p, and a line through p0 with direction vector d,
// find the closest point (p1) on the line // find the closest point (p1) on the line
void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0, void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
@@ -40,8 +54,7 @@ void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
sgSubVec3(u, p, p0); sgSubVec3(u, p, p0);
// calculate the projection, u1, of u along d. // calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d; sgProjection(u1, u, d);
sgScaleVec3( u1, d, sgScalarProductVec3(u,d) / sgScalarProductVec3(d,d) );
// calculate the point p1 along the line that is closest to p // calculate the point p1 along the line that is closest to p
// p0 = p1 + u1 // p0 = p1 + u1
@@ -60,12 +73,7 @@ void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
sgdSubVec3(u, p, p0); sgdSubVec3(u, p, p0);
// calculate the projection, u1, of u along d. // calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d; sgProjection(u1, u, d);
double ud = sgdScalarProductVec3(u, d);
double dd = sgdScalarProductVec3(d, d);
double tmp = ud / dd;
sgdScaleVec3(u1, d, tmp);;
// calculate the point p1 along the line that is closest to p // calculate the point p1 along the line that is closest to p
// p0 = p1 + u1 // p0 = p1 + u1
@@ -84,8 +92,7 @@ double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
sgSubVec3(u, p, p0); sgSubVec3(u, p, p0);
// calculate the projection, u1, of u along d. // calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d; sgProjection(u1, u, d);
sgScaleVec3( u1, d, sgScalarProductVec3(u,d) / sgScalarProductVec3(d,d) );
// v = u - u1 = vector from closest point on line, p1, to the // v = u - u1 = vector from closest point on line, p1, to the
// original point, p. // original point, p.
@@ -106,12 +113,7 @@ double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
sgdSubVec3(u, p, p0); sgdSubVec3(u, p, p0);
// calculate the projection, u1, of u along d. // calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d; sgProjection(u1, u, d);
double ud = sgdScalarProductVec3(u, d);
double dd = sgdScalarProductVec3(d, d);
double tmp = ud / dd;
sgdScaleVec3(u1, d, tmp);;
// v = u - u1 = vector from closest point on line, p1, to the // v = u - u1 = vector from closest point on line, p1, to the
// original point, p. // original point, p.
+11 -1
View File
@@ -38,7 +38,17 @@
/** /**
* Map a vector onto a plane. * calculate the projection, p, of u along the direction of d.
* @param p (out) the projection
* @param u (in) the vector to be projected
* @param d (in) the direction onto which we project
*/
void sgProjection(sgVec3 p, const sgVec3 u, const sgVec3 d);
void sgProjection(sgdVec3 p, const sgdVec3 u, const sgdVec3 d);
/**
* Map i.e. project a vector onto a plane.
* @param normal (in) normal vector for the plane * @param normal (in) normal vector for the plane
* @param v0 (in) a point on the plane * @param v0 (in) a point on the plane
* @param vec (in) the vector to map onto the plane * @param vec (in) the vector to map onto the plane
+7 -7
View File
@@ -24,13 +24,13 @@ libsgmisc_a_SOURCES = \
interpolator.cxx \ interpolator.cxx \
PathOptions.cxx PathOptions.cxx
noinst_PROGRAMS = tabbed_value_test swap_test #noinst_PROGRAMS = tabbed_value_test swap_test
tabbed_value_test_SOURCES = tabbed_values_test.cxx #tabbed_value_test_SOURCES = tabbed_values_test.cxx
tabbed_value_test_LDADD = \ #tabbed_value_test_LDADD = \
libsgmisc.a \ # libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \ # $(top_builddir)/simgear/xml/libsgxml.a \
$(top_builddir)/simgear/debug/libsgdebug.a # $(top_builddir)/simgear/debug/libsgdebug.a
$(top_builddir)/simgear/xml/libsgxml.a: $(top_builddir)/simgear/xml/libsgxml.a:
cd $(top_builddir)/simgear/xml && $(MAKE) $(AM_MAKEFLAGS) libsgxml.a cd $(top_builddir)/simgear/xml && $(MAKE) $(AM_MAKEFLAGS) libsgxml.a
@@ -38,6 +38,6 @@ $(top_builddir)/simgear/xml/libsgxml.a:
$(top_builddir)/simgear/debug/libsgdebug.a: $(top_builddir)/simgear/debug/libsgdebug.a:
cd $(top_builddir)/simgear/debug && $(MAKE) $(AM_MAKEFLAGS) libsgdebug.a cd $(top_builddir)/simgear/debug && $(MAKE) $(AM_MAKEFLAGS) libsgdebug.a
swap_test_SOURCES = swap_test.cpp #swap_test_SOURCES = swap_test.cpp
INCLUDES = -I$(top_srcdir) INCLUDES = -I$(top_srcdir)
+2
View File
@@ -18,6 +18,8 @@
#include "interpolator.hxx" #include "interpolator.hxx"
#include <simgear/math/SGMath.hxx>
void SGInterpolator::addNew(SGPropertyNode* prop, int nPoints) void SGInterpolator::addNew(SGPropertyNode* prop, int nPoints)
{ {
// Set the property type to a double, if it isn't already, and // Set the property type to a double, if it isn't already, and
+3
View File
@@ -25,6 +25,9 @@
#include "strutils.hxx" #include "strutils.hxx"
using std::string;
using std::vector;
namespace simgear { namespace simgear {
namespace strutils { namespace strutils {
+8 -12
View File
@@ -30,16 +30,12 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <string> #include <string>
#include <vector> #include <vector>
using std::vector;
#include <cstdlib> #include <cstdlib>
using std::string;
namespace simgear { namespace simgear {
namespace strutils { namespace strutils {
// /** // /**
// * atof() wrapper for "string" type // * atof() wrapper for "string" type
@@ -64,9 +60,9 @@ namespace simgear {
* @param s String to strip. * @param s String to strip.
* @return The stripped string. * @return The stripped string.
*/ */
string lstrip( const string& s ); std::string lstrip( const std::string& s );
string rstrip( const string& s ); std::string rstrip( const std::string& s );
string strip( const string& s ); std::string strip( const std::string& s );
/** /**
* Split a string into a words using 'sep' as the delimiter string. * Split a string into a words using 'sep' as the delimiter string.
@@ -79,12 +75,12 @@ namespace simgear {
* resulting in at most maxsplit+1 words. * resulting in at most maxsplit+1 words.
* @return Array of words. * @return Array of words.
*/ */
vector<string> std::vector<std::string>
split( const string& s, split( const std::string& s,
const char* sep = 0, const char* sep = 0,
int maxsplit = 0 ); int maxsplit = 0 );
} // end namespace strutils } // end namespace strutils
} // end namespace simgear } // end namespace simgear
#endif // STRUTILS_H #endif // STRUTILS_H
+1 -1
View File
@@ -21,10 +21,10 @@
// $Id$ // $Id$
#include <cstdlib> #include <cstdlib>
#include <assert.h>
#include "tabbed_values.hxx" #include "tabbed_values.hxx"
#include "assert.h"
SGTabbedValues::SGTabbedValues(const char *line) : SGTabbedValues::SGTabbedValues(const char *line) :
_line(line) _line(line)
+1
View File
@@ -149,6 +149,7 @@ enter this in the official comments in case I forget again. :-)
#include "texcoord.hxx" #include "texcoord.hxx"
#include <simgear/math/point3d.hxx>
// using std::cout; // using std::cout;
// using std::endl; // using std::endl;
+38 -2
View File
@@ -67,6 +67,15 @@ static naRef f_tell(naContext c, naRef me, int argc, naRef* args)
return naNum(g->type->tell(c, g->handle)); return naNum(g->type->tell(c, g->handle));
} }
static naRef f_flush(naContext c, naRef me, int argc, naRef* args)
{
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
if(!g)
naRuntimeError(c, "bad argument to flush()");
g->type->flush(c, g->handle);
return naNil();
}
static void ghostDestroy(void* g) static void ghostDestroy(void* g)
{ {
struct naIOGhost* io = (struct naIOGhost*)g; struct naIOGhost* io = (struct naIOGhost*)g;
@@ -111,6 +120,11 @@ static int iotell(naContext c, void* f)
return n; return n;
} }
static void ioflush(naContext c, void* f)
{
if(fflush(f)) naRuntimeError(c, strerror(errno));
}
static void iodestroy(void* f) static void iodestroy(void* f)
{ {
if(f != stdin && f != stdout && f != stderr) if(f != stdin && f != stdout && f != stderr)
@@ -118,7 +132,7 @@ static void iodestroy(void* f)
} }
struct naIOType naStdIOType = { ioclose, ioread, iowrite, ioseek, struct naIOType naStdIOType = { ioclose, ioread, iowrite, ioseek,
iotell, iodestroy }; iotell, ioflush, iodestroy };
naRef naIOGhost(naContext c, FILE* f) naRef naIOGhost(naContext c, FILE* f)
{ {
@@ -181,6 +195,26 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
return result; return result;
} }
#ifdef _MSC_VER
#define S_ISREG(m) (((m)&_S_IFMT)==_S_IFREG)
#define S_ISDIR(m) (((m)&_S_IFMT)==_S_IFDIR)
#define S_ISCHR(m) (((m)&_S_IFMT)==_S_IFCHR)
#define S_ISFIFO(m) (((m)&_S_IFMT)==_S_IFIFO)
#define S_ISBLK(m) 0
#define S_ISLNK(m) 0
#define S_ISSOCK(m) 0
typedef unsigned short mode_t;
#endif
static naRef ftype(naContext ctx, mode_t m)
{
const char* t = "unk";
if(S_ISREG(m)) t = "reg";
else if(S_ISDIR(m)) t = "dir"; else if(S_ISCHR(m)) t = "chr";
else if(S_ISBLK(m)) t = "blk"; else if(S_ISFIFO(m)) t = "fifo";
else if(S_ISLNK(m)) t = "lnk"; else if(S_ISSOCK(m)) t = "sock";
return naStr_fromdata(naNewString(ctx), t, strlen(t));
}
static naRef f_stat(naContext ctx, naRef me, int argc, naRef* args) static naRef f_stat(naContext ctx, naRef me, int argc, naRef* args)
{ {
int n=0; int n=0;
@@ -192,11 +226,12 @@ static naRef f_stat(naContext ctx, naRef me, int argc, naRef* args)
naRuntimeError(ctx, strerror(errno)); naRuntimeError(ctx, strerror(errno));
} }
result = naNewVector(ctx); result = naNewVector(ctx);
naVec_setsize(result, 11); naVec_setsize(result, 12);
#define FLD(x) naVec_set(result, n++, naNum(s.st_##x)); #define FLD(x) naVec_set(result, n++, naNum(s.st_##x));
FLD(dev); FLD(ino); FLD(mode); FLD(nlink); FLD(uid); FLD(gid); FLD(dev); FLD(ino); FLD(mode); FLD(nlink); FLD(uid); FLD(gid);
FLD(rdev); FLD(size); FLD(atime); FLD(mtime); FLD(ctime); FLD(rdev); FLD(size); FLD(atime); FLD(mtime); FLD(ctime);
#undef FLD #undef FLD
naVec_set(result, n++, ftype(ctx, s.st_mode));
return result; return result;
} }
@@ -206,6 +241,7 @@ static naCFuncItem funcs[] = {
{ "write", f_write }, { "write", f_write },
{ "seek", f_seek }, { "seek", f_seek },
{ "tell", f_tell }, { "tell", f_tell },
{ "flush", f_flush },
{ "open", f_open }, { "open", f_open },
{ "readln", f_readln }, { "readln", f_readln },
{ "stat", f_stat }, { "stat", f_stat },
+1
View File
@@ -15,6 +15,7 @@ struct naIOType {
int (*write)(naContext c, void* f, char* buf, unsigned int len); int (*write)(naContext c, void* f, char* buf, unsigned int len);
void (*seek) (naContext c, void* f, unsigned int off, int whence); void (*seek) (naContext c, void* f, unsigned int off, int whence);
int (*tell) (naContext c, void* f); int (*tell) (naContext c, void* f);
void (*flush) (naContext c, void* f);
void (*destroy)(void* f); void (*destroy)(void* f);
}; };
+2 -1
View File
@@ -11,7 +11,8 @@
* tested */ * tested */
# define NASAL_NAN64 # define NASAL_NAN64
#elif defined(_M_IX86) || defined(i386) || defined(__x86_64) || \ #elif defined(_M_IX86) || defined(i386) || defined(__x86_64) || \
defined(__ia64__) || defined(_M_IA64) || defined(__ARMEL__) defined(__ia64__) || defined(_M_IA64) || defined(__ARMEL__) || \
defined(_M_X64)
# define NASAL_LE # define NASAL_LE
#elif defined(__sparc) || defined(__ppc__) || defined(__PPC) || \ #elif defined(__sparc) || defined(__ppc__) || defined(__PPC) || \
defined(__mips) || defined(__ARMEB__) defined(__mips) || defined(__ARMEB__)
+71
View File
@@ -0,0 +1,71 @@
#include "AtomicChangeListener.hxx"
#include <algorithm>
#include <iterator>
#include <vector>
#include <boost/bind.hpp>
#include <simgear/structure/Singleton.hxx>
namespace simgear
{
using namespace std;
MultiChangeListener::MultiChangeListener()
{
}
void MultiChangeListener::valueChanged(SGPropertyNode* node)
{
valueChangedImplementation();
}
void MultiChangeListener::valueChangedImplementation()
{
}
AtomicChangeListener::AtomicChangeListener(std::vector<SGPropertyNode*>& nodes)
: _dirty(false), _valid(true)
{
listenToProperties(nodes.begin(), nodes.end());
}
void AtomicChangeListener::unregister_property(SGPropertyNode* node)
{
_valid = false;
// not necessary, but good hygine
vector<SGPropertyNode*>::iterator itr
= find(_watched.begin(), _watched.end(), node);
if (itr != _watched.end())
*itr = 0;
MultiChangeListener::unregister_property(node);
}
void AtomicChangeListener::fireChangeListeners()
{
vector<SGSharedPtr<AtomicChangeListener> >& listeners
= ListenerListSingleton::instance()->listeners;
for (vector<SGSharedPtr<AtomicChangeListener> >::iterator itr = listeners.begin(),
end = listeners.end();
itr != end;
++itr) {
(*itr)->valuesChanged();
(*itr)->_dirty = false;
}
listeners.clear();
}
void AtomicChangeListener::valueChangedImplementation()
{
if (!_dirty) {
_dirty = true;
if (_valid)
ListenerListSingleton::instance()->listeners.push_back(this);
}
}
void AtomicChangeListener::valuesChanged()
{
}
}
+104
View File
@@ -0,0 +1,104 @@
#ifndef SIMGEAR_ATOMICCHANGELISTENER_HXX
#define SIMGEAR_ATOMICCHANGELISTENER_HXX 1
#include <algorithm>
#include <iterator>
#include <vector>
#include <boost/bind.hpp>
#include <simgear/structure/Singleton.hxx>
#include "props.hxx"
#include "ExtendedPropertyAdapter.hxx"
namespace simgear
{
// Performs an action when one of several nodes changes
class MultiChangeListener : public SGPropertyChangeListener
{
public:
MultiChangeListener();
template<typename Pitr>
void listenToProperties(Pitr propsBegin, Pitr propsEnd)
{
for (Pitr itr = propsBegin, end = propsEnd; itr != end; ++itr)
(*itr)->addChangeListener(this);
}
private:
void valueChanged(SGPropertyNode* node);
virtual void valueChangedImplementation();
};
class AtomicChangeListener : public MultiChangeListener,
public virtual SGReferenced
{
public:
AtomicChangeListener(std::vector<SGPropertyNode*>& nodes);
/**
* Lookup / create child nodes from their relative names.
*/
template<typename Itr>
AtomicChangeListener(SGPropertyNode* parent, Itr childNamesBegin,
Itr childNamesEnd)
: _dirty(false), _valid(true)
{
using namespace std;
for (Itr itr = childNamesBegin, end = childNamesEnd;
itr != end;
++itr)
_watched.push_back(makeNode(parent, *itr));
listenToProperties(_watched.begin(), _watched.end());
}
bool isDirty() { return _dirty; }
bool isValid() { return _valid; }
void unregister_property(SGPropertyNode* node);
static void fireChangeListeners();
private:
virtual void valueChangedImplementation();
virtual void valuesChanged();
bool _dirty;
bool _valid;
struct ListenerListSingleton : public Singleton<ListenerListSingleton>
{
std::vector<SGSharedPtr<AtomicChangeListener> > listeners;
};
protected:
std::vector<SGPropertyNode*> _watched;
};
template<typename T, typename Func>
class ExtendedPropListener : public AtomicChangeListener
{
public:
ExtendedPropListener(std::vector<SGPropertyNode*>& nodes, const Func& func,
bool initial = false)
: AtomicChangeListener(nodes), _func(func)
{
if (initial)
valuesChanged();
}
template<typename Itr>
ExtendedPropListener(SGPropertyNode* parent, Itr childNamesBegin,
Itr childNamesEnd, const Func& func,
bool initial = false)
: AtomicChangeListener(parent, childNamesBegin, childNamesEnd),
_func(func)
{
if (initial)
valuesChanged();
}
virtual void valuesChanged()
{
ExtendedPropertyAdapter<T, std::vector<SGPropertyNode*> > adaptor(_watched);
T val = adaptor();
_func(val);
}
private:
Func _func;
};
}
#endif
+72
View File
@@ -0,0 +1,72 @@
#ifndef SIMGEAR_EXTENDEDPROPERTYADAPTER_HXX
#define SIMGEAR_EXTENDEDPROPERTYADAPTER_HXX 1
#include <algorithm>
#include <boost/bind.hpp>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/exception.hxx>
#include "props.hxx"
namespace simgear
{
namespace props
{
// This should be in simgear/math/SGVec.hxx and friends
template<typename T> struct NumComponents;
template<> struct NumComponents<SGVec3d>
{
enum { num_components = 3 };
};
template<> struct NumComponents<SGVec4d>
{
enum { num_components = 4 };
};
}
template<typename T, typename NodeContainer>
class ExtendedPropertyAdapter
{
public:
enum { num_components = props::NumComponents<T>::num_components };
ExtendedPropertyAdapter(const NodeContainer& elements)
: _elements(elements)
{
}
T operator()() const
{
T result;
if (_elements.size() < num_components)
throw sg_exception();
for (int i = 0; i < num_components; ++i)
result[i] = _elements[i]->getValue<double>();
return result;
}
void set(const T& val)
{
if (_elements.size() < num_components)
throw sg_exception();
for (int i = 0; i < num_components; ++i)
_elements[i]->setValue(val[i]);
}
private:
const NodeContainer& _elements;
};
template<typename InIterator, typename OutIterator>
inline void makeChildList(SGPropertyNode* prop, InIterator inBegin,
InIterator inEnd, OutIterator outBegin)
{
std::transform(inBegin, inEnd, outBegin,
boost::bind(static_cast<SGPropertyNode* (SGPropertyNode::*)(const char*, int, bool)>(&SGPropertyNode::getChild), prop, _1, 0, true));
}
}
#endif
+11 -2
View File
@@ -5,12 +5,15 @@ lib_LIBRARIES = libsgprops.a
include_HEADERS = \ include_HEADERS = \
condition.hxx \ condition.hxx \
props.hxx \ props.hxx \
props_io.hxx props_io.hxx \
AtomicChangeListener.hxx \
ExtendedPropertyAdapter.hxx
libsgprops_a_SOURCES = \ libsgprops_a_SOURCES = \
condition.cxx \ condition.cxx \
props.cxx \ props.cxx \
props_io.cxx props_io.cxx \
AtomicChangeListener.cxx
noinst_PROGRAMS = props_test noinst_PROGRAMS = props_test
@@ -22,4 +25,10 @@ props_test_LDADD = \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/structure/libsgstructure.a $(top_builddir)/simgear/structure/libsgstructure.a
if HAVE_FRAMEWORK_OSG
props_test_LDFLAGS = $(openthreads_FRAMEWORK)
else
props_test_LDFLAGS = -lOpenThreads
endif
INCLUDES = -I$(top_srcdir) INCLUDES = -I$(top_srcdir)
+15 -10
View File
@@ -8,7 +8,7 @@
// $Id$ // $Id$
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <simgear/compiler.h> # include <simgear_config.h>
#endif #endif
// #include <iostream> // #include <iostream>
@@ -18,6 +18,8 @@
#include "props.hxx" #include "props.hxx"
#include "condition.hxx" #include "condition.hxx"
#include <simgear/math/SGMath.hxx>
using std::istream; using std::istream;
using std::ostream; using std::ostream;
@@ -144,8 +146,9 @@ SGOrCondition::addCondition (SGCondition * condition)
static int static int
doComparison (const SGPropertyNode * left, const SGPropertyNode *right) doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
{ {
using namespace simgear;
switch (left->getType()) { switch (left->getType()) {
case SGPropertyNode::BOOL: { case props::BOOL: {
bool v1 = left->getBoolValue(); bool v1 = left->getBoolValue();
bool v2 = right->getBoolValue(); bool v2 = right->getBoolValue();
if (v1 < v2) if (v1 < v2)
@@ -156,7 +159,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
case SGPropertyNode::INT: { case props::INT: {
int v1 = left->getIntValue(); int v1 = left->getIntValue();
int v2 = right->getIntValue(); int v2 = right->getIntValue();
if (v1 < v2) if (v1 < v2)
@@ -167,7 +170,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
case SGPropertyNode::LONG: { case props::LONG: {
long v1 = left->getLongValue(); long v1 = left->getLongValue();
long v2 = right->getLongValue(); long v2 = right->getLongValue();
if (v1 < v2) if (v1 < v2)
@@ -178,7 +181,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
case SGPropertyNode::FLOAT: { case props::FLOAT: {
float v1 = left->getFloatValue(); float v1 = left->getFloatValue();
float v2 = right->getFloatValue(); float v2 = right->getFloatValue();
if (v1 < v2) if (v1 < v2)
@@ -189,7 +192,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
case SGPropertyNode::DOUBLE: { case props::DOUBLE: {
double v1 = left->getDoubleValue(); double v1 = left->getDoubleValue();
double v2 = right->getDoubleValue(); double v2 = right->getDoubleValue();
if (v1 < v2) if (v1 < v2)
@@ -200,9 +203,9 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
case SGPropertyNode::STRING: case props::STRING:
case SGPropertyNode::NONE: case props::NONE:
case SGPropertyNode::UNSPECIFIED: { case props::UNSPECIFIED: {
string v1 = left->getStringValue(); string v1 = left->getStringValue();
string v2 = right->getStringValue(); string v2 = right->getStringValue();
if (v1 < v2) if (v1 < v2)
@@ -213,8 +216,10 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
return SGComparisonCondition::EQUALS; return SGComparisonCondition::EQUALS;
break; break;
} }
default:
throw sg_exception("condition: unrecognized node type in comparison");
} }
throw sg_exception("condition: unrecognized node type in comparison");
return 0; return 0;
} }
+818 -667
View File
File diff suppressed because it is too large Load Diff
+554 -126
View File
@@ -18,6 +18,10 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <iostream>
#include <sstream>
#include <boost/utility.hpp>
#if PROPS_STANDALONE #if PROPS_STANDALONE
#else #else
@@ -26,10 +30,49 @@
#endif #endif
#include <simgear/math/SGMathFwd.hxx>
#include <simgear/structure/SGReferenced.hxx> #include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
// XXX This whole file should be in the simgear namespace, but I don't
// have the guts yet...
namespace simgear
{
template<typename T>
std::istream& readFrom(std::istream& stream, T& result)
{
stream >> result;
return stream;
}
/**
* Parse a string as an object of a given type.
* XXX no error behavior yet.
*
* @tparam T the return type
* @param str the string
* @return the object.
*/
template<typename T>
inline T parseString(const std::string& str)
{
std::istringstream stream(str);
T result;
readFrom(stream, result);
return result;
}
// Extended properties
template<>
std::istream& readFrom<SGVec3d>(std::istream& stream, SGVec3d& result);
template<>
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result);
/**
* Property value types.
*/
#ifdef NONE #ifdef NONE
#pragma warn A sloppy coder has defined NONE as a macro! #pragma warn A sloppy coder has defined NONE as a macro!
@@ -76,6 +119,68 @@
#undef STRING #undef STRING
#endif #endif
namespace props
{
/**
* The possible types of an SGPropertyNode. Types that appear after
* EXTENDED are not stored in the SGPropertyNode itself.
*/
enum Type {
NONE = 0, /**< The node hasn't been assigned a value yet. */
ALIAS, /**< The node "points" to another node. */
BOOL,
INT,
LONG,
FLOAT,
DOUBLE,
STRING,
UNSPECIFIED,
EXTENDED, /**< The node's value is not stored in the property;
* the actual value and type is retrieved from an
* SGRawValue node. This type is never returned by @see
* SGPropertyNode::getType.
*/
// Extended properties
VEC3D,
VEC4D
};
template<typename T> struct PropertyTraits;
#define DEFINTERNALPROP(TYPE, PROP) \
template<> \
struct PropertyTraits<TYPE> \
{ \
static const Type type_tag = PROP; \
enum { Internal = 1 }; \
}
DEFINTERNALPROP(bool, BOOL);
DEFINTERNALPROP(int, INT);
DEFINTERNALPROP(long, LONG);
DEFINTERNALPROP(float, FLOAT);
DEFINTERNALPROP(double, DOUBLE);
DEFINTERNALPROP(const char *, STRING);
DEFINTERNALPROP(const char[], STRING);
#undef DEFINTERNALPROP
template<>
struct PropertyTraits<SGVec3d>
{
static const Type type_tag = VEC3D;
enum { Internal = 0 };
};
template<>
struct PropertyTraits<SGVec4d>
{
static const Type type_tag = VEC4D;
enum { Internal = 0 };
};
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -90,6 +195,74 @@
// a small performance hit for that. // a small performance hit for that.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/**
* Base class for SGRawValue classes that holds no type
* information. This allows some generic manipulation of the
* SGRawValue object.
*/
class SGRaw
{
public:
/**
* Get the type enumeration for the raw value.
*
* @return the type.
*/
virtual simgear::props::Type getType() const = 0;
virtual ~SGRaw() {}
/**
* Create a new deep copy of this raw value.
*
* The copy will contain its own version of the underlying value
* as well, and will be the same type.
*
* @return A deep copy of the current object.
*/
virtual SGRaw* clone() const = 0;
};
class SGRawExtended : public SGRaw
{
public:
/**
* Make an SGRawValueContainer from the SGRawValue.
*
* This is a virtual function of SGRawExtended so that
* SGPropertyNode::untie doesn't need to know the type of an
* extended property.
*/
virtual SGRawExtended* makeContainer() const = 0;
/**
* Write value out to a stream
*/
virtual std::ostream& printOn(std::ostream& stream) const = 0;
/**
* Read value from a stream and store it.
*/
virtual std::istream& readFrom(std::istream& stream) = 0;
};
// Choose between different base classes based on whether the value is
// stored internal to the property node. This frees us from defining
// the virtual functions in the SGRawExtended interface where they
// don't make sense, e.g. readFrom for the const char* type.
template<typename T, int internal = simgear::props::PropertyTraits<T>::Internal>
class SGRawBase;
template<typename T>
class SGRawBase<T, 1> : public SGRaw
{
};
template<typename T>
class SGRawBase<T, 0> : public SGRawExtended
{
virtual SGRawExtended* makeContainer() const;
virtual std::ostream& printOn(std::ostream& stream) const;
virtual std::istream& readFrom(std::istream& stream);
};
/** /**
* Abstract base class for a raw value. * Abstract base class for a raw value.
@@ -108,10 +281,7 @@
* set, and clone the underlying value. The SGRawValue may change * set, and clone the underlying value. The SGRawValue may change
* frequently during a session as a value is retyped or bound and * frequently during a session as a value is retyped or bound and
* unbound to various data source, but the abstract SGPropertyNode * unbound to various data source, but the abstract SGPropertyNode
* layer insulates the application from those changes. The raw value * layer insulates the application from those changes.
* contains no facilities for data binding or for type conversion: it
* is simply the abstraction of a primitive data type (or a compound
* data type, in the case of a string).</p>
* *
* <p>The SGPropertyNode class always keeps a *copy* of a raw value, * <p>The SGPropertyNode class always keeps a *copy* of a raw value,
* not the original one passed to it; if you override a derived class * not the original one passed to it; if you override a derived class
@@ -127,9 +297,10 @@
* @see SGRawValueFunctionsIndexed * @see SGRawValueFunctionsIndexed
* @see SGRawValueMethods * @see SGRawValueMethods
* @see SGRawValueMethodsIndexed * @see SGRawValueMethodsIndexed
* @see SGRawValueContainer
*/ */
template <class T> template <class T>
class SGRawValue class SGRawValue : public SGRawBase<T>
{ {
public: public:
@@ -142,7 +313,10 @@ public:
* may need different kinds of default values (such as epoch for a * may need different kinds of default values (such as epoch for a
* date type). The default value is used when creating new values. * date type). The default value is used when creating new values.
*/ */
static const T DefaultValue; // Default for this kind of raw value. static T DefaultValue()
{
return T();
}
/** /**
@@ -184,17 +358,30 @@ public:
/** /**
* Create a new deep copy of this raw value. * Return the type tag for this raw value type.
*
* The copy will contain its own version of the underlying value
* as well.
*
* @return A deep copy of the current object.
*/ */
virtual SGRawValue * clone () const = 0; virtual simgear::props::Type getType() const
{
return simgear::props::PropertyTraits<T>::type_tag;
}
}; };
////////////////////////////////////////////////////////////////////////
// Default values for every type.
////////////////////////////////////////////////////////////////////////
template<> inline bool SGRawValue<bool>::DefaultValue()
{
return false;
}
template<> inline const char * SGRawValue<const char *>::DefaultValue()
{
return "";
}
/** /**
* A raw value bound to a pointer. * A raw value bound to a pointer.
* *
@@ -247,8 +434,8 @@ public:
* *
* The copy will use the same external pointer as the original. * The copy will use the same external pointer as the original.
*/ */
virtual SGRawValue<T> * clone () const { virtual SGRaw* clone () const {
return new SGRawValuePointer<T>(_ptr); return new SGRawValuePointer(_ptr);
} }
private: private:
@@ -304,7 +491,7 @@ public:
*/ */
virtual T getValue () const { virtual T getValue () const {
if (_getter) return (*_getter)(); if (_getter) return (*_getter)();
else return SGRawValue<T>::DefaultValue; else return SGRawValue<T>::DefaultValue();
} }
/** /**
@@ -322,8 +509,8 @@ public:
/** /**
* Create a copy of this raw value, bound to the same functions. * Create a copy of this raw value, bound to the same functions.
*/ */
virtual SGRawValue<T> * clone () const { virtual SGRaw* clone () const {
return new SGRawValueFunctions<T>(_getter,_setter); return new SGRawValueFunctions(_getter,_setter);
} }
private: private:
@@ -353,14 +540,14 @@ public:
virtual ~SGRawValueFunctionsIndexed () {} virtual ~SGRawValueFunctionsIndexed () {}
virtual T getValue () const { virtual T getValue () const {
if (_getter) return (*_getter)(_index); if (_getter) return (*_getter)(_index);
else return SGRawValue<T>::DefaultValue; else return SGRawValue<T>::DefaultValue();
} }
virtual bool setValue (T value) { virtual bool setValue (T value) {
if (_setter) { (*_setter)(_index, value); return true; } if (_setter) { (*_setter)(_index, value); return true; }
else return false; else return false;
} }
virtual SGRawValue<T> * clone () const { virtual SGRaw* clone () const {
return new SGRawValueFunctionsIndexed<T>(_index, _getter, _setter); return new SGRawValueFunctionsIndexed(_index, _getter, _setter);
} }
private: private:
int _index; int _index;
@@ -386,14 +573,14 @@ public:
virtual ~SGRawValueMethods () {} virtual ~SGRawValueMethods () {}
virtual T getValue () const { virtual T getValue () const {
if (_getter) { return (_obj.*_getter)(); } if (_getter) { return (_obj.*_getter)(); }
else { return SGRawValue<T>::DefaultValue; } else { return SGRawValue<T>::DefaultValue(); }
} }
virtual bool setValue (T value) { virtual bool setValue (T value) {
if (_setter) { (_obj.*_setter)(value); return true; } if (_setter) { (_obj.*_setter)(value); return true; }
else return false; else return false;
} }
virtual SGRawValue<T> * clone () const { virtual SGRaw* clone () const {
return new SGRawValueMethods<C,T>(_obj, _getter, _setter); return new SGRawValueMethods(_obj, _getter, _setter);
} }
private: private:
C &_obj; C &_obj;
@@ -420,14 +607,14 @@ public:
virtual ~SGRawValueMethodsIndexed () {} virtual ~SGRawValueMethodsIndexed () {}
virtual T getValue () const { virtual T getValue () const {
if (_getter) { return (_obj.*_getter)(_index); } if (_getter) { return (_obj.*_getter)(_index); }
else { return SGRawValue<T>::DefaultValue; } else { return SGRawValue<T>::DefaultValue(); }
} }
virtual bool setValue (T value) { virtual bool setValue (T value) {
if (_setter) { (_obj.*_setter)(_index, value); return true; } if (_setter) { (_obj.*_setter)(_index, value); return true; }
else return false; else return false;
} }
virtual SGRawValue<T> * clone () const { virtual SGRaw* clone () const {
return new SGRawValueMethodsIndexed<C,T>(_obj, _index, _getter, _setter); return new SGRawValueMethodsIndexed(_obj, _index, _getter, _setter);
} }
private: private:
C &_obj; C &_obj;
@@ -436,6 +623,77 @@ private:
setter_t _setter; setter_t _setter;
}; };
/**
* A raw value that contains its value. This provides a way for
* property nodes to contain values that shouldn't be stored in the
* property node itself.
*/
template <class T>
class SGRawValueContainer : public SGRawValue<T>
{
public:
/**
* Explicit constructor.
*/
SGRawValueContainer(const T& obj) : _obj(obj) {}
/**
* Destructor.
*/
virtual ~SGRawValueContainer() {}
/**
* Get the underlying value.
*/
virtual T getValue() const { return _obj; }
/**
* Set the underlying value.
*
* This method will dereference the pointer and change the
* variable's value.
*/
virtual bool setValue (T value) { _obj = value; return true; }
/**
* Create a copy of this raw value.
*/
virtual SGRaw* clone () const {
return new SGRawValueContainer(_obj);
}
private:
T _obj;
};
template<typename T>
SGRawExtended* SGRawBase<T, 0>::makeContainer() const
{
return new SGRawValueContainer<T>(static_cast<const SGRawValue<T>*>(this)
->getValue());
}
template<typename T>
std::ostream& SGRawBase<T, 0>::printOn(std::ostream& stream) const
{
return stream << static_cast<SGRawValue<T>*>(this)->getValue();
}
template<typename T>
std::istream& SGRawBase<T, 0>::readFrom(std::istream& stream)
{
T value;
simgear::readFrom(stream, value);
static_cast<SGRawValue<T>*>(this)->setValue(value);
return stream;
}
template<>
std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const;
template<>
std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const;
/** /**
* The smart pointer that manage reference counting * The smart pointer that manage reference counting
@@ -444,6 +702,11 @@ class SGPropertyNode;
typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr; typedef SGSharedPtr<SGPropertyNode> SGPropertyNode_ptr;
typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr; typedef SGSharedPtr<const SGPropertyNode> SGConstPropertyNode_ptr;
namespace simgear
{
typedef std::vector<SGPropertyNode_ptr> PropertyList;
}
/** /**
* The property change listener interface. * The property change listener interface.
@@ -484,22 +747,6 @@ public:
MAX_STRING_LEN = 1024 MAX_STRING_LEN = 1024
}; };
/**
* Property value types.
*/
enum Type {
NONE = 0,
ALIAS,
BOOL,
INT,
LONG,
FLOAT,
DOUBLE,
STRING,
UNSPECIFIED
};
/** /**
* Access mode attributes. * Access mode attributes.
* *
@@ -550,7 +797,7 @@ public:
/** /**
* Test whether this node contains a primitive leaf value. * Test whether this node contains a primitive leaf value.
*/ */
bool hasValue () const { return (_type != NONE); } bool hasValue () const { return (_type != simgear::props::NONE); }
/** /**
@@ -558,11 +805,15 @@ public:
*/ */
const char * getName () const { return _name.c_str(); } const char * getName () const { return _name.c_str(); }
/**
* Get the node's simple name as a string.
*/
const std::string& getNameString () const { return _name; }
/** /**
* Get the node's pretty display name, with subscript when needed. * Get the node's pretty display name, with subscript when needed.
*/ */
const char * getDisplayName (bool simplify = false) const; std::string getDisplayName (bool simplify = false) const;
/** /**
@@ -591,7 +842,7 @@ public:
/** /**
* Get the number of child nodes. * Get the number of child nodes.
*/ */
int nChildren () const { return _children.size(); } int nChildren () const { return (int)_children.size(); }
/** /**
@@ -622,21 +873,18 @@ public:
return (getChild(name, index) != 0); return (getChild(name, index) != 0);
} }
/**
* Create a child node after the last node with the same name.
*/
SGPropertyNode * addChild (const char * name);
/** /**
* Get a child node by name and index. * Get a child node by name and index.
*/ */
SGPropertyNode * getChild (const char * name, int index = 0, SGPropertyNode * getChild (const char* name, int index = 0,
bool create = false); bool create = false);
/**
* Get a child node by name and index.
*/
SGPropertyNode * getChild (const std::string& name, int index = 0, SGPropertyNode * getChild (const std::string& name, int index = 0,
bool create = false) bool create = false);
{ return getChild(name.c_str(), index, create); }
/** /**
* Get a const child node by name and index. * Get a const child node by name and index.
*/ */
@@ -652,12 +900,12 @@ public:
/** /**
* Get a vector of all children with the specified name. * Get a vector of all children with the specified name.
*/ */
std::vector<SGPropertyNode_ptr> getChildren (const char * name) const; simgear::PropertyList getChildren (const char * name) const;
/** /**
* Get a vector of all children with the specified name. * Get a vector of all children with the specified name.
*/ */
std::vector<SGPropertyNode_ptr> getChildren (const std::string& name) const simgear::PropertyList getChildren (const std::string& name) const
{ return getChildren(name.c_str()); } { return getChildren(name.c_str()); }
/** /**
@@ -682,15 +930,13 @@ public:
/** /**
* Remove all children with the specified name. * Remove all children with the specified name.
*/ */
std::vector<SGPropertyNode_ptr> removeChildren (const char * name, simgear::PropertyList removeChildren (const char * name, bool keep = true);
bool keep = true);
/** /**
* Remove all children with the specified name. * Remove all children with the specified name.
*/ */
std::vector<SGPropertyNode_ptr> removeChildren (const std::string& name, simgear::PropertyList removeChildren (const std::string& name,
bool keep = true) bool keep = true)
{ return removeChildren(name.c_str(), keep); } { return removeChildren(name.c_str(), keep); }
// //
@@ -725,7 +971,7 @@ public:
/** /**
* Test whether the node's leaf value is aliased to another's. * Test whether the node's leaf value is aliased to another's.
*/ */
bool isAlias () const { return (_type == ALIAS); } bool isAlias () const { return (_type == simgear::props::ALIAS); }
/** /**
@@ -870,7 +1116,7 @@ public:
/** /**
* Get the type of leaf value, if any, for this node. * Get the type of leaf value, if any, for this node.
*/ */
Type getType () const; simgear::props::Type getType () const;
/** /**
@@ -908,7 +1154,17 @@ public:
*/ */
const char * getStringValue () const; const char * getStringValue () const;
/**
* Get a value from a node. If the actual type of the node doesn't
* match the desired type, a conversion isn't guaranteed.
*/
template<typename T>
T getValue(typename boost::enable_if_c<simgear::props::PropertyTraits<T>::Internal>
::type* dummy = 0) const;
// Getter for extended property
template<typename T>
T getValue(typename boost::disable_if_c<simgear::props::PropertyTraits<T>::Internal>
::type* dummy = 0) const;
/** /**
* Set a bool value for this node. * Set a bool value for this node.
@@ -957,7 +1213,27 @@ public:
*/ */
bool setUnspecifiedValue (const char * value); bool setUnspecifiedValue (const char * value);
template<typename T>
bool setValue(const T& val,
typename boost::enable_if_c<simgear::props::PropertyTraits<T>::Internal>
::type* dummy = 0);
template<typename T>
bool setValue(const T& val,
typename boost::disable_if_c<simgear::props::PropertyTraits<T>::Internal>
::type* dummy = 0);
template<int N>
bool setValue(const char (&val)[N])
{
return setValue(&val[0]);
}
/**
* Print the value of the property to a stream.
*/
std::ostream& printOn(std::ostream& stream) const;
// //
// Data binding. // Data binding.
// //
@@ -968,42 +1244,11 @@ public:
*/ */
bool isTied () const { return _tied; } bool isTied () const { return _tied; }
/**
/** * Bind this node to an external source.
* Bind this node to an external bool source. */
*/ template<typename T>
bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true); bool tie(const SGRawValue<T> &rawValue, bool useDefault = true);
/**
* Bind this node to an external int source.
*/
bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
/**
* Bind this node to an external long int source.
*/
bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
/**
* Bind this node to an external float source.
*/
bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
/**
* Bind this node to an external double source.
*/
bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
/**
* Bind this node to an external string source.
*/
bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
/** /**
* Unbind this node from any external data source. * Unbind this node from any external data source.
@@ -1020,12 +1265,12 @@ public:
/** /**
* Get another node's type. * Get another node's type.
*/ */
Type getType (const char * relative_path) const; simgear::props::Type getType (const char * relative_path) const;
/** /**
* Get another node's type. * Get another node's type.
*/ */
Type getType (const std::string& relative_path) const simgear::props::Type getType (const std::string& relative_path) const
{ return getType(relative_path.c_str()); } { return getType(relative_path.c_str()); }
/** /**
@@ -1186,12 +1431,17 @@ public:
*/ */
bool setStringValue (const char * relative_path, const char * value); bool setStringValue (const char * relative_path, const char * value);
bool setStringValue(const char * relative_path, const std::string& value)
{ return setStringValue(relative_path, value.c_str()); }
/** /**
* Set another node's value as a string. * Set another node's value as a string.
*/ */
bool setStringValue (const std::string& relative_path, const char * value) bool setStringValue (const std::string& relative_path, const char * value)
{ return setStringValue(relative_path.c_str(), value); } { return setStringValue(relative_path.c_str(), value); }
bool setStringValue (const std::string& relative_path,
const std::string& value)
{ return setStringValue(relative_path.c_str(), value.c_str()); }
/** /**
* Set another node's value with no specified type. * Set another node's value with no specified type.
@@ -1323,7 +1573,7 @@ public:
/** /**
* Get the number of listeners. * Get the number of listeners.
*/ */
int nListeners () const { return _listeners ? _listeners->size() : 0; } int nListeners () const { return _listeners ? (int)_listeners->size() : 0; }
/** /**
@@ -1349,6 +1599,16 @@ public:
*/ */
void clearValue (); void clearValue ();
/**
* Compare two property trees. The property trees are equal if: 1)
* They have no children, and have the same type and the values are
* equal, or 2) have the same number of children, and the
* corresponding children in each tree are equal. "corresponding"
* means have the same name and index.
*
* Attributes, removed children, and aliases aren't considered.
*/
static bool compare (const SGPropertyNode& lhs, const SGPropertyNode& rhs);
protected: protected:
@@ -1359,12 +1619,13 @@ protected:
/** /**
* Protected constructor for making new nodes on demand. * Protected constructor for making new nodes on demand.
*/ */
SGPropertyNode (const char * name, int index, SGPropertyNode * parent); SGPropertyNode (const std::string& name, int index, SGPropertyNode * parent);
template<typename Itr>
SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent);
private: private:
// Get the raw value // Get the raw value
bool get_bool () const; bool get_bool () const;
int get_int () const; int get_int () const;
long get_long () const; long get_long () const;
@@ -1372,7 +1633,7 @@ private:
double get_double () const; double get_double () const;
const char * get_string () const; const char * get_string () const;
// Set the raw value // Set the raw value
bool set_bool (bool value); bool set_bool (bool value);
bool set_int (int value); bool set_int (int value);
bool set_long (long value); bool set_long (long value);
@@ -1386,7 +1647,6 @@ private:
*/ */
const char * make_string () const; const char * make_string () const;
/** /**
* Trace a read access. * Trace a read access.
*/ */
@@ -1409,29 +1669,23 @@ private:
int _index; int _index;
std::string _name; std::string _name;
mutable std::string _display_name;
/// To avoid cyclic reference counting loops this shall not be a reference /// To avoid cyclic reference counting loops this shall not be a reference
/// counted pointer /// counted pointer
SGPropertyNode * _parent; SGPropertyNode * _parent;
std::vector<SGPropertyNode_ptr> _children; simgear::PropertyList _children;
std::vector<SGPropertyNode_ptr> _removedChildren; simgear::PropertyList _removedChildren;
std::vector<hash_table *> _linkedNodes; std::vector<hash_table *> _linkedNodes;
mutable std::string _path; mutable std::string _path;
mutable std::string _buffer; mutable std::string _buffer;
hash_table * _path_cache; hash_table * _path_cache;
Type _type; simgear::props::Type _type;
bool _tied; bool _tied;
int _attr; int _attr;
// The right kind of pointer... // The right kind of pointer...
union { union {
SGPropertyNode * alias; SGPropertyNode * alias;
SGRawValue<bool> * bool_val; SGRaw* val;
SGRawValue<int> * int_val;
SGRawValue<long> * long_val;
SGRawValue<float> * float_val;
SGRawValue<double> * double_val;
SGRawValue<const char *> * string_val;
} _value; } _value;
union { union {
@@ -1447,8 +1701,8 @@ private:
/** /**
* Register/unregister node that links to this node in its path cache. * Register/unregister node that links to this node in its path cache.
*/ */
void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); } void add_linked_node (hash_table * node) { _linkedNodes.push_back(node); }
bool remove_linked_node (hash_table * node); bool remove_linked_node (hash_table * node);
@@ -1505,10 +1759,21 @@ private:
unsigned int _data_length; unsigned int _data_length;
bucket ** _data; bucket ** _data;
}; };
// Pass name as a pair of iterators
template<typename Itr>
SGPropertyNode * getChildImpl (Itr begin, Itr end, int index = 0, bool create = false);
// very internal method
template<typename Itr>
SGPropertyNode* getExistingChild (Itr begin, Itr end, int index, bool create);
// very internal path parsing function
template<typename SplitItr>
friend SGPropertyNode* find_node_aux(SGPropertyNode * current, SplitItr& itr,
bool create, int last_index);
// For boost
friend size_t hash_value(const SGPropertyNode& node);
}; };
// Convenice functions for use in templates // Convenience functions for use in templates
template<typename T> template<typename T>
T getValue(const SGPropertyNode*); T getValue(const SGPropertyNode*);
@@ -1574,6 +1839,169 @@ inline bool setValue (SGPropertyNode* node, const std::string& value)
return node->setStringValue(value.c_str()); return node->setStringValue(value.c_str());
} }
template<typename T>
bool SGPropertyNode::tie(const SGRawValue<T> &rawValue, bool useDefault)
{
using namespace simgear::props;
if (_type == ALIAS || _tied)
return false;
useDefault = useDefault && hasValue();
T old_val = SGRawValue<T>::DefaultValue();
if (useDefault)
old_val = getValue<T>(this);
clearValue();
if (PropertyTraits<T>::Internal)
_type = PropertyTraits<T>::type_tag;
else
_type = EXTENDED;
_tied = true;
_value.val = rawValue.clone();
if (useDefault)
setValue(old_val);
return true;
}
template<>
bool SGPropertyNode::tie (const SGRawValue<const char *> &rawValue,
bool useDefault);
template<typename T>
T SGPropertyNode::getValue(typename boost::disable_if_c<simgear::props
::PropertyTraits<T>::Internal>::type* dummy) const
{
using namespace simgear::props;
if (_attr == (READ|WRITE) && _type == EXTENDED
&& _value.val->getType() == PropertyTraits<T>::type_tag) {
return static_cast<SGRawValue<T>*>(_value.val)->getValue();
}
if (getAttribute(TRACE_READ))
trace_read();
if (!getAttribute(READ))
return SGRawValue<T>::DefaultValue();
switch (_type) {
case EXTENDED:
if (_value.val->getType() == PropertyTraits<T>::type_tag)
return static_cast<SGRawValue<T>*>(_value.val)->getValue();
break;
case STRING:
case UNSPECIFIED:
return simgear::parseString<T>(make_string());
break;
default: // avoid compiler warning
break;
}
return SGRawValue<T>::DefaultValue();
}
template<typename T>
inline T SGPropertyNode::getValue(typename boost::enable_if_c<simgear::props
::PropertyTraits<T>::Internal>::type* dummy) const
{
return ::getValue<T>(this);
}
template<typename T>
bool SGPropertyNode::setValue(const T& val,
typename boost::disable_if_c<simgear::props
::PropertyTraits<T>::Internal>::type* dummy)
{
using namespace simgear::props;
if (_attr == (READ|WRITE) && _type == EXTENDED
&& _value.val->getType() == PropertyTraits<T>::type_tag) {
static_cast<SGRawValue<T>*>(_value.val)->setValue(val);
return true;
}
if (getAttribute(WRITE)
&& ((_type == EXTENDED
&& _value.val->getType() == PropertyTraits<T>::type_tag)
|| _type == NONE || _type == UNSPECIFIED)) {
if (_type == NONE || _type == UNSPECIFIED) {
clearValue();
_type = EXTENDED;
_value.val = new SGRawValueContainer<T>(val);
} else {
static_cast<SGRawValue<T>*>(_value.val)->setValue(val);
}
if (getAttribute(TRACE_WRITE))
trace_write();
return true;
}
return false;
}
template<typename T>
inline bool SGPropertyNode::setValue(const T& val,
typename boost::enable_if_c<simgear::props
::PropertyTraits<T>::Internal>::type* dummy)
{
return ::setValue(this, val);
}
/**
* Utility function for creation of a child property node.
*/
inline SGPropertyNode* makeChild(SGPropertyNode* parent, const char* name,
int index = 0)
{
return parent->getChild(name, index, true);
}
/**
* Utility function for creation of a child property node using a
* relative path.
*/
namespace simgear
{
template<typename StringType>
inline SGPropertyNode* makeNode(SGPropertyNode* parent, const StringType& name)
{
return parent->getNode(name, true);
}
}
// For boost::hash
size_t hash_value(const SGPropertyNode& node);
// Helper comparison and hash functions for common cases
namespace simgear
{
namespace props
{
struct Compare
{
bool operator()(const SGPropertyNode* lhs, const SGPropertyNode* rhs) const
{
return SGPropertyNode::compare(*lhs, *rhs);
}
bool operator()(SGPropertyNode_ptr lhs, const SGPropertyNode* rhs) const
{
return SGPropertyNode::compare(*lhs, *rhs);
}
bool operator()(const SGPropertyNode* lhs, SGPropertyNode_ptr rhs) const
{
return SGPropertyNode::compare(*lhs, *rhs);
}
bool operator()(SGPropertyNode_ptr lhs, SGPropertyNode_ptr rhs) const
{
return SGPropertyNode::compare(*lhs, *rhs);
}
};
struct Hash
{
size_t operator()(const SGPropertyNode* node) const
{
return hash_value(*node);
}
size_t operator()(SGPropertyNode_ptr node) const
{
return hash_value(*node);
}
};
}
}
#endif // __PROPS_HXX #endif // __PROPS_HXX
// end of props.hxx // end of props.hxx
+70 -33
View File
@@ -18,6 +18,7 @@
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/xml/easyxml.hxx> #include <simgear/xml/easyxml.hxx>
@@ -27,6 +28,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <cstring> // strcmp()
#include <vector> #include <vector>
#include <map> #include <map>
@@ -52,8 +54,11 @@ class PropsVisitor : public XMLVisitor
{ {
public: public:
PropsVisitor (SGPropertyNode * root, const string &base, int default_mode = 0) PropsVisitor (SGPropertyNode * root, const string &base, int default_mode = 0,
: _default_mode(default_mode), _root(root), _level(0), _base(base), _hasException(false) {} bool extended = false)
: _default_mode(default_mode), _root(root), _level(0), _base(base),
_hasException(false), _extended(extended)
{}
virtual ~PropsVisitor () {} virtual ~PropsVisitor () {}
@@ -110,6 +115,7 @@ private:
string _base; string _base;
sg_io_exception _exception; sg_io_exception _exception;
bool _hasException; bool _hasException;
bool _extended;
}; };
void void
@@ -167,7 +173,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
SGPath path(SGPath(_base).dir()); SGPath path(SGPath(_base).dir());
path.append(attval); path.append(attval);
try { try {
readProperties(path.str(), _root); readProperties(path.str(), _root, 0, _extended);
} catch (sg_io_exception &e) { } catch (sg_io_exception &e) {
setException(e); setException(e);
} }
@@ -181,16 +187,17 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
// Get the index. // Get the index.
attval = atts.getValue("n"); attval = atts.getValue("n");
int index = 0; int index = 0;
string strName(name);
if (attval != 0) { if (attval != 0) {
index = atoi(attval); index = atoi(attval);
st.counters[name] = SG_MAX2(st.counters[name], index+1); st.counters[strName] = SG_MAX2(st.counters[strName], index+1);
} else { } else {
index = st.counters[name]; index = st.counters[strName];
st.counters[name]++; st.counters[strName]++;
} }
// Got the index, so grab the node. // Got the index, so grab the node.
SGPropertyNode * node = st.node->getChild(name, index, true); SGPropertyNode * node = st.node->getChild(strName, index, true);
if (!node->getAttribute(SGPropertyNode::WRITE)) { if (!node->getAttribute(SGPropertyNode::WRITE)) {
SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property " SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property "
<< node->getPath(true)); << node->getPath(true));
@@ -235,7 +242,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
SGPath path(SGPath(_base).dir()); SGPath path(SGPath(_base).dir());
path.append(attval); path.append(attval);
try { try {
readProperties(path.str(), node); readProperties(path.str(), node, 0, _extended);
} catch (sg_io_exception &e) { } catch (sg_io_exception &e) {
setException(e); setException(e);
} }
@@ -275,6 +282,12 @@ PropsVisitor::endElement (const char * name)
ret = st.node->setDoubleValue(strtod(_data.c_str(), 0)); ret = st.node->setDoubleValue(strtod(_data.c_str(), 0));
} else if (st.type == "string") { } else if (st.type == "string") {
ret = st.node->setStringValue(_data.c_str()); ret = st.node->setStringValue(_data.c_str());
} else if (st.type == "vec3d" && _extended) {
ret = st.node
->setValue(simgear::parseString<SGVec3d>(_data));
} else if (st.type == "vec4d" && _extended) {
ret = st.node
->setValue(simgear::parseString<SGVec4d>(_data));
} else if (st.type == "unspecified") { } else if (st.type == "unspecified") {
ret = st.node->setUnspecifiedValue(_data.c_str()); ret = st.node->setUnspecifiedValue(_data.c_str());
} else if (_level == 1) { } else if (_level == 1) {
@@ -344,9 +357,9 @@ PropsVisitor::warning (const char * message, int line, int column)
*/ */
void void
readProperties (istream &input, SGPropertyNode * start_node, readProperties (istream &input, SGPropertyNode * start_node,
const string &base, int default_mode) const string &base, int default_mode, bool extended)
{ {
PropsVisitor visitor(start_node, base, default_mode); PropsVisitor visitor(start_node, base, default_mode, extended);
readXML(input, visitor, base); readXML(input, visitor, base);
if (visitor.hasException()) if (visitor.hasException())
throw visitor.getException(); throw visitor.getException();
@@ -362,9 +375,9 @@ readProperties (istream &input, SGPropertyNode * start_node,
*/ */
void void
readProperties (const string &file, SGPropertyNode * start_node, readProperties (const string &file, SGPropertyNode * start_node,
int default_mode) int default_mode, bool extended)
{ {
PropsVisitor visitor(start_node, file, default_mode); PropsVisitor visitor(start_node, file, default_mode, extended);
readXML(file, visitor); readXML(file, visitor);
if (visitor.hasException()) if (visitor.hasException())
throw visitor.getException(); throw visitor.getException();
@@ -380,9 +393,10 @@ readProperties (const string &file, SGPropertyNode * start_node,
* @return true if the read succeeded, false otherwise. * @return true if the read succeeded, false otherwise.
*/ */
void readProperties (const char *buf, const int size, void readProperties (const char *buf, const int size,
SGPropertyNode * start_node, int default_mode) SGPropertyNode * start_node, int default_mode,
bool extended)
{ {
PropsVisitor visitor(start_node, "", default_mode); PropsVisitor visitor(start_node, "", default_mode, extended);
readXML(buf, size, visitor); readXML(buf, size, visitor);
if (visitor.hasException()) if (visitor.hasException())
throw visitor.getException(); throw visitor.getException();
@@ -399,26 +413,33 @@ void readProperties (const char *buf, const int size,
* Return the type name. * Return the type name.
*/ */
static const char * static const char *
getTypeName (SGPropertyNode::Type type) getTypeName (simgear::props::Type type)
{ {
using namespace simgear;
switch (type) { switch (type) {
case SGPropertyNode::UNSPECIFIED: case props::UNSPECIFIED:
return "unspecified"; return "unspecified";
case SGPropertyNode::BOOL: case props::BOOL:
return "bool"; return "bool";
case SGPropertyNode::INT: case props::INT:
return "int"; return "int";
case SGPropertyNode::LONG: case props::LONG:
return "long"; return "long";
case SGPropertyNode::FLOAT: case props::FLOAT:
return "float"; return "float";
case SGPropertyNode::DOUBLE: case props::DOUBLE:
return "double"; return "double";
case SGPropertyNode::STRING: case props::STRING:
return "string"; return "string";
case SGPropertyNode::ALIAS: case props::VEC3D:
case SGPropertyNode::NONE: return "vec3d";
case props::VEC4D:
return "vec4d";
case props::ALIAS:
case props::NONE:
return "unspecified"; return "unspecified";
default: // avoid compiler warning
break;
} }
// keep the compiler from squawking // keep the compiler from squawking
@@ -524,7 +545,7 @@ writeNode (ostream &output, const SGPropertyNode * node,
output << " alias=\"" << node->getAliasTarget()->getPath() output << " alias=\"" << node->getAliasTarget()->getPath()
<< "\"/>" << endl; << "\"/>" << endl;
} else { } else {
if (node->getType() != SGPropertyNode::UNSPECIFIED) if (node->getType() != simgear::props::UNSPECIFIED)
output << " type=\"" << getTypeName(node->getType()) << '"'; output << " type=\"" << getTypeName(node->getType()) << '"';
output << '>'; output << '>';
writeData(output, node->getStringValue()); writeData(output, node->getStringValue());
@@ -581,6 +602,13 @@ writeProperties (const string &file, const SGPropertyNode * start_node,
} }
} }
// Another variation, useful when called from gdb
void
writeProperties (const char* file, const SGPropertyNode * start_node)
{
writeProperties(string(file), start_node, true);
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -599,40 +627,49 @@ writeProperties (const string &file, const SGPropertyNode * start_node,
bool bool
copyProperties (const SGPropertyNode *in, SGPropertyNode *out) copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
{ {
using namespace simgear;
bool retval = true; bool retval = true;
// First, copy the actual value, // First, copy the actual value,
// if any. // if any.
if (in->hasValue()) { if (in->hasValue()) {
switch (in->getType()) { switch (in->getType()) {
case SGPropertyNode::BOOL: case props::BOOL:
if (!out->setBoolValue(in->getBoolValue())) if (!out->setBoolValue(in->getBoolValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::INT: case props::INT:
if (!out->setIntValue(in->getIntValue())) if (!out->setIntValue(in->getIntValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::LONG: case props::LONG:
if (!out->setLongValue(in->getLongValue())) if (!out->setLongValue(in->getLongValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::FLOAT: case props::FLOAT:
if (!out->setFloatValue(in->getFloatValue())) if (!out->setFloatValue(in->getFloatValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::DOUBLE: case props::DOUBLE:
if (!out->setDoubleValue(in->getDoubleValue())) if (!out->setDoubleValue(in->getDoubleValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::STRING: case props::STRING:
if (!out->setStringValue(in->getStringValue())) if (!out->setStringValue(in->getStringValue()))
retval = false; retval = false;
break; break;
case SGPropertyNode::UNSPECIFIED: case props::UNSPECIFIED:
if (!out->setUnspecifiedValue(in->getStringValue())) if (!out->setUnspecifiedValue(in->getStringValue()))
retval = false; retval = false;
break; break;
case props::VEC3D:
if (!out->setValue(in->getValue<SGVec3d>()))
retval = false;
break;
case props::VEC4D:
if (!out->setValue(in->getValue<SGVec4d>()))
retval = false;
break;
default: default:
if (in->isAlias()) if (in->isAlias())
break; break;
@@ -649,7 +686,7 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
int nChildren = in->nChildren(); int nChildren = in->nChildren();
for (int i = 0; i < nChildren; i++) { for (int i = 0; i < nChildren; i++) {
const SGPropertyNode * in_child = in->getChild(i); const SGPropertyNode * in_child = in->getChild(i);
SGPropertyNode * out_child = out->getChild(in_child->getName(), SGPropertyNode * out_child = out->getChild(in_child->getNameString(),
in_child->getIndex(), in_child->getIndex(),
true); true);
if (!copyProperties(in_child, out_child)) if (!copyProperties(in_child, out_child))
+5 -3
View File
@@ -26,21 +26,23 @@
* Read properties from an XML input stream. * Read properties from an XML input stream.
*/ */
void readProperties (std::istream &input, SGPropertyNode * start_node, void readProperties (std::istream &input, SGPropertyNode * start_node,
const std::string &base = "", int default_mode = 0); const std::string &base = "", int default_mode = 0,
bool extended = false);
/** /**
* Read properties from an XML file. * Read properties from an XML file.
*/ */
void readProperties (const std::string &file, SGPropertyNode * start_node, void readProperties (const std::string &file, SGPropertyNode * start_node,
int default_mode = 0); int default_mode = 0, bool extended = false);
/** /**
* Read properties from an in-memory buffer. * Read properties from an in-memory buffer.
*/ */
void readProperties (const char *buf, const int size, void readProperties (const char *buf, const int size,
SGPropertyNode * start_node, int default_mode = 0); SGPropertyNode * start_node, int default_mode = 0,
bool extended = false);
/** /**
+22
View File
@@ -324,6 +324,26 @@ test_property_nodes ()
cout << endl; cout << endl;
} }
void test_addChild()
{
SGPropertyNode root;
cout << "Testing the addChild function " << endl;
cout << "Created root node " << root.getPath() << endl;
SGPropertyNode *test = root.getChild("test", 0, true);
SGPropertyNode *n = test->getNode("foo", true);
n->getChild("child", 1, true)->setIntValue(1);
n->getChild("child", 2, true)->setIntValue(2);
n->getChild("child", 4, true)->setIntValue(2);
dump_node(&root);
SGPropertyNode *ch = n->addChild("child");
ch->setIntValue(3);
cerr << endl << "ADDED: " << ch->getPath() << endl << endl;
dump_node(&root);
}
int main (int ac, char ** av) int main (int ac, char ** av)
{ {
@@ -342,5 +362,7 @@ int main (int ac, char ** av)
} }
} }
test_addChild();
return 0; return 0;
} }
+1
View File
@@ -31,4 +31,5 @@ routetest_LDADD = \
libsgroute.a \ libsgroute.a \
$(top_builddir)/simgear/math/libsgmath.a \ $(top_builddir)/simgear/math/libsgmath.a \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/structure/libsgstructure.a \
$(base_LIBS) $(base_LIBS)
+26 -44
View File
@@ -20,6 +20,9 @@
// //
// $Id$ // $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <plib/sg.h> #include <plib/sg.h>
@@ -38,51 +41,22 @@ SGRoute::SGRoute() {
SGRoute::~SGRoute() { SGRoute::~SGRoute() {
} }
// Calculate perpendicular distance from the current route segment
// This routine assumes all points are laying on a flat plane and
// ignores the altitude (or Z) dimension. For best results, use with
// CARTESIAN way points.
double SGRoute::distance_off_route( double x, double y ) const {
if ( current_wp > 0 ) {
int n0 = current_wp - 1;
int n1 = current_wp;
sgdVec3 p, p0, p1, d;
sgdSetVec3( p, x, y, 0.0 );
sgdSetVec3( p0,
route[n0].get_target_lon(), route[n0].get_target_lat(),
0.0 );
sgdSetVec3( p1,
route[n1].get_target_lon(), route[n1].get_target_lat(),
0.0 );
sgdSubVec3( d, p0, p1 );
return sqrt( sgdClosestPointToLineDistSquared( p, p0, d ) );
} else {
// We are tracking the first waypoint so there is no route
// segment. If you add the current location as the first
// waypoint and the actual waypoint as the second, then we
// will have a route segment and calculate distance from it.
return 0;
}
}
/** Update the length of the leg ending at waypoint index */ /** Update the length of the leg ending at waypoint index */
void SGRoute::update_distance(int index) void SGRoute::update_distance_and_track(int index)
{ {
SGWayPoint& curr = route[ index ]; SGWayPoint& curr = route[ index ];
double course, dist; double course, dist;
if ( index == 0 ) { if ( index == 0 ) {
dist = 0; dist = 0;
} else { course = 0.0;
const SGWayPoint& prev = route[ index - 1 ]; } else {
curr.CourseAndDistance( prev, &course, &dist ); const SGWayPoint& prev = route[index - 1];
} curr.CourseAndDistance( prev, &course, &dist );
}
curr.set_distance( dist ); curr.set_distance(dist);
curr.set_track(course);
} }
/** /**
@@ -97,9 +71,9 @@ void SGRoute::add_waypoint( const SGWayPoint &wp, int n ) {
} else { } else {
route.insert( route.begin() + n, 1, wp ); route.insert( route.begin() + n, 1, wp );
// update distance of next leg if not at end of route // update distance of next leg if not at end of route
update_distance( n + 1 ); update_distance_and_track( n + 1 );
} }
update_distance( n ); update_distance_and_track( n );
} }
/** Delete waypoint with index n (last one if n < 0) */ /** Delete waypoint with index n (last one if n < 0) */
@@ -113,5 +87,13 @@ void SGRoute::delete_waypoint( int n ) {
route.erase( route.begin() + n ); route.erase( route.begin() + n );
// update distance of next leg if not at end of route // update distance of next leg if not at end of route
if ( n < size - 1 ) if ( n < size - 1 )
update_distance( n ); update_distance_and_track( n );
}
double SGRoute::total_distance() const {
double total = 0.0;
for (unsigned int i=0; i<route.size(); ++i) {
total += route[i].get_distance();
}
return total;
} }
+20 -7
View File
@@ -52,7 +52,7 @@ private:
route_list route; route_list route;
int current_wp; int current_wp;
void update_distance(int index); void update_distance_and_track(int index);
public: public:
@@ -102,6 +102,22 @@ public:
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" ); return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
} }
} }
inline SGWayPoint get_previous() const {
if ( (current_wp > 0) && (current_wp < (int)route.size()) ) {
return route[current_wp - 1];
} else {
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
}
}
inline SGWayPoint get_next() const {
if ( (current_wp + 1) < (int)route.size() ) {
return route[current_wp+1];
} else {
return SGWayPoint( 0.0, 0.0, 0.0, SGWayPoint::WGS84, "invalid" );
}
}
/** /**
* Set the current waypoint * Set the current waypoint
@@ -142,14 +158,11 @@ public:
/** Delete waypoint waypoint with index n (last one if n < 0) */ /** Delete waypoint waypoint with index n (last one if n < 0) */
void delete_waypoint( int n = 0 ); void delete_waypoint( int n = 0 );
/** /**
* Calculate perpendicular distance from the current route segment * Helper, sum the distance members of each waypoint
* This routine assumes all points are laying on a flat plane and
* ignores the altitude (or Z) dimension. For most accurate
* results, use with CARTESIAN way points.
*/ */
double distance_off_route( double x, double y ) const; double total_distance() const;
}; };
+2 -2
View File
@@ -23,7 +23,7 @@ void dump_route(const SGRoute& route, const char* message)
int main() int main()
{ {
SGRoute route; SGRoute route;
/*
route.add_waypoint( SGWayPoint(0, 0, 0, SGWayPoint::CARTESIAN, "Start") ); route.add_waypoint( SGWayPoint(0, 0, 0, SGWayPoint::CARTESIAN, "Start") );
route.add_waypoint( SGWayPoint(1, 0, 0, SGWayPoint::CARTESIAN, "1") ); route.add_waypoint( SGWayPoint(1, 0, 0, SGWayPoint::CARTESIAN, "1") );
route.add_waypoint( SGWayPoint(2, 0, 0, SGWayPoint::CARTESIAN, "2") ); route.add_waypoint( SGWayPoint(2, 0, 0, SGWayPoint::CARTESIAN, "2") );
@@ -48,6 +48,6 @@ int main()
route.add_waypoint(wp2, 3); route.add_waypoint(wp2, 3);
dump_route(route, "added back WP2 after WP3"); dump_route(route, "added back WP2 after WP3");
*/
return 0; return 0;
} }
+24 -32
View File
@@ -29,23 +29,38 @@
#include "waypoint.hxx" #include "waypoint.hxx"
using std::string;
// Constructor // Constructor
SGWayPoint::SGWayPoint( const double lon, const double lat, const double alt, SGWayPoint::SGWayPoint( const double lon, const double lat, const double alt,
const modetype m, const string& s, const string& n ) { const modetype, const string& s, const string& n ) :
target_lon = lon; pos(SGGeod::fromDegM(lon, lat, alt)),
target_lat = lat; id(s),
target_alt = alt; name(n),
mode = m; _distance(0.0),
id = s; _track(0.0),
name = n; _speed(0.0)
{
} }
SGWayPoint::SGWayPoint(const SGGeod& geod, const string& s, const string& n ) :
pos(geod),
id(s),
name(n),
_distance(0.0),
_track(0.0),
_speed(0.0)
{
}
// Destructor // Destructor
SGWayPoint::~SGWayPoint() { SGWayPoint::~SGWayPoint() {
} }
void SGWayPoint::CourseAndDistance(const SGGeod& cur, double& course, double& dist ) const {
double reverse;
SGGeodesy::inverse(cur, pos, course, reverse, dist);
}
// Calculate course and distances. For WGS84 and SPHERICAL // Calculate course and distances. For WGS84 and SPHERICAL
// coordinates lat, lon, and course are in degrees, alt and distance // coordinates lat, lon, and course are in degrees, alt and distance
@@ -55,34 +70,11 @@ void SGWayPoint::CourseAndDistance( const double cur_lon,
const double cur_lat, const double cur_lat,
const double cur_alt, const double cur_alt,
double *course, double *dist ) const { double *course, double *dist ) const {
if ( mode == WGS84 ) { CourseAndDistance(SGGeod::fromDegM(cur_lon, cur_lat, cur_alt), *course, *dist);
double reverse;
geo_inverse_wgs_84( cur_alt, cur_lat, cur_lon, target_lat, target_lon,
course, &reverse, dist );
} else if ( mode == SPHERICAL ) {
Point3D current( cur_lon * SGD_DEGREES_TO_RADIANS, cur_lat * SGD_DEGREES_TO_RADIANS, 0.0 );
Point3D target( target_lon * SGD_DEGREES_TO_RADIANS, target_lat * SGD_DEGREES_TO_RADIANS, 0.0 );
calc_gc_course_dist( current, target, course, dist );
*course = 360.0 - *course * SGD_RADIANS_TO_DEGREES;
} else if ( mode == CARTESIAN ) {
double dx = target_lon - cur_lon;
double dy = target_lat - cur_lat;
*course = -atan2( dy, dx ) * SGD_RADIANS_TO_DEGREES - 90;
while ( *course < 0 ) {
*course += 360.0;
}
while ( *course > 360.0 ) {
*course -= 360.0;
}
*dist = sqrt( dx * dx + dy * dy );
}
} }
// Calculate course and distances between two waypoints // Calculate course and distances between two waypoints
void SGWayPoint::CourseAndDistance( const SGWayPoint &wp, void SGWayPoint::CourseAndDistance( const SGWayPoint &wp,
double *course, double *dist ) const { double *course, double *dist ) const {
CourseAndDistance( wp.get_target_lon(), CourseAndDistance( wp.get_target(), *course, *dist );
wp.get_target_lat(),
wp.get_target_alt(),
course, dist );
} }
+36 -34
View File
@@ -27,17 +27,12 @@
#ifndef _WAYPOINT_HXX #ifndef _WAYPOINT_HXX
#define _WAYPOINT_HXX #define _WAYPOINT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <string> #include <simgear/math/SGMath.hxx>
#include <simgear/math/SGGeod.hxx>
using std::string; #include <string>
/** /**
@@ -57,27 +52,21 @@ public:
* the world is a perfect sphere. This is less compuntationally * the world is a perfect sphere. This is less compuntationally
* expensive than using wgs84 math and still a fairly good * expensive than using wgs84 math and still a fairly good
* approximation of the real world, especially over shorter distances. * approximation of the real world, especially over shorter distances.
* <li> CARTESIAN requests all math be done assuming the coordinates specify
* position in a Z = up world.
*/ */
enum modetype { enum modetype {
WGS84 = 0, WGS84 = 0,
SPHERICAL = 1,
CARTESIAN = 2
}; };
private: private:
SGGeod pos;
modetype mode; std::string id;
std::string name;
double target_lon;
double target_lat; // route data associated with the waypoint
double target_alt; double _distance;
double distance; double _track;
double _speed;
string id;
string name;
public: public:
/** /**
@@ -91,7 +80,12 @@ public:
*/ */
SGWayPoint( const double lon = 0.0, const double lat = 0.0, SGWayPoint( const double lon = 0.0, const double lat = 0.0,
const double alt = 0.0, const modetype m = WGS84, const double alt = 0.0, const modetype m = WGS84,
const string& s = "", const string& n = "" ); const std::string& s = "", const std::string& n = "" );
/**
* Construct from a geodetic position, in WGS84 coordinates
*/
SGWayPoint(const SGGeod& pos, const std::string& s, const std::string& n);
/** Destructor */ /** Destructor */
~SGWayPoint(); ~SGWayPoint();
@@ -112,6 +106,9 @@ public:
const double cur_alt, const double cur_alt,
double *course, double *dist ) const; double *course, double *dist ) const;
void CourseAndDistance(const SGGeod& current,
double& course, double& dist ) const;
/** /**
* Calculate course and distances between a specified starting waypoint * Calculate course and distances between a specified starting waypoint
* and this waypoint. * and this waypoint.
@@ -122,17 +119,16 @@ public:
void CourseAndDistance( const SGWayPoint &wp, void CourseAndDistance( const SGWayPoint &wp,
double *course, double *dist ) const; double *course, double *dist ) const;
/** @return waypoint mode */
inline modetype get_mode() const { return mode; }
/** @return waypoint longitude */ /** @return waypoint longitude */
inline double get_target_lon() const { return target_lon; } inline double get_target_lon() const { return pos.getLongitudeDeg(); }
/** @return waypoint latitude */ /** @return waypoint latitude */
inline double get_target_lat() const { return target_lat; } inline double get_target_lat() const { return pos.getLatitudeDeg(); }
/** @return waypoint altitude */ /** @return waypoint altitude */
inline double get_target_alt() const { return target_alt; } inline double get_target_alt() const { return pos.getElevationM(); }
inline const SGGeod& get_target() const { return pos; }
/** /**
* This value is not calculated by this class. It is simply a * This value is not calculated by this class. It is simply a
@@ -144,19 +140,25 @@ public:
* is for your convenience only. * is for your convenience only.
* @return waypoint distance holder (what ever the user has stashed here) * @return waypoint distance holder (what ever the user has stashed here)
*/ */
inline double get_distance() const { return distance; } inline double get_distance() const { return _distance; }
/** /**
* Set the waypoint distance value to a value of our choice. * Set the waypoint distance value to a value of our choice.
* @param d distance * @param d distance
*/ */
inline void set_distance( double d ) { distance = d; } inline void set_distance( double d ) { _distance = d; }
inline double get_track() const { return _track; }
inline void set_track(double t) { _track = t; }
inline double get_speed() const { return _speed; }
inline void set_speed(double v) { _speed = v; }
/** @return waypoint id */ /** @return waypoint id */
inline const string& get_id() const { return id; } inline const std::string& get_id() const { return id; }
/** @return waypoint name */ /** @return waypoint name */
inline const string& get_name() const { return name; } inline const std::string& get_name() const { return name; }
}; };
+2 -30
View File
@@ -10,7 +10,7 @@ using std::endl;
int main() { int main() {
SGWayPoint a1(-93.216923, 44.880547, 0.0, SGWayPoint::WGS84, "KMSP"); SGWayPoint a1(-93.216923, 44.880547, 0.0, SGWayPoint::WGS84, "KMSP");
SGWayPoint a2(-93.216923, 44.880547, 0.0, SGWayPoint::SPHERICAL, "KMSP");
// KMSN (Madison) // KMSN (Madison)
double cur_lon = -89.336939; double cur_lon = -89.336939;
@@ -24,43 +24,15 @@ int main() {
cout << "Distance to " << a1.get_id() << " is " << distance * SG_METER_TO_NM cout << "Distance to " << a1.get_id() << " is " << distance * SG_METER_TO_NM
<< endl; << endl;
a2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << a2.get_id() << " is " << course << endl;
cout << "Distance to " << a2.get_id() << " is " << distance * SG_METER_TO_NM
<< endl;
cout << endl;
SGWayPoint b1(-88.237037, 43.041038, 0.0, SGWayPoint::WGS84, "KUES"); SGWayPoint b1(-88.237037, 43.041038, 0.0, SGWayPoint::WGS84, "KUES");
SGWayPoint b2(-88.237037, 43.041038, 0.0, SGWayPoint::SPHERICAL, "KUES");
b1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance ); b1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << b1.get_id() << " is " << course << endl; cout << "Course to " << b1.get_id() << " is " << course << endl;
cout << "Distance to " << b1.get_id() << " is " << distance * SG_METER_TO_NM cout << "Distance to " << b1.get_id() << " is " << distance * SG_METER_TO_NM
<< endl; << endl;
b2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << b2.get_id() << " is " << course << endl;
cout << "Distance to " << b2.get_id() << " is " << distance * SG_METER_TO_NM
<< endl;
cout << endl; cout << endl;
cur_lon = 10;
cur_lat = 10;
SGWayPoint c1(-20, 10, 0, SGWayPoint::CARTESIAN, "Due East");
c1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << c1.get_id() << " is " << course << endl;
cout << "Distance to " << c1.get_id() << " is " << distance << endl;
SGWayPoint c2(20, 20, 0, SGWayPoint::CARTESIAN, "Due SW");
c2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << c2.get_id() << " is " << course << endl;
cout << "Distance to " << c2.get_id() << " is " << distance << endl;
SGWayPoint c3(20, 0, 0, SGWayPoint::CARTESIAN, "Due NW");
c3.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
cout << "Course to " << c3.get_id() << " is " << course << endl;
cout << "Distance to " << c3.get_id() << " is " << distance << endl;
return 0; return 0;
} }
+1 -1
View File
@@ -1,6 +1,6 @@
includedir = @includedir@/scene includedir = @includedir@/scene
SUBDIRS = material model sky tgdb util SUBDIRS = bvh material model sky tgdb util
# lib_LIBRARIES = libsgscene.a # lib_LIBRARIES = libsgscene.a
+3
View File
@@ -0,0 +1,3 @@
.deps
Makefile
Makefile.in
@@ -0,0 +1,80 @@
// Copyright (C) 2008 - 2009 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 BVHBoundingBoxVisitor_hxx
#define BVHBoundingBoxVisitor_hxx
#include <simgear/math/SGGeometry.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
#include "BVHMotionTransform.hxx"
#include "BVHLineGeometry.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
#include "BVHStaticGeometry.hxx"
namespace simgear {
class BVHBoundingBoxVisitor : public BVHVisitor {
public:
virtual ~BVHBoundingBoxVisitor() {}
void clear()
{ _box.clear(); }
virtual void apply(BVHGroup& node)
{ expandBy(node.getBoundingSphere()); }
virtual void apply(BVHTransform& node)
{ expandBy(node.getBoundingSphere()); }
virtual void apply(BVHMotionTransform& node)
{ expandBy(node.getBoundingSphere()); }
virtual void apply(BVHLineGeometry& node)
{ expandBy(node.getBoundingSphere()); }
virtual void apply(BVHStaticGeometry& node)
{ expandBy(node.getBoundingSphere()); }
virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
{ expandBy(node.getBoundingBox()); }
virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
{ expandBy(node.computeBoundingBox(data)); }
const SGBoxf& getBox() const
{ return _box; }
private:
void expandBy(const SGSphered& sphere)
{
SGVec3f v0(sphere.getCenter() - sphere.getRadius()*SGVec3d(1, 1, 1));
SGVec3f v1(sphere.getCenter() + sphere.getRadius()*SGVec3d(1, 1, 1));
_box.expandBy(SGBoxf(v0, v1));
}
void expandBy(const SGBoxf& box)
{ _box.expandBy(box); }
SGBoxf _box;
};
}
#endif
@@ -0,0 +1,210 @@
// Copyright (C) 2008 - 2009 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 BVHDebugCollectVisitor_hxx
#define BVHDebugCollectVisitor_hxx
#include <osg/ref_ptr>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/PolygonOffset>
#include <osg/PrimitiveSet>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osg/Shape>
#include <osg/Depth>
#include <osg/BlendFunc>
#include <osg/StateSet>
#include <simgear/math/SGGeometry.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
#include "BVHMotionTransform.hxx"
#include "BVHStaticGeometry.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
#include "BVHBoundingBoxVisitor.hxx"
namespace simgear {
class BVHNode;
class BVHStaticNode;
class BVHDebugCollectVisitor : public BVHVisitor {
public:
BVHDebugCollectVisitor(const double& time, unsigned level = ~0u) :
_group(new osg::Group),
_time(time),
_level(level),
_currentLevel(0)
{
osg::StateSet* stateSet = _group->getOrCreateStateSet();
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false));
osg::BlendFunc *blendFunc;
blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::DST_ALPHA);
stateSet->setAttributeAndModes(blendFunc);
osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1);
stateSet->setAttributeAndModes(polygonOffset);
}
virtual ~BVHDebugCollectVisitor()
{ }
virtual void apply(BVHGroup& node)
{
addNodeSphere(node);
++_currentLevel;
node.traverse(*this);
--_currentLevel;
}
virtual void apply(BVHTransform& node)
{
addNodeSphere(node);
osg::ref_ptr<osg::Group> oldGroup = _group;
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
transform->setMatrix(osg::Matrix(node.getToWorldTransform().data()));
_group = transform;
++_currentLevel;
node.traverse(*this);
--_currentLevel;
_group = oldGroup;
if (transform->getNumChildren())
_group->addChild(transform.get());
}
virtual void apply(BVHMotionTransform& node)
{
addNodeSphere(node);
osg::ref_ptr<osg::Group> oldGroup = _group;
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
transform->setMatrix(osg::Matrix(node.getToWorldTransform(_time).data()));
_group = transform;
++_currentLevel;
node.traverse(*this);
--_currentLevel;
_group = oldGroup;
if (transform->getNumChildren())
_group->addChild(transform.get());
}
virtual void apply(BVHLineGeometry&)
{
}
virtual void apply(BVHStaticGeometry& node)
{
addNodeSphere(node);
++_currentLevel;
node.traverse(*this);
--_currentLevel;
}
virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
{
addNodeBox(node, data);
++_currentLevel;
node.traverse(*this, data);
--_currentLevel;
}
virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
{
addNodeBox(node, data);
addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2));
}
osg::Node* getNode() const { return _group.get(); }
static unsigned allLevels() { return ~0u; }
static unsigned triangles() { return ~0u - 1; }
private:
void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color)
{
if (_level != triangles())
return;
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(triangle.getVertex(0).osg());
vertices->push_back(triangle.getVertex(1).osg());
vertices->push_back(triangle.getVertex(2).osg());
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(color);
geometry->setVertexArray(vertices);
geometry->setColorArray(colors);
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3));
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geometry);
_group->addChild(geode);
}
void addNodeSphere(const BVHNode& node)
{
if (_level != ~0u && _level != _currentLevel)
return;
SGSphered sphere = node.getBoundingSphere();
osg::Sphere* shape = new osg::Sphere;
shape->setCenter(SGVec3f(sphere.getCenter()).osg());
shape->setRadius(sphere.getRadius());
addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
}
void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data)
{
if (_level != ~0u && _level != _currentLevel)
return;
BVHBoundingBoxVisitor bbv;
node.accept(bbv, data);
osg::Box* shape = new osg::Box;
shape->setCenter(bbv.getBox().getCenter().osg());
shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg());
addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
}
void addShape(osg::Shape* shape, const osg::Vec4& color)
{
osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable;
shapeDrawable->setColor(color);
shapeDrawable->setShape(shape);
osg::Geode* geode = new osg::Geode;
geode->addDrawable(shapeDrawable);
_group->addChild(geode);
}
osg::ref_ptr<osg::Group> _group;
const double _time;
const unsigned _level;
unsigned _currentLevel;
};
}
#endif
+92
View File
@@ -0,0 +1,92 @@
// Copyright (C) 2008 - 2009 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 "BVHGroup.hxx"
#include <algorithm>
namespace simgear {
BVHGroup::BVHGroup()
{
}
BVHGroup::~BVHGroup()
{
ChildList::iterator i;
for (i = _children.begin(); i != _children.end(); ++i) {
(*i)->removeParent(this);
*i = 0;
}
}
void
BVHGroup::accept(BVHVisitor& visitor)
{
visitor.apply(*this);
}
void
BVHGroup::clear()
{
_children.clear();
invalidateBound();
}
void
BVHGroup::addChild(BVHNode* child)
{
if (!child)
return;
ChildList::iterator i;
i = std::find(_children.begin(), _children.end(), child);
if (i != _children.end())
return;
invalidateBound();
child->addParent(this);
_children.push_back(child);
}
void
BVHGroup::removeChild(BVHNode* child)
{
if (!child)
return;
ChildList::iterator i;
i = std::find(_children.begin(), _children.end(), child);
if (i == _children.end())
return;
invalidateBound();
child->removeParent(this);
_children.erase(i);
}
SGSphered
BVHGroup::computeBoundingSphere() const
{
SGSphered sphere;
ChildList::const_iterator i;
for (i = _children.begin(); i != _children.end(); ++i)
sphere.expandBy((*i)->getBoundingSphere());
return sphere;
}
}
+61
View File
@@ -0,0 +1,61 @@
// Copyright (C) 2008 - 2009 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 BVHGroup_hxx
#define BVHGroup_hxx
#include <simgear/structure/SGSharedPtr.hxx>
#include "BVHNode.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
class BVHGroup : public BVHNode {
public:
BVHGroup();
virtual ~BVHGroup();
virtual void accept(BVHVisitor& visitor);
void traverse(BVHVisitor& visitor)
{
ChildList::const_iterator i;
for (i = _children.begin(); i != _children.end(); ++i)
(*i)->accept(visitor);
}
void clear();
void addChild(BVHNode* child);
void removeChild(BVHNode* child);
unsigned getNumChildren() const
{ return _children.size(); }
const BVHNode* getChild(unsigned i) const
{ if (_children.size() <= i) return 0; return _children[i]; }
BVHNode* getChild(unsigned i)
{ if (_children.size() <= i) return 0; return _children[i]; }
virtual SGSphered computeBoundingSphere() const;
private:
typedef std::vector<SGSharedPtr<BVHNode> > ChildList;
ChildList _children;
};
}
#endif
+49
View File
@@ -0,0 +1,49 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHLineGeometry.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
BVHLineGeometry::BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type) :
_lineSegment(lineSegment),
_type(type)
{
}
BVHLineGeometry::~BVHLineGeometry()
{
}
void
BVHLineGeometry::accept(BVHVisitor& visitor)
{
visitor.apply(*this);
}
SGSphered
BVHLineGeometry::computeBoundingSphere() const
{
SGSphered sphere;
sphere.expandBy(SGVec3d(_lineSegment.getStart()));
sphere.expandBy(SGVec3d(_lineSegment.getEnd()));
return sphere;
}
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright (C) 2008 - 2009 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 BVHLineGeometry_hxx
#define BVHLineGeometry_hxx
#include <simgear/math/SGGeometry.hxx>
#include "BVHNode.hxx"
namespace simgear {
class BVHLineGeometry : public BVHNode {
public:
enum Type {
CarrierCatapult,
CarrierWire
};
BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type);
virtual ~BVHLineGeometry();
virtual void accept(BVHVisitor& visitor);
const SGLineSegmentf& getLineSegment() const
{ return _lineSegment; }
Type getType() const
{ return _type; }
virtual SGSphered computeBoundingSphere() const;
private:
SGLineSegmentf _lineSegment;
Type _type;
};
}
#endif
+154
View File
@@ -0,0 +1,154 @@
// Copyright (C) 2008 - 2009 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.
//
#include <simgear/math/SGMath.hxx>
#include "BVHLineSegmentVisitor.hxx"
#include <simgear/math/SGGeometry.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
#include "BVHMotionTransform.hxx"
#include "BVHLineGeometry.hxx"
#include "BVHStaticGeometry.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
namespace simgear {
void
BVHLineSegmentVisitor::apply(BVHGroup& group)
{
if (!intersects(_lineSegment, group.getBoundingSphere()))
return;
group.traverse(*this);
}
void
BVHLineSegmentVisitor::apply(BVHTransform& transform)
{
if (!intersects(_lineSegment, transform.getBoundingSphere()))
return;
bool haveHit = _haveHit;
_haveHit = false;
// Push the line segment
SGLineSegmentd lineSegment = getLineSegment();
_lineSegment = transform.lineSegmentToLocal(lineSegment);
transform.traverse(*this);
if (_haveHit) {
_linearVelocity = transform.vecToWorld(_linearVelocity);
_angularVelocity = transform.vecToWorld(_angularVelocity);
SGVec3d point(transform.ptToWorld(_lineSegment.getEnd()));
_lineSegment.set(lineSegment.getStart(), point);
_normal = transform.vecToWorld(_normal);
} else {
_lineSegment = lineSegment;
_haveHit = haveHit;
}
}
void
BVHLineSegmentVisitor::apply(BVHMotionTransform& transform)
{
if (!intersects(_lineSegment, transform.getBoundingSphere()))
return;
bool haveHit = _haveHit;
_haveHit = false;
// Push the line segment
SGLineSegmentd lineSegment = getLineSegment();
SGMatrixd toLocal = transform.getToLocalTransform(_time);
_lineSegment = lineSegment.transform(toLocal);
transform.traverse(*this);
if (_haveHit) {
SGMatrixd toWorld = transform.getToWorldTransform(_time);
SGVec3d localStart = _lineSegment.getStart();
_linearVelocity += transform.getLinearVelocityAt(localStart);
_angularVelocity += transform.getAngularVelocity();
_linearVelocity = toWorld.xformVec(_linearVelocity);
_angularVelocity = toWorld.xformVec(_angularVelocity);
SGVec3d localEnd = _lineSegment.getEnd();
_lineSegment.set(lineSegment.getStart(), toWorld.xformPt(localEnd));
_normal = toWorld.xformVec(_normal);
if (!_id)
_id = transform.getId();
} else {
_lineSegment = lineSegment;
_haveHit = haveHit;
}
}
void
BVHLineSegmentVisitor::apply(BVHLineGeometry&)
{
}
void
BVHLineSegmentVisitor::apply(BVHStaticGeometry& node)
{
if (!intersects(_lineSegment, node.getBoundingSphere()))
return;
node.traverse(*this);
}
void
BVHLineSegmentVisitor::apply(const BVHStaticBinary& node,
const BVHStaticData& data)
{
if (!intersects(SGLineSegmentf(_lineSegment), node.getBoundingBox()))
return;
// The first box to enter is the one the startpoint is in.
// this increases the probability, that on exit of that box we do not
// even need to walk the other one, since the line segment is
// then already short enough to not intersect the other one anymore.
node.traverse(*this, data, _lineSegment.getStart());
}
void
BVHLineSegmentVisitor::apply(const BVHStaticTriangle& triangle,
const BVHStaticData& data)
{
SGTrianglef tri = triangle.getTriangle(data);
SGVec3f point;
if (!intersects(point, tri, SGLineSegmentf(_lineSegment), 1e-4f))
return;
setLineSegmentEnd(SGVec3d(point));
_normal = SGVec3d(tri.getNormal());
_linearVelocity = SGVec3d::zeros();
_angularVelocity = SGVec3d::zeros();
_material = data.getMaterial(triangle.getMaterialIndex());
_id = 0;
_haveHit = true;
}
}
@@ -0,0 +1,98 @@
// Copyright (C) 2008 - 2009 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 BVHLineSegmentVisitor_hxx
#define BVHLineSegmentVisitor_hxx
#include <simgear/math/SGGeometry.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/scene/material/mat.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
namespace simgear {
class BVHLineSegmentVisitor : public BVHVisitor {
public:
BVHLineSegmentVisitor(const SGLineSegmentd& lineSegment,
const double& t = 0) :
_lineSegment(lineSegment),
_time(t),
_material(0),
_id(0),
_haveHit(false)
{ }
virtual ~BVHLineSegmentVisitor()
{ }
bool empty() const
{ return !_haveHit; }
const SGLineSegmentd& getLineSegment() const
{ return _lineSegment; }
SGVec3d getPoint() const
{ return _lineSegment.getEnd(); }
const SGVec3d& getNormal() const
{ return _normal; }
const SGVec3d& getLinearVelocity() const
{ return _linearVelocity; }
const SGVec3d& getAngularVelocity() const
{ return _angularVelocity; }
const SGMaterial* getMaterial() const
{ return _material; }
BVHNode::Id getId() const
{ return _id; }
virtual void apply(BVHGroup& group);
virtual void apply(BVHTransform& transform);
virtual void apply(BVHMotionTransform& transform);
virtual void apply(BVHLineGeometry&);
virtual void apply(BVHStaticGeometry& node);
virtual void apply(const BVHStaticBinary&, const BVHStaticData&);
virtual void apply(const BVHStaticTriangle&, const BVHStaticData&);
protected:
void setLineSegmentEnd(const SGVec3d& end)
{
// Ok, you need to make sure that the new end is in the previous
// direction and that the line segment is not enlarged by that call.
#ifndef _NDEBUG
// FIXME insert code to check this...
#endif
_lineSegment.set(_lineSegment.getStart(), end);
}
private:
SGLineSegmentd _lineSegment;
double _time;
// belongs in a derived class
SGVec3d _normal;
SGVec3d _linearVelocity;
SGVec3d _angularVelocity;
const SGMaterial* _material;
BVHNode::Id _id;
bool _haveHit;
};
}
#endif
+116
View File
@@ -0,0 +1,116 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHMotionTransform.hxx"
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
namespace simgear {
BVHMotionTransform::BVHMotionTransform() :
_toWorldReference(SGMatrixd::unit()),
_toLocalReference(SGMatrixd::unit()),
_toWorldAmplification(1),
_toLocalAmplification(1),
_linearVelocity(0, 0, 0),
_angularVelocity(0, 0, 0),
_referenceTime(0),
_startTime(0),
_endTime(0),
_id(0)
{
}
BVHMotionTransform::~BVHMotionTransform()
{
}
void
BVHMotionTransform::accept(BVHVisitor& visitor)
{
visitor.apply(*this);
}
void
BVHMotionTransform::setTransform(const BVHMotionTransform& transform)
{
_toWorldReference = transform._toWorldReference;
_toLocalReference = transform._toLocalReference;
_toWorldAmplification = transform._toWorldAmplification;
_toLocalAmplification = transform._toLocalAmplification;
_linearVelocity = transform._linearVelocity;
_angularVelocity = transform._angularVelocity;
_referenceTime = transform._referenceTime;
_startTime = transform._startTime;
_endTime = transform._endTime;
_id = transform._id;
invalidateParentBound();
}
void
BVHMotionTransform::setToWorldTransform(const SGMatrixd& transform)
{
_toWorldReference = transform;
invert(_toLocalReference, transform);
updateAmplificationFactors();
invalidateParentBound();
}
void
BVHMotionTransform::setToLocalTransform(const SGMatrixd& transform)
{
_toLocalReference = transform;
invert(_toWorldReference, transform);
updateAmplificationFactors();
invalidateParentBound();
}
SGSphered
BVHMotionTransform::computeBoundingSphere() const
{
SGSphered sphere(BVHGroup::computeBoundingSphere());
if (sphere.empty())
return sphere;
SGMatrixd toWorldStart = getToWorldTransform(_startTime);
SGVec3d centerStart = toWorldStart.xformPt(sphere.getCenter());
SGMatrixd toWorldEnd = getToWorldTransform(_endTime);
SGVec3d centerEnd = toWorldEnd.xformPt(sphere.getCenter());
double rad = 0.5*length(centerStart - centerEnd) + sphere.getRadius();
rad *= _toWorldAmplification;
return SGSphered(0.5*(centerStart + centerEnd), rad);
}
void
BVHMotionTransform::updateAmplificationFactors()
{
// Hmm, this is just a hint, true?
// But anyway, almost all transforms in a scenegraph will
// have them equal to 1 ...
double r = norm(_toWorldReference.xformVec(SGVec3d(1, 0, 0)));
r = std::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 1, 0))));
r = std::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 0, 1))));
_toWorldAmplification = r;
r = norm(_toLocalReference.xformVec(SGVec3d(1, 0, 0)));
r = std::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 1, 0))));
r = std::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 0, 1))));
_toLocalAmplification = r;
}
}
+126
View File
@@ -0,0 +1,126 @@
// Copyright (C) 2008 - 2009 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 BVHMotionTransform_hxx
#define BVHMotionTransform_hxx
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
namespace simgear {
class BVHMotionTransform : public BVHGroup {
public:
BVHMotionTransform();
virtual ~BVHMotionTransform();
virtual void accept(BVHVisitor& visitor);
void setTransform(const BVHMotionTransform& transform);
void setToWorldTransform(const SGMatrixd& transform);
void setToLocalTransform(const SGMatrixd& transform);
void setLinearVelocity(const SGVec3d& linearVelocity)
{ _linearVelocity = linearVelocity; }
const SGVec3d& getLinearVelocity() const
{ return _linearVelocity; }
void setAngularVelocity(const SGVec3d& angularVelocity)
{ _angularVelocity = angularVelocity; }
const SGVec3d& getAngularVelocity() const
{ return _angularVelocity; }
void setReferenceTime(const double& referenceTime)
{ _referenceTime = referenceTime; }
const double& getReferenceTime() const
{ return _referenceTime; }
void setStartTime(const double& startTime)
{ _startTime = startTime; }
const double& getStartTime() const
{ return _startTime; }
void setEndTime(const double& endTime)
{ _endTime = endTime; }
const double& getEndTime() const
{ return _endTime; }
SGMatrixd getToWorldTransform(const double& t) const
{
if (t == _referenceTime)
return _toWorldReference;
double dt = t - _referenceTime;
SGMatrixd matrix(_toWorldReference);
matrix.postMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity));
matrix.postMultTranslate(dt*_linearVelocity);
return matrix;
}
SGMatrixd getToLocalTransform(const double& t) const
{
if (t == _referenceTime)
return _toLocalReference;
double dt = _referenceTime - t;
SGMatrixd matrix(_toLocalReference);
matrix.preMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity));
matrix.preMultTranslate(dt*_linearVelocity);
return matrix;
}
const SGMatrixd& getToWorldReferenceTransform() const
{ return _toWorldReference; }
const SGMatrixd& getToLocalReferenceTransform() const
{ return _toLocalReference; }
SGVec3d getLinearVelocityAt(const SGVec3d& reference) const
{ return _linearVelocity + cross(_angularVelocity, reference); }
SGSphered sphereToLocal(const SGSphered& sphere, const double& t) const
{
SGMatrixd matrix = getToLocalTransform(t);
SGVec3d center = matrix.xformPt(sphere.getCenter());
double radius = _toLocalAmplification*sphere.getRadius();
return SGSphered(center, radius);
}
void setId(Id id)
{ _id = id; }
Id getId() const
{ return _id; }
private:
virtual SGSphered computeBoundingSphere() const;
void updateAmplificationFactors();
SGMatrixd _toWorldReference;
SGMatrixd _toLocalReference;
double _toWorldAmplification;
double _toLocalAmplification;
SGVec3d _linearVelocity;
SGVec3d _angularVelocity;
double _referenceTime;
double _startTime;
double _endTime;
Id _id;
};
}
#endif
@@ -0,0 +1,166 @@
// Copyright (C) 2008 - 2009 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 BVHNearestPointVisitor_hxx
#define BVHNearestPointVisitor_hxx
#include <simgear/math/SGGeometry.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
#include "BVHLineGeometry.hxx"
#include "BVHStaticGeometry.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
namespace simgear {
class BVHNearestPointVisitor : public BVHVisitor {
public:
BVHNearestPointVisitor(const SGSphered& sphere, const double& t) :
_sphere(sphere),
_time(t),
_material(0),
_id(0),
_havePoint(false)
{ }
virtual void apply(BVHGroup& leaf)
{
if (!intersects(_sphere, leaf.getBoundingSphere()))
return;
leaf.traverse(*this);
}
virtual void apply(BVHTransform& transform)
{
if (!intersects(_sphere, transform.getBoundingSphere()))
return;
SGSphered sphere = _sphere;
_sphere = transform.sphereToLocal(sphere);
bool havePoint = _havePoint;
_havePoint = false;
transform.traverse(*this);
if (_havePoint) {
_point = transform.ptToWorld(_point);
_linearVelocity = transform.vecToWorld(_linearVelocity);
_angularVelocity = transform.vecToWorld(_angularVelocity);
}
_havePoint |= havePoint;
_sphere.setCenter(sphere.getCenter());
}
virtual void apply(BVHMotionTransform& transform)
{
if (!intersects(_sphere, transform.getBoundingSphere()))
return;
SGSphered sphere = _sphere;
_sphere = transform.sphereToLocal(sphere, _time);
bool havePoint = _havePoint;
_havePoint = false;
transform.traverse(*this);
if (_havePoint) {
SGMatrixd toWorld = transform.getToWorldTransform(_time);
SGVec3d localCenter = _sphere.getCenter();
_linearVelocity += transform.getLinearVelocityAt(localCenter);
_angularVelocity += transform.getAngularVelocity();
_linearVelocity = toWorld.xformVec(_linearVelocity);
_angularVelocity = toWorld.xformVec(_angularVelocity);
_point = toWorld.xformPt(_point);
if (!_id)
_id = transform.getId();
}
_havePoint |= havePoint;
_sphere.setCenter(sphere.getCenter());
}
virtual void apply(BVHLineGeometry& node)
{ }
virtual void apply(BVHStaticGeometry& node)
{
if (!intersects(_sphere, node.getBoundingSphere()))
return;
node.traverse(*this);
}
virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
{
if (!intersects(_sphere, node.getBoundingBox()))
return;
node.traverse(*this, data, _sphere.getCenter());
}
virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
{
SGVec3f center(_sphere.getCenter());
SGVec3d closest(closestPoint(node.getTriangle(data), center));
if (!intersects(_sphere, closest))
return;
_point = closest;
_linearVelocity = SGVec3d::zeros();
_angularVelocity = SGVec3d::zeros();
_material = data.getMaterial(node.getMaterialIndex());
// The trick is to decrease the radius of the search sphere.
_sphere.setRadius(length(closest - _sphere.getCenter()));
_havePoint = true;
_id = 0;
}
void setSphere(const SGSphered& sphere)
{ _sphere = sphere; }
const SGSphered& getSphere() const
{ return _sphere; }
const SGVec3d& getPoint() const
{ return _point; }
const SGVec3d& getLinearVelocity() const
{ return _linearVelocity; }
const SGVec3d& getAngularVelocity() const
{ return _angularVelocity; }
const SGMaterial* getMaterial() const
{ return _material; }
BVHNode::Id getId() const
{ return _id; }
bool empty() const
{ return !_havePoint; }
private:
SGSphered _sphere;
double _time;
SGVec3d _point;
SGVec3d _linearVelocity;
SGVec3d _angularVelocity;
const SGMaterial* _material;
BVHNode::Id _id;
bool _havePoint;
};
}
#endif
+80
View File
@@ -0,0 +1,80 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHNode.hxx"
#include <algorithm>
#include <simgear/structure/SGAtomic.hxx>
#include <simgear/math/SGGeometry.hxx>
namespace simgear {
BVHNode::BVHNode() :
_dirtyBoundingSphere(true)
{
}
BVHNode::~BVHNode()
{
}
BVHNode::Id
BVHNode::getNewId()
{
static SGAtomic id(0);
return ++id;
}
void
BVHNode::addParent(BVHNode* parent)
{
// should not happen, but be paranoid ...
ParentList::iterator i;
i = std::find(_parents.begin(), _parents.end(), parent);
if (i != _parents.end())
return;
// add to the parents list ...
_parents.push_back(parent);
}
void
BVHNode::removeParent(BVHNode* parent)
{
ParentList::iterator i;
i = std::find(_parents.begin(), _parents.end(), parent);
if (i == _parents.end())
return;
_parents.erase(i);
}
void
BVHNode::invalidateParentBound()
{
for (ParentList::iterator i = _parents.begin(); i != _parents.end(); ++i)
(*i)->invalidateBound();
}
void
BVHNode::invalidateBound()
{
if (_dirtyBoundingSphere)
return;
invalidateParentBound();
_dirtyBoundingSphere = true;
}
}
+74
View File
@@ -0,0 +1,74 @@
// Copyright (C) 2008 - 2009 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 BVHNode_hxx
#define BVHNode_hxx
#include <vector>
#include <simgear/math/SGGeometry.hxx>
#include <simgear/structure/SGReferenced.hxx>
namespace simgear {
class BVHGroup;
class BVHVisitor;
// Base for the tree nodes
class BVHNode : public SGReferenced {
public:
BVHNode();
virtual ~BVHNode();
// visitors ...
virtual void accept(BVHVisitor& visitor) = 0;
const SGSphered& getBoundingSphere() const
{
if (_dirtyBoundingSphere) {
_boundingSphere = computeBoundingSphere();
_dirtyBoundingSphere = false;
}
return _boundingSphere;
}
virtual SGSphered computeBoundingSphere() const = 0;
/// A unique id for some kind of BVHNodes.
/// Currently only motions transforms.
typedef unsigned Id;
// Factory to get a new id
static Id getNewId();
protected:
friend class BVHGroup;
void addParent(BVHNode* parent);
void removeParent(BVHNode* parent);
void invalidateParentBound();
virtual void invalidateBound();
private:
mutable bool _dirtyBoundingSphere;
mutable SGSphered _boundingSphere;
typedef std::vector<BVHNode*> ParentList;
ParentList _parents;
};
}
#endif
+45
View File
@@ -0,0 +1,45 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHStaticBinary.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
BVHStaticBinary::BVHStaticBinary(unsigned splitAxis,
const BVHStaticNode* leftChild,
const BVHStaticNode* rightChild,
const SGBoxf& boundingBox) :
_splitAxis(splitAxis),
_leftChild(leftChild),
_rightChild(rightChild),
_boundingBox(boundingBox)
{
}
BVHStaticBinary::~BVHStaticBinary()
{
}
void
BVHStaticBinary::accept(BVHVisitor& visitor, const BVHStaticData& data) const
{
visitor.apply(*this, data);
}
}
+78
View File
@@ -0,0 +1,78 @@
// Copyright (C) 2008 - 2009 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 BVHStaticBinary_hxx
#define BVHStaticBinary_hxx
#include <simgear/math/SGGeometry.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include "BVHStaticNode.hxx"
namespace simgear {
class BVHStaticBinary : public BVHStaticNode {
public:
BVHStaticBinary(unsigned splitAxis, const BVHStaticNode* leftChild,
const BVHStaticNode* rightChild, const SGBoxf& box);
virtual ~BVHStaticBinary();
virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const;
void traverse(BVHVisitor& visitor, const BVHStaticData& data) const
{
_leftChild->accept(visitor, data);
_rightChild->accept(visitor, data);
}
// Traverse call that first enters the child node that is potentially closer
// to the given point than the other.
template<typename T>
void traverse(BVHVisitor& visitor, const BVHStaticData& data,
const SGVec3<T>& pt) const
{
float center = 0.5f*(_boundingBox.getMin()[_splitAxis]
+ _boundingBox.getMax()[_splitAxis]);
if (pt[_splitAxis] < center) {
_leftChild->accept(visitor, data);
_rightChild->accept(visitor, data);
} else {
_rightChild->accept(visitor, data);
_leftChild->accept(visitor, data);
}
}
unsigned getSplitAxis() const
{ return _splitAxis; }
const BVHStaticNode* getLeftChild() const
{ return _leftChild; }
const BVHStaticNode* getRightChild() const
{ return _rightChild; }
const SGBoxf& getBoundingBox() const
{ return _boundingBox; }
private:
// Note the order of the members, this is to avoid padding
unsigned _splitAxis;
SGSharedPtr<const BVHStaticNode> _leftChild;
SGSharedPtr<const BVHStaticNode> _rightChild;
SGBoxf _boundingBox;
};
}
#endif
+61
View File
@@ -0,0 +1,61 @@
// Copyright (C) 2008 - 2009 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 BVHStaticData_hxx
#define BVHStaticData_hxx
#include <vector>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGGeometry.hxx>
/// FIXME, the SGMaterial class is too much tied to the scenegraph aspects of
/// the materials. Use some class more decribing the
/// nature of the surface we live on ...
class SGMaterial;
namespace simgear {
class BVHStaticData : public SGReferenced {
public:
virtual ~BVHStaticData() {}
unsigned addVertex(const SGVec3f& vertex)
{ _vertices.push_back(vertex); return _vertices.size() - 1; }
const SGVec3f& getVertex(unsigned i) const
{ return _vertices[i]; }
unsigned addMaterial(const SGMaterial* material)
{ _materials.push_back(material); return _materials.size() - 1; }
const SGMaterial* getMaterial(unsigned i) const
{ if (_materials.size() <= i) return 0; return _materials[i]; }
void trim()
{
std::vector<SGVec3f>(_vertices).swap(_vertices);
std::vector<const SGMaterial*>(_materials).swap(_materials);
}
private:
std::vector<SGVec3f> _vertices;
std::vector<const SGMaterial*> _materials;
};
}
#endif
+51
View File
@@ -0,0 +1,51 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHStaticGeometry.hxx"
#include "BVHBoundingBoxVisitor.hxx"
namespace simgear {
BVHStaticGeometry::BVHStaticGeometry(const BVHStaticNode* staticNode,
const BVHStaticData* staticData) :
_staticNode(staticNode),
_staticData(staticData)
{
}
BVHStaticGeometry::~BVHStaticGeometry()
{
}
void
BVHStaticGeometry::accept(BVHVisitor& visitor)
{
visitor.apply(*this);
}
SGSphered
BVHStaticGeometry::computeBoundingSphere() const
{
BVHBoundingBoxVisitor bbv;
_staticNode->accept(bbv, *_staticData);
SGSphered sphere;
sphere.expandBy(SGBoxd(bbv.getBox()));
return sphere;
}
}
+56
View File
@@ -0,0 +1,56 @@
// Copyright (C) 2008 - 2009 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 BVHStaticGeometry_hxx
#define BVHStaticGeometry_hxx
#include <simgear/math/SGGeometry.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
namespace simgear {
class BVHStaticGeometry : public BVHNode {
public:
BVHStaticGeometry(const BVHStaticNode* staticNode,
const BVHStaticData* staticData);
virtual ~BVHStaticGeometry();
virtual void accept(BVHVisitor& visitor);
void traverse(BVHVisitor& visitor) const
{ _staticNode->accept(visitor, *_staticData); }
const BVHStaticData* getStaticData() const
{ return _staticData; }
const BVHStaticNode* getStaticNode() const
{ return _staticNode; }
virtual SGSphered computeBoundingSphere() const;
private:
SGSharedPtr<const BVHStaticNode> _staticNode;
SGSharedPtr<const BVHStaticData> _staticData;
};
}
#endif
@@ -0,0 +1,228 @@
// Copyright (C) 2008 - 2009 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 BVHStaticGeometryBuilder_hxx
#define BVHStaticGeometryBuilder_hxx
#include <algorithm>
#include <map>
#include <set>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include "BVHVisitor.hxx"
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
#include "BVHStaticLeaf.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
#include "BVHStaticGeometry.hxx"
namespace simgear {
class BVHStaticGeometryBuilder : public SGReferenced {
public:
BVHStaticGeometryBuilder() :
_staticData(new BVHStaticData),
_currentMaterial(0),
_currentMaterialIndex(~0u)
{ }
virtual ~BVHStaticGeometryBuilder()
{ }
struct LeafRef {
LeafRef(const BVHStaticLeaf* leaf, const BVHStaticData& data) :
_leaf(leaf),
_box(_leaf->computeBoundingBox(data)),
_center(_leaf->computeCenter(data))
{ }
SGSharedPtr<const BVHStaticLeaf> _leaf;
SGBoxf _box;
SGVec3f _center;
};
typedef std::list<LeafRef> LeafRefList;
struct LeafRefLess : public std::binary_function<LeafRef, LeafRef, bool> {
LeafRefLess(unsigned sortAxis) : _sortAxis(sortAxis) {}
bool operator()(const LeafRef& x, const LeafRef& y)
{ return x._center[_sortAxis] < y._center[_sortAxis]; }
unsigned _sortAxis;
};
SGSharedPtr<BVHStaticData> _staticData;
LeafRefList _leafRefList;
typedef std::map<SGVec3f, unsigned> VertexMap;
VertexMap _vertexMap;
typedef std::set<SGVec3<unsigned> > TriangleSet;
TriangleSet _triangleSet;
void setCurrentMaterial(const SGMaterial* material)
{
_currentMaterial = material;
_currentMaterialIndex = addMaterial(material);
}
const SGMaterial* getCurrentMaterial() const
{
return _currentMaterial;
}
unsigned addMaterial(const SGMaterial* material)
{
MaterialMap::const_iterator i = _materialMap.find(material);
if (i != _materialMap.end())
return i->second;
unsigned index = _staticData->addMaterial(material);
_materialMap[material] = index;
return index;
}
typedef std::map<const SGMaterial*, unsigned> MaterialMap;
MaterialMap _materialMap;
const SGMaterial* _currentMaterial;
unsigned _currentMaterialIndex;
void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3)
{
unsigned indices[3] = { addVertex(v1), addVertex(v2), addVertex(v3) };
std::sort(indices, indices + 3);
SGVec3<unsigned> indexKey(indices);
if (_triangleSet.find(indexKey) != _triangleSet.end())
return;
_triangleSet.insert(indexKey);
BVHStaticTriangle* staticTriangle;
staticTriangle = new BVHStaticTriangle(_currentMaterialIndex, indices);
_leafRefList.push_back(LeafRef(staticTriangle, *_staticData));
}
unsigned addVertex(const SGVec3f& v)
{
VertexMap::const_iterator i = _vertexMap.find(v);
if (i != _vertexMap.end())
return i->second;
unsigned index = _staticData->addVertex(v);
_vertexMap[v] = index;
return index;
}
BVHStaticGeometry* buildTree()
{
const BVHStaticNode* tree = buildTreeRecursive(_leafRefList);
if (!tree)
return 0;
_staticData->trim();
return new BVHStaticGeometry(tree, _staticData);
}
private:
static void
centerSplitLeafs(unsigned splitAxis, const double& splitValue,
LeafRefList& leafs, LeafRefList split[2])
{
while (!leafs.empty()) {
if (leafs.front()._center[splitAxis] < splitValue) {
split[0].splice(split[0].begin(), leafs, leafs.begin());
} else {
split[1].splice(split[1].begin(), leafs, leafs.begin());
}
}
}
static void
equalSplitLeafs(unsigned splitAxis, LeafRefList& leafs,
LeafRefList split[2])
{
leafs.sort(LeafRefLess(splitAxis));
while (true) {
if (leafs.empty())
break;
split[0].splice(split[0].begin(), leafs, leafs.begin());
if (leafs.empty())
break;
split[1].splice(split[1].begin(), leafs, --leafs.end());
}
}
static const BVHStaticNode* buildTreeRecursive(LeafRefList& leafs)
{
// recursion termination
if (leafs.empty())
return 0;
// FIXME size is O(n)!!!
// if (leafs.size() == 1)
if (++leafs.begin() == leafs.end())
return leafs.front()._leaf;
SGBoxf box;
for (LeafRefList::const_iterator i = leafs.begin();
i != leafs.end(); ++i)
box.expandBy(i->_box);
// // FIXME ...
// if (length(box.getSize()) < 1)
// return new BVHBox(box);
if (box.empty())
return 0;
unsigned splitAxis = box.getBroadestAxis();
LeafRefList splitLeafs[2];
double splitValue = box.getCenter()[splitAxis];
centerSplitLeafs(splitAxis, splitValue, leafs, splitLeafs);
if (splitLeafs[0].empty() || splitLeafs[1].empty()) {
for (unsigned i = 0; i < 3 ; ++i) {
if (i == splitAxis)
continue;
leafs.swap(splitLeafs[0]);
leafs.splice(leafs.begin(), splitLeafs[1]);
splitValue = box.getCenter()[i];
centerSplitLeafs(i, splitValue, leafs, splitLeafs);
if (!splitLeafs[0].empty() && !splitLeafs[1].empty()) {
splitAxis = i;
break;
}
}
}
if (splitLeafs[0].empty() || splitLeafs[1].empty()) {
leafs.swap(splitLeafs[0]);
leafs.splice(leafs.begin(), splitLeafs[1]);
equalSplitLeafs(splitAxis, leafs, splitLeafs);
}
const BVHStaticNode* child0 = buildTreeRecursive(splitLeafs[0]);
const BVHStaticNode* child1 = buildTreeRecursive(splitLeafs[1]);
if (!child0)
return child1;
if (!child1)
return child0;
return new BVHStaticBinary(splitAxis, child0, child1, box);
}
};
}
#endif
+27
View File
@@ -0,0 +1,27 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHStaticLeaf.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
BVHStaticLeaf::~BVHStaticLeaf()
{
}
}
+38
View File
@@ -0,0 +1,38 @@
// Copyright (C) 2008 - 2009 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 BVHStaticLeaf_hxx
#define BVHStaticLeaf_hxx
#include <simgear/math/SGGeometry.hxx>
#include "BVHStaticNode.hxx"
namespace simgear {
class BVHStaticLeaf : public BVHStaticNode {
public:
virtual ~BVHStaticLeaf();
virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const = 0;
virtual SGBoxf computeBoundingBox(const BVHStaticData&) const = 0;
virtual SGVec3f computeCenter(const BVHStaticData&) const = 0;
};
}
#endif
+26
View File
@@ -0,0 +1,26 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHStaticNode.hxx"
namespace simgear {
BVHStaticNode::~BVHStaticNode()
{
}
}
+37
View File
@@ -0,0 +1,37 @@
// Copyright (C) 2008 - 2009 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 BVHStaticNode_hxx
#define BVHStaticNode_hxx
#include <simgear/structure/SGReferenced.hxx>
namespace simgear {
class BVHStaticData;
class BVHVisitor;
class BVHStaticNode : public SGReferenced {
public:
virtual ~BVHStaticNode();
virtual void accept(BVHVisitor&, const BVHStaticData&) const = 0;
};
}
#endif
+58
View File
@@ -0,0 +1,58 @@
// Copyright (C) 2008 - 2009 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.
//
#include "BVHStaticTriangle.hxx"
#include "BVHVisitor.hxx"
namespace simgear {
BVHStaticTriangle::BVHStaticTriangle(unsigned material,
const unsigned indices[3]) :
_material(material)
{
for (unsigned i = 0; i < 3; ++i)
_indices[i] = indices[i];
}
BVHStaticTriangle::~BVHStaticTriangle()
{
}
void
BVHStaticTriangle::accept(BVHVisitor& visitor, const BVHStaticData& data) const
{
visitor.apply(*this, data);
}
SGBoxf
BVHStaticTriangle::computeBoundingBox(const BVHStaticData& data) const
{
SGBoxf box;
box.expandBy(data.getVertex(_indices[0]));
box.expandBy(data.getVertex(_indices[1]));
box.expandBy(data.getVertex(_indices[2]));
return box;
}
SGVec3f
BVHStaticTriangle::computeCenter(const BVHStaticData& data) const
{
return getTriangle(data).getCenter();
}
}

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