Compare commits

..

64 Commits

Author SHA1 Message Date
Automatic Release Builder
c92a953511 new version: 2016.4.3 2016-12-05 13:28:25 +01:00
James Turner
863ae19d1d Package::indexOfvariant works on fully-qualified IDs.
Should fix issues restoring variants in the launcher.
2016-11-29 15:44:19 +00:00
Automatic Release Builder
cd7b6d69b0 new version: 2016.4.2 2016-11-22 09:38:58 +01:00
Automatic Release Builder
277dab0d55 new version: 2016.4.1 2016-11-17 13:43:29 +01:00
Erik Hofman
321a3fdaba Fix a typo 2016-11-17 13:05:08 +01:00
Erik Hofman
2eb17d0083 Revetr previous paatch for SGVec4 so close to the release 2016-11-17 11:50:15 +01:00
Erik Hofman
ff7e4597e7 Maximize simd optimization 2016-11-17 11:48:16 +01:00
Erik Hofman
4a4baf1b42 Merge branch 'next' of ssh://git.code.sf.net/p/flightgear/simgear into next 2016-11-17 09:15:02 +01:00
Erik Hofman
2672d5cd11 include simd.hxx 2016-11-17 09:14:51 +01:00
Erik Hofman
1bf3d7c9b1 Add a copyright header 2016-11-16 15:34:25 +01:00
Erik Hofman
f7c0a7f933 Add a simd_t<int> class and more inlining 2016-11-16 14:00:25 +01:00
Erik Hofman
6bf864babb Add class assingment functions 2016-11-16 13:33:51 +01:00
Erik Hofman
43bd1b15ee Add a SIMD accelerator class for float[4] and double[4] types 2016-11-16 12:45:14 +01:00
Rebecca N. Palmer
14c79d9ffb Nasal: disable NASAL_NAN64 on non-x86
Not every architecture has <=48-bit virtual address spaces:
http://meetings-archive.debian.net/pub/debian-meetings/2016/miniconf_cambridge16/Thanks_for_the_Memory.webm
2016-11-15 22:50:41 +00:00
James Turner
3009aadaa6 Simplify Boost auto-detection on MSVC. 2016-11-14 23:05:10 +01:00
James Turner
fca64343ae Attempting to fix Windows include issues.
Only handle PackageRef by reference in the header file, so we don’t
create calls to the copy constructor and/or destructor. If this doesn’t
work will need to create a stub implementation file.
2016-11-14 07:52:15 +01:00
James Turner
042a2659f6 Disable Codecvt for now, libstdc++ is problematic.
Need to research which libstdc++ versions implement codecvt.
2016-11-14 07:45:23 +01:00
James Turner
fe54af405c Zlib is a public, not private include in Simgear.
Should fix Windows compilation as reported by Alan Teeder on the list.
2016-11-14 07:31:54 +01:00
James Turner
ab70090a0a Finally fix bogus terrasync download numbers.
(Staying a hotel with sufficiently slow wi-fi to debug this!)
2016-11-13 22:18:32 +01:00
James Turner
ee02750e95 Enforce VS2013/2015 requirement on Windows. 2016-11-13 14:57:39 +00:00
James Turner
f55007394e Make more includes target-specific. 2016-11-13 14:57:21 +00:00
James Turner
60a9e8fb7e Implement UTF-8 conversion using codecvt 2016-11-13 14:56:52 +00:00
James Turner
7f8455f731 Multi-thumbnail support in packages.
Allow multiple thumbnails per variant / package, including
tagging with types so we can require certain thumbnails in the future.
2016-11-13 14:56:31 +00:00
James Turner
6ae86fc4ca Fix a warning. 2016-11-13 12:02:12 +00:00
Torsten Dreyer
e1fb13bed8 Allow passing of service and protocol for DNS SRV requests 2016-11-09 13:30:58 +01:00
Torsten Dreyer
27fff3b72a Sort DNS TXT entries and provide an attribute map 2016-11-09 12:03:37 +01:00
Torsten Dreyer
6a9235223e Set correct class for DNS TXT queries 2016-11-09 09:44:10 +01:00
Stuart Buchanan
c1e50e9a9c Correct mesh size correction for building LOD ranges 2016-11-08 20:06:34 +00:00
Stuart Buchanan
dcbf5b7c11 Fix for OBJECT_BUILDING_MESH_DETAILED 2016-11-08 19:56:08 +00:00
Torsten Dreyer
4b571f2a24 Implement SRV and TXT DNS records 2016-11-08 17:09:37 +01:00
Erik Hofman
679b7b845c Always define the class destructor 2016-11-08 13:17:15 +01:00
Edward d'Auvergne
50d7127c51 Calculation of the illuminance factor for the moon.
This is a number ranging between 0 and 1 based on the log of the illuminance of
the moon outside the atmosphere.  It is calculated as

    factor = (log(I) - max_loglux) / (max_loglux - min_loglux) + 1.0,

where I is the illuminance of the moon outside the atmosphere and min_loglux and
max_loglux are hardcoded to -0.504030345621 and -4.39964634562 respectively.
Although the value should never be outside of [0, 1], for safety it is clipped
to be between these values.  For more background, see
http://forum.flightgear.org/viewtopic.php?f=47&t=28201&start=60#p270516 .
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
0e09ee4bce Calculation of the log of the illuminance of the moon outside the atmosphere.
This is the base 10 log of equation 20, converted from foot-candles to lux,
from:

   Krisciunas K. and Schaefer B.E. (1991). A model of the brightness of
moonlight, Publ. Astron.  Soc. Pacif. 103(667), 1033-1039 (DOI:
http://dx.doi.org/10.1086/132921).
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
76ebd569d5 Calculation and exposure of the moon's age and phase.
To obtain the sun's true longitude, the Star::getlonEcl() function has been
created.  The moon's age is then calculated as the difference between the moon's
and sun's true longitudes.  The phase is then simply half of one minus the
cosine of the age.  Hence these calculations are very cheap compared to the rest
of the moon position calculations.  The algorithm is from:

    Duffett-Smith, Peter. Practical Astronomy With Your Calculator. 3rd ed.
Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

The code can replicate the example in the book of Feb 26, 1979 at 16h UT, with
an age of -0.4767 degrees a phase of 0.0:

$ fgfs --aircraft=UFO --start-date-gmt=1979:02:26:16:00:00 --airport=EGLL \
--altitude=50000 --enable-hud

The calculated phase is 1.459e-5 and the age is -6.2908 (which is -0.43628
degrees).  For a recent full moon:

$ fgfs --aircraft=UFO --start-date-gmt=2015:11:25:22:44:00 --airport=EGLL \
--altitude=50000 --enable-hud

The calculated age is -3.1413 and the phase is 0.9999999778.
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
edcd42bc2d Optimisation of the celestialBody ephemeris code.
By storing repetitive intermediate calculations, the number of mathematical
operations for a single call to CelestialBody::updatePosition() has decreased by
12.  This matches the changes to MoonPos::updatePosition().
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
f04e501472 Exposure of the moon position.
The following functions have been added:  MoonPos::getM(), MoonPos::getw(),
MoonPos::getxg(), MoonPos::getyg(), MoonPos::getye(), MoonPos::getze(),
MoonPos::getDistance().  These are copied from and match the Star class
functions (but with xs and ys replaced by xg and yg).
2016-11-08 09:49:57 +01:00
Edward d'Auvergne
32d152ba38 A few spelling fixes for the moon position ephemeris code. 2016-11-08 09:49:57 +01:00
Edward d'Auvergne
94c4c44d92 Optimisation of the moon position ephemeris code.
By storing repetitive intermediate calculations, the number of mathematical
operations for a single call to MoonPos::updatePosition() has decreased by 32.
2016-11-08 09:49:57 +01:00
James Turner
ab1d4e651e Bugfix: avoid bogus download size on start
Missed a default init of the HTTP repo download content size, so until
the request response header was received, this could report a very
large value.
2016-11-07 15:49:07 +01:00
James Turner
5cd250e452 Packages: notify delegate of uninstalls. 2016-11-06 21:58:01 +01:00
James Turner
2dcff4bb8e Ensure build include location is used first.
Otherwise PREFIX_PATH headers might be found first, but these could be
from an older SimGear version.
2016-11-06 21:57:30 +01:00
James Turner
604a9ff614 Hopefully fix Win32 linkage. 2016-11-02 22:57:39 +00:00
James Turner
a09630bcca Cmake export fixes.
Should hopefully fix importing in FlightGear
2016-11-02 13:59:43 +00:00
James Turner
b44c70b3f4 Simplify isnan detection with C++11 library. 2016-10-30 22:49:38 +00:00
James Turner
e4cddb100e Drastically simplify compiler.h 2016-10-30 22:49:11 +00:00
Erik Hofman
e3a4144e6c Switch to SGMisc::isNaN 2016-10-28 11:18:40 +02:00
James Turner
51e7d95bf2 Require CMake 3.0, enable C++11
Let’s see what this breaks.
2016-10-24 22:52:51 +02:00
James Turner
202571386b Exported package fix.
https://sourceforge.net/p/flightgear/codetickets/1892/
2016-10-20 20:26:51 +01:00
Florent Rougon
7837bd0e11 Add parameter 'use_exact_name' to sg_gzifstream's constructor and open() method
This allows one to be sure about which file is opened.
2016-10-20 14:07:08 +02:00
Florent Rougon
11c6e5bf04 Require zlib 1.2.4 or compatible
Commit 8277857827 relies on zlib's
gzoffset() function (not just offset(): that was a typo in the commit
message, sorry). This function appeared in zlib 1.2.4 (which dates from
2010). Enforce this requirement with CMake.
2016-10-19 21:17:54 +02:00
Florent Rougon
8277857827 Add gzfilebuf::approxOffset() and sg_gzifstream::approxOffset()
gzfilebuf::approxOffset() is a wrapper for zlib's offset() function.
It can be useful to implement progress indicators and such.
2016-10-19 00:30:55 +02:00
Florent Rougon
412111ba5a Change sgSearchPathSep into a public static member: SGPath::pathListSep
This way, one can easily use the OS-dependent separarator for path lists in
other places to build and split path lists in an optimal way (e.g., not
sacrificing ';' on Unix, since the path list separator is ':' on this
platform).
2016-10-12 09:05:21 +02:00
James Turner
dd52b6af50 Remove some archaic code. 2016-10-09 11:08:17 +02:00
Erik Hofman
a97c145f56 Always return a value 2016-10-04 09:08:43 +02:00
Erik Hofman
b9deebb59d It's perfectly valid to call is_sample_stopped() even if the sample was already stopped. So remove the assert and replace it with an if-test 2016-10-03 09:55:31 +02:00
Richard Harrison
906813c90b Console handling: VS2015 seems to only work with redirection when both stdout and stderr are redirected; so show a message box error when redirecting only one stream. 2016-10-02 02:29:22 +02:00
Florent Rougon
1711592e64 A few more tests for simgear::strutils::split() 2016-10-01 10:44:33 +02:00
James Turner
7b2507cb19 Config changes to warn on older tools.
Warn on to-be-deprecated versions of Cmake, Visual Studio and GCC
2016-09-28 17:20:51 -05:00
James Turner
2e19aaaff9 Remove multi-arch workaround in CMake
Since we now require 2.8.11, we can rely on this bug being fixed.
2016-09-27 20:43:03 -05:00
James Turner
6854598b79 Initial pieces for full OBJ support.
Needs testing by aircraft developers, this is just the first piece.
2016-09-27 20:41:31 -05:00
Stuart Buchanan
809ddb21c9 Add STG verbs for building mesh integration.
Add OBJECT_BUILDING_MESH_ROUGH and OBJECT_BUILDING_MESH_DETAILED

Intended for use by OSM buildings.
2016-09-22 20:38:58 +01:00
Richard Harrison
38bab59c1a Revised Windows console handling
- When started from the console use the console (when no --console)

- When started from the GUI (with --console) open a new console window

- When started from the GUI (without --console) don't open a new console window; stdout/stderr will not appear (except in logfiles as they do now). This opens stderr/stdout on the NUL device to alleviate any potential issues

- When started from the Console (with --console) open a new console window

- Ensure that IO redirection still works when started from the console. When redirecting stdout stderr will also be redirected (providing it wasn't already via 2>&1) - otherwise output from stderr will be lost.

- When using redirection from the command prompt --console will produce an error message box.

Notes:
- fgfs needs to be a linked as Win32 GUI subsystem app - which it already is
- What can't be done is to make the cmd prompt run fgfs synchronously; this is only something that can be done via "start /wait fgfs"

Basically the way that Win32 works is quite sensible, but slightly at odds with the unix nature of the C-RTL; so the standard streams sort of get lost for GUI apps. AttachConsole and AllocConsole are provided to address this - but they do slightly different things. AttachConsole will attach to the cmd.exe (or any console related to the parent process), whereas AllocConsole will open a new one. Depending on where the application was launched from it makes sense to use AttachConsole for a cmd.exe launch and do nothing (unless --console is given) for a GUI launch.

Redirection is not available from the GUI (unless set in the Process Create block) - so really only available when launched from the command line. If any stream is redirected then all must be otherwise it appears that AttachConsole will undo the redirection by changing the standard handles.
2016-09-21 00:50:13 +02:00
James Turner
87590cafb2 Fix terrasync behaviour when net is down. 2016-09-07 22:49:03 +01:00
Automatic Release Builder
6e5cbd7fc5 new version: 2016.4.0 2016-09-06 12:50:55 +02:00
47 changed files with 2006 additions and 445 deletions

View File

@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.8.11)
cmake_minimum_required (VERSION 3.0)
if(COMMAND cmake_policy)
if(POLICY CMP0054)
@@ -16,28 +16,25 @@ include (CheckCXXSourceCompiles)
include (CheckCXXCompilerFlag)
include (GenerateExportHeader)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
# only relevant for building shared libs but let's set it regardless
set(CMAKE_OSX_RPATH 1)
# Set the C++ standard to C++98 to avoid compilation errors on GCC 6 (which
# defaults to C++14).
if(CMAKE_VERSION VERSION_LESS "3.1")
if(CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_CXX_FLAGS "-std=gnu++98 ${CMAKE_CXX_FLAGS}")
endif()
else()
set (CMAKE_CXX_STANDARD 98)
endif()
project(SimGear)
# let's use & require C++11 - note these are only functional with CMake 3.1
# we do manual fallbacks for CMake 3.0 in the compilers section
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
# read 'version' file into a variable (stripping any newlines or spaces)
file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION)
project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it
# Cmake documentation says we must set this before calling project(), but
# it only seems to be picked up setting it /after/ the call to project()
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7")
# add a dependency on the versino file
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version)
@@ -76,8 +73,6 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "simgear-${SIMGEAR_VERSION}" CACHE INTERNAL "
set(CPACK_SOURCE_IGNORE_FILES
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
message(STATUS "ignoring: ${CPACK_SOURCE_IGNORE_FILES}")
include (CPack)
# We have some custom .cmake scripts not in the official distribution.
@@ -100,21 +95,6 @@ message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
# Configure library search paths
#####################################################################################
if(NOT "${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "")
# Workaround for Ubuntu/Debian which introduced the "multiarch" library
# directory structure, which is unsupported by CMake < 2.8.10, so we need to
# add paths manually
# see http://www.cmake.org/Bug/view.php?id=12049 and
# http://www.cmake.org/Bug/view.php?id=12037
list(APPEND ADDITIONAL_LIBRARY_PATHS
/usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/lib/${CMAKE_LIBRARY_ARCHITECTURE})
message(STATUS "additional library directories: ${ADDITIONAL_LIBRARY_PATHS}")
endif()
#####################################################################################
if (NOT MSVC)
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
option(SYSTEM_EXPAT "Set to ON to build SimGear using the system expat library" OFF)
@@ -163,10 +143,8 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
set( OSG_MSVC ${OSG_MSVC}140 )
elseif (${MSVC_VERSION} EQUAL 1800)
set( OSG_MSVC ${OSG_MSVC}120 )
elseif (${MSVC_VERSION} EQUAL 1700)
set( OSG_MSVC ${OSG_MSVC}110 )
elseif (${MSVC_VERSION} EQUAL 1600)
set( OSG_MSVC ${OSG_MSVC}100 )
else ()
message(FATAL_ERROR "Visual Studio 2013/2015 is required now")
endif ()
if (CMAKE_CL_64)
set( OSG_MSVC ${OSG_MSVC}-64 )
@@ -178,24 +156,15 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/lib )
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/include)
GET_FILENAME_COMPONENT(MSVC_ROOT_PARENT_DIR ${MSVC_3RDPARTY_ROOT} PATH)
find_path(BOOST_ROOT boost/version.hpp
PATHS
${MSVC_ROOT_PARENT_DIR}
${MSVC_3RDPARTY_ROOT}/boost
${MSVC_3RDPARTY_ROOT}/boost_1_52_0
${MSVC_3RDPARTY_ROOT}/boost_1_51_0
${MSVC_3RDPARTY_ROOT}/boost_1_50_0
${MSVC_3RDPARTY_ROOT}/boost_1_49_0
${MSVC_3RDPARTY_ROOT}/boost_1_48_0
${MSVC_3RDPARTY_ROOT}/boost_1_47_0
${MSVC_3RDPARTY_ROOT}/boost_1_46_1
${MSVC_3RDPARTY_ROOT}/boost_1_46_0
${MSVC_3RDPARTY_ROOT}/boost_1_45_0
${MSVC_3RDPARTY_ROOT}/boost_1_44_0
)
# set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
if(NOT BOOST_INCLUDEDIR)
# if this variable was not set by the user, set it to 3rdparty root's
# parent dir, which is the normal location for people using our
# windows-3rd-party repo
GET_FILENAME_COMPONENT(MSVC_ROOT_PARENT_DIR ${MSVC_3RDPARTY_ROOT} PATH)
set(BOOST_INCLUDEDIR ${MSVC_ROOT_PARENT_DIR})
message(STATUS "BOOST_INCLUDEDIR is ${BOOST_INCLUDEDIR}")
endif()
if (NOT USE_AEONWAVE)
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
@@ -205,15 +174,9 @@ endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE)
find_library(COCOA_LIBRARY Cocoa)
# this should be handled by setting CMAKE_OSX_DEPLOYMENT_TARGET
# but it's not working reliably, so forcing it for now
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR
${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(Threads REQUIRED)
endif()
@@ -231,17 +194,14 @@ else()
if (ENABLE_SOUND)
if (USE_AEONWAVE)
find_package(AAX COMPONENTS aax REQUIRED)
include_directories( ${AAX_INCLUDE_DIR} )
else()
find_package(OpenAL REQUIRED)
include_directories( ${OPENAL_INCLUDE_DIR} )
endif()
message(STATUS "Sound support: ENABLED")
endif(ENABLE_SOUND)
find_package(OpenSceneGraph 3.2.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgViewer osgUtil)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
if (MSVC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSCENEGRAPH_INCLUDE_DIRS})
@@ -254,12 +214,12 @@ else()
int main() { return 0; }"
SIMGEAR_OSG_USE_UTF8_FILENAME)
if (NOT SIMGEAR_OSG_USE_UTF8_FILENAME)
message(WARNING "Please rebuild OSG with OSG_USE_UTF8_FILENAME set to ON")
message(FATAL_ERROR "Please rebuild OSG with OSG_USE_UTF8_FILENAME set to ON")
endif()
endif()
endif(SIMGEAR_HEADLESS)
find_package(ZLIB REQUIRED)
find_package(ZLIB 1.2.4 REQUIRED)
find_package(CURL REQUIRED)
if (SYSTEM_EXPAT)
@@ -277,8 +237,6 @@ else()
${PROJECT_BINARY_DIR}/3rdparty/expat)
endif(SYSTEM_EXPAT)
include_directories(${EXPAT_INCLUDE_DIRS})
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
@@ -350,19 +308,26 @@ SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on wi
# isnan might not be real symbol, so can't check using function_exists
check_cxx_source_compiles(
"#include <cmath>
int main() { return isnan(0.0);} "
HAVE_ISNAN)
check_cxx_source_compiles(
"#include <cmath>
"#include <cstdlib>
int main() { return std::isnan(0.0);} "
HAVE_STD_ISNAN)
if (NOT ${HAVE_STD_ISNAN})
message(FATAL_ERROR "Your compiler lacks C++11 std::isnan, please update it")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS_CXX "-Wall")
set(WARNING_FLAGS_C "-Wall")
if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
message(WARNING "GCC 4.4 will be required soon, please upgrade")
endif()
# certain GCC versions don't provide the atomic builds, and hence
# require is to provide them in SGAtomic.cxx
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
@@ -371,13 +336,17 @@ if(CMAKE_COMPILER_IS_GNUCXX)
GCC_ATOMIC_BUILTINS_FOUND)
endif(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# Boost redeclares class members
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
# fix Boost compilation :(
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -397,7 +366,7 @@ if(WIN32)
if(MSVC)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /MP")
if (NOT OSG_FSTREAM_EXPORT_FIXED AND ${MSVC_VERSION} GREATER 1599)
if (NOT OSG_FSTREAM_EXPORT_FIXED)
message(STATUS "For better linking performance, use OSG with patched fstream header")
# needed to avoid link errors on multiply-defined standard C++
# symbols. Suspect this may be an OSG-DB export bug
@@ -424,16 +393,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
# use BEFORE to ensure local directories are used first,
# ahead of system-installed libs
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
include_directories(BEFORE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
include_directories(
${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
)
add_definitions(-DHAVE_CONFIG_H)
# configure a header file to pass some of the CMake settings
@@ -471,8 +432,6 @@ endif()
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
include_directories(3rdparty/utf8/source)
if(ENABLE_DNS)
if(SYSTEM_UDNS)
message(STATUS "Requested to use system udns library, forcing SIMGEAR_SHARED to true")
@@ -512,7 +471,7 @@ configure_file(SimGearConfig.cmake.in
@ONLY
)
set(ConfigPackageLocation lib/cmake/SimGear)
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/SimGear)
install(EXPORT SimGearTargets
DESTINATION ${ConfigPackageLocation}
)

View File

@@ -54,24 +54,14 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
install(TARGETS SimGearCore
EXPORT SimGearTargets
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
add_library(SimGearScene SHARED ${sceneSources})
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
# EXPORT SimGearSceneConfig
install(TARGETS SimGearScene
EXPORT SimGearTargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
endif()
else()
message(STATUS "Library building mode: STATIC LIBRARIES")
@@ -94,9 +84,6 @@ else()
endforeach()
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
install(TARGETS SimGearCore
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
@@ -118,19 +105,51 @@ else()
endforeach()
add_library(SimGearScene STATIC ${sceneSources})
install(TARGETS SimGearScene
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(NOT SIMGEAR_HEADLESS)
endif(SIMGEAR_SHARED)
target_include_directories(SimGearCore BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_include_directories(SimGearCore PUBLIC
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
target_include_directories(SimGearCore PRIVATE
${EXPAT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS})
install(TARGETS SimGearCore
EXPORT SimGearTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if (NOT SIMGEAR_HEADLESS)
install(TARGETS SimGearScene
EXPORT SimGearTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
target_include_directories(SimGearScene BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_include_directories(SimGearScene PUBLIC ${OPENSCENEGRAPH_INCLUDE_DIRS})
if (USE_AEONWAVE)
target_include_directories(SimGearScene PRIVATE ${AAX_INCLUDE_DIR} )
else()
target_include_directories(SimGearScene PRIVATE ${OPENAL_INCLUDE_DIR} )
endif()
endif()
target_link_libraries(SimGearCore
${ZLIB_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${COCOA_LIBRARY}
${CURL_LIBRARIES})
${CURL_LIBRARIES}
${WINSOCK_LIBRARY})
if(SYSTEM_EXPAT)
target_link_libraries(SimGearCore
@@ -143,6 +162,8 @@ if(ENABLE_DNS AND SYSTEM_UDNS)
endif()
if(NOT SIMGEAR_HEADLESS)
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
target_link_libraries(SimGearScene
SimGearCore
${ZLIB_LIBRARY}
@@ -150,6 +171,9 @@ if(NOT SIMGEAR_HEADLESS)
${OPENAL_LIBRARY}
${OPENGL_LIBRARY}
${JPEG_LIBRARY})
# only actually needed by canvas/KeyboardEvent.cxx
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/utf8/source)
endif()
if(ENABLE_RTI)

View File

@@ -40,23 +40,12 @@
#define SG_DO_STRINGIZE(X) #X
#ifdef __GNUC__
# if __GNUC__ < 3
# error Time to upgrade. GNU compilers < 3.0 not supported
# elif (__GNUC__ == 3) && (__GNUC_MINOR__ < 4)
# warning GCC compilers prior to 3.4 are suspect
# endif
# define SG_GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
# define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
#endif // __GNUC__
/* KAI C++ */
#if defined(__KCC)
# define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
#endif // __KCC
//
// Microsoft compilers.
//
@@ -70,12 +59,6 @@
# define strdup _strdup
# define copysign _copysign
# endif
# if _MSC_VER < 1800
# define isnan _isnan
# endif
# if _MSC_VER < 1500
# define vsnprintf _vsnprintf
# endif
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
# pragma warning(disable: 4244) // conversion from double to float
@@ -91,49 +74,6 @@
#endif // _MSC_VER
//
// Native SGI compilers
//
#if defined ( sgi ) && !defined( __GNUC__ )
# if (_COMPILER_VERSION < 740)
# error Need MipsPro 7.4.0 or higher now
# endif
#define SG_HAVE_NATIVE_SGI_COMPILERS
#pragma set woff 1001,1012,1014,1116,1155,1172,1174
#pragma set woff 1401,1460,1551,1552,1681
#ifdef __cplusplus
# pragma set woff 1682,3303
# pragma set woff 3624
#endif
# define SG_COMPILER_STR "SGI MipsPro compiler version " SG_STRINGIZE(_COMPILER_VERSION)
#endif // Native SGI compilers
#if defined (__sun)
# define SG_UNIX
# include <strings.h>
# include <memory.h>
# if defined ( __cplusplus )
// typedef unsigned int size_t;
extern "C" {
extern void *memmove(void *, const void *, size_t);
}
# else
extern void *memmove(void *, const void *, size_t);
# endif // __cplusplus
# if !defined( __GNUC__ )
# define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
# endif
#endif // sun
//
// Intel C++ Compiler
//
@@ -148,29 +88,10 @@
#ifdef __APPLE__
# define SG_MAC
# define SG_UNIX
# ifdef __GNUC__
# if ( __GNUC__ > 3 ) || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 3 )
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
# 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__)
# define SG_UNIX
#include <sys/param.h>
# if __FreeBSD_version < 500000
extern "C" {
inline int isnan(double r) { return !(r <= 0 || r >= 0); }
}
# endif
#endif
#if defined (__CYGWIN__)

View File

@@ -211,8 +211,10 @@ const float SG_RADIANS_TO_DEGREES = 180.0f / SG_PI;
/** for backwards compatibility */
#define SG_SCENERY_FILE_FORMAT "0.4"
/** Default range in m at which all objects are displayed. Overridden by /sim/rendering/static-lod/rough **/
#define SG_OBJECT_RANGE 9000.0
/** Default object ranges. Overridden by /sim/rendering/static-lod/[bare|rough|detailed] **/
#define SG_OBJECT_RANGE_BARE 30000.0
#define SG_OBJECT_RANGE_ROUGH 9000.0
#define SG_OBJECT_RANGE_DETAILED 1500.0
/** Radius of scenery tiles in m **/
#define SG_TILE_RADIUS 14000.0

View File

@@ -42,6 +42,8 @@
#if defined (SG_WINDOWS)
// for AllocConsole, OutputDebugString
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#endif
const char* debugClassToString(sgDebugClass c)
@@ -222,26 +224,106 @@ public:
LogStreamPrivate() :
m_logClass(SG_ALL),
m_logPriority(SG_ALERT),
#if defined (SG_WINDOWS)
m_stdout_isRedirectedAlready(false),
m_stderr_isRedirectedAlready(false),
#endif
m_isRunning(false)
{
bool addStderr = true;
#if defined (SG_WINDOWS)
// Check for stream redirection, has to be done before we call
// Attach / AllocConsole
const bool isFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_DISK); // Redirect to file?
if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) {
// attach failed, don't install the callback
addStderr = false;
} else if (!isFile) {
// No - OK! now set streams to attached console
freopen("conout$", "w", stdout);
freopen("conout$", "w", stderr);
}
#endif
if (addStderr) {
m_callbacks.push_back(new StderrLogCallback(m_logClass, m_logPriority));
m_consoleCallbacks.push_back(m_callbacks.back());
/*
* 2016-09-20(RJH) - Reworked console handling
* 1) When started from the console use the console (when no --console)
* 2) When started from the GUI (with --console) open a new console window
* 3) When started from the GUI (without --console) don't open a new console
* window; stdout/stderr will not appear (except in logfiles as they do now)
* 4) When started from the Console (with --console) open a new console window
* 5) Ensure that IO redirection still works when started from the console
*
* Notes:
* 1) fgfs needs to be a GUI subsystem app - which it already is
* 2) What can't be done is to make the cmd prompt run fgfs synchronously;
* this is only something that can be done via "start /wait fgfs".
*/
int stderr_handle_type = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
int stdout_handle_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
int stdout_isNull = 0;
int stderr_isNull = 0;
m_stderr_isRedirectedAlready = stderr_handle_type == FILE_TYPE_DISK || stderr_handle_type == FILE_TYPE_PIPE || stderr_handle_type == FILE_TYPE_CHAR;
m_stdout_isRedirectedAlready = stdout_handle_type == FILE_TYPE_DISK || stdout_handle_type == FILE_TYPE_PIPE || stdout_handle_type == FILE_TYPE_CHAR;
/*
* We don't want to attach to the console if either stream has been redirected - so in this case ensure that both streams
* are redirected as otherwise something will be lost (as Alloc or Attach Console will cause the handles that were bound
* to disappear)
*/
if (m_stdout_isRedirectedAlready){
if (!m_stderr_isRedirectedAlready) {
MessageBox(0, "Redirection only works when you use 2>&1 before using > or |\r\n(e.g. fgfs 2>&1 | more)", "Simgear Error", MB_OK | MB_ICONERROR);
exit(3);
}
} else {
/*
* Attempt to attach to the console process of the parent process; when launched from cmd.exe this should be the console,
* when launched via the RUN menu explorer, or another GUI app that wasn't started from the console this will fail.
* When it fails we will redirect to the NUL device. This is to ensure that we have valid streams.
* Later on in the initialisation sequence the --console option will be processed and this will cause the requestConsole() to
* always open a new console, except for streams that are redirected. The same rules apply there, if both streams are redirected
* the console will be opened, and it will contain a message to indicate that no output will be present because the streams are redirected
*/
if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) {
/*
* attach failed - so ensure that the streams are bound to the null device - but only when not already redirected
*/
if (!m_stdout_isRedirectedAlready)
{
stdout_isNull = true;
freopen("NUL", "w", stdout);
}
if (!m_stderr_isRedirectedAlready)
{
stderr_isNull = true;
freopen("NUL", "w", stderr);
}
}
/*
* providing that AttachConsole succeeded - we can then either reopen the stream onto the console, or use
* _fdopen to attached to the currently redirected (and open stream)
*/
if (!stdout_isNull){
if (!m_stdout_isRedirectedAlready)
freopen("conout$", "w", stdout);
else
/*
* for already redirected streams we need to attach the stream to the OS handle that is open.
* - this comes from part of the answer http://stackoverflow.com/a/13841522
* _open_osfhandle returns an FD for the Win32 Handle, which is then opened using fdopen and
* hopefully safely assigned to the stream (although it does look wrong to me it works)
* Removing this bit will stop pipes and command line redirection (> 2> and 2>&1 from working)
*/
*stdout = *_fdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY), "a");
}
if (!stderr_isNull){
if (!m_stderr_isRedirectedAlready)
freopen("conout$", "w", stderr);
else
*stderr = *_fdopen(_open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_WRONLY), "a");
}
}
//http://stackoverflow.com/a/25927081
//Clear the error state for each of the C++ standard stream objects.
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
#endif
m_callbacks.push_back(new StderrLogCallback(m_logClass, m_logPriority));
m_consoleCallbacks.push_back(m_callbacks.back());
#if defined (SG_WINDOWS) && !defined(NDEBUG)
m_callbacks.push_back(new WinDebugLogCallback(m_logClass, m_logPriority));
m_consoleCallbacks.push_back(m_callbacks.back());
@@ -267,6 +349,11 @@ public:
sgDebugClass m_logClass;
sgDebugPriority m_logPriority;
bool m_isRunning;
#if defined (SG_WINDOWS)
// track whether the console was redirected on launch (in the constructor, which is called early on)
bool m_stderr_isRedirectedAlready;
bool m_stdout_isRedirectedAlready;
#endif
void startLog()
{
@@ -474,10 +561,47 @@ namespace simgear
{
void requestConsole()
{
// this is a no-op now, stub exists for compatability for the moment.
{
#if defined (SG_WINDOWS)
/*
* 2016-09-20(RJH) - Reworked console handling
* This is part of the reworked console handling for Win32. This is for building as a Win32 GUI Subsystem where no
* console is allocated on launch. If building as a console app then the startup will ensure that a console is created - but
* we don't need to handle that.
* The new handling is quite simple:
* 1. The constructor will ensure that these streams exists. It will attach to the
* parent command prompt if started from the command prompt, otherwise the
* stdout/stderr will be bound to the NUL device.
* 2. with --console a window will always appear regardless of where the process was
* started from. Any non redirected streams will be redirected
* 3. You cannot use --console and either redirected stream.
*
* This is called after the Private Log Stream constructor so we need to undo any console that it has attached to.
*/
if (!global_privateLogstream->m_stderr_isRedirectedAlready && !global_privateLogstream->m_stdout_isRedirectedAlready) {
FreeConsole();
if (AllocConsole()) {
if (!global_privateLogstream->m_stdout_isRedirectedAlready)
freopen("conout$", "w", stdout);
if (!global_privateLogstream->m_stderr_isRedirectedAlready)
freopen("conout$", "w", stderr);
//http://stackoverflow.com/a/25927081
//Clear the error state for each of the C++ standard stream objects.
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
}
} else {
MessageBox(0, "--console ignored because stdout or stderr redirected with > or 2>", "Simgear Error", MB_OK | MB_ICONERROR);
}
#endif
}
void shutdownLogging()
{
SGGuard<SGMutex> g(global_logStreamLock);

View File

@@ -52,7 +52,8 @@
void CelestialBody::updatePosition(double mjd, Star *ourSun)
{
double eccAnom, v, ecl, actTime,
xv, yv, xh, yh, zh, xg, yg, zg, xe, ye, ze;
xv, yv, xh, yh, zh, xg, yg, zg, xe, ye, ze,
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl;
updateOrbElements(mjd);
actTime = sgCalcActTime(mjd);
@@ -66,10 +67,19 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
v = atan2(yv, xv); // the planet's true anomaly
r = sqrt (xv*xv + yv*yv); // the planet's distance
// repetitive calculations, minimised for speed
cosN = cos(N);
sinN = sin(N);
cosvw = cos(v+w);
sinvw = sin(v+w);
sinvw_cosi = sinvw * cos(i);
cosecl = cos(ecl);
sinecl = sin(ecl);
// calculate the planet's position in 3D space
xh = r * (cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i));
yh = r * (sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i));
zh = r * (sin(v+w) * sin(i));
xh = r * (cosN * cosvw - sinN * sinvw_cosi);
yh = r * (sinN * cosvw + cosN * sinvw_cosi);
zh = r * (sinvw * sin(i));
// calculate the ecliptic longitude and latitude
xg = xh + ourSun->getxs();
@@ -80,8 +90,8 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
latEcl = atan2(zh, sqrt(xh*xh+yh*yh));
xe = xg;
ye = yg * cos(ecl) - zg * sin(ecl);
ze = yg * sin(ecl) + zg * cos(ecl);
ye = yg * cosecl - zg * sinecl;
ze = yg * sinecl + zg * cosecl;
rightAscension = atan2(ye, xe);
declination = atan2(ze, sqrt(xe*xe + ye*ye));
/* SG_LOG(SG_GENERAL, SG_INFO, "Planet found at : "

View File

@@ -26,6 +26,7 @@
#include <string.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/SGMath.hxx>
#include <math.h>
@@ -78,69 +79,90 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
{
double
eccAnom, ecl, actTime,
xv, yv, v, r, xh, yh, zh, xg, yg, zg, xe, ye, ze,
xv, yv, v, r, xh, yh, zh, zg, xe,
Ls, Lm, D, F, mpar, gclat, rho, HA, g,
geoRa, geoDec;
geoRa, geoDec,
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
double max_loglux = -0.504030345621;
double min_loglux = -4.39964634562;
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
updateOrbElements(mjd);
actTime = sgCalcActTime(mjd);
// calculate the angle between ecliptic and equatorial coordinate system
// in Radians
ecl = ((SGD_DEGREES_TO_RADIANS * 23.4393) - (SGD_DEGREES_TO_RADIANS * 3.563E-7) * actTime);
ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 * actTime);
eccAnom = sgCalcEccAnom(M, e); // Calculate the eccentric anomaly
xv = a * (cos(eccAnom) - e);
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
v = atan2(yv, xv); // the moon's true anomaly
r = sqrt (xv*xv + yv*yv); // and its distance
// repetitive calculations, minimised for speed
cosN = cos(N);
sinN = sin(N);
cosvw = cos(v+w);
sinvw = sin(v+w);
sinvw_cosi = sinvw * cos(i);
cosecl = cos(ecl);
sinecl = sin(ecl);
// estimate the geocentric rectangular coordinates here
xh = r * (cos(N) * cos (v+w) - sin (N) * sin(v+w) * cos(i));
yh = r * (sin(N) * cos (v+w) + cos (N) * sin(v+w) * cos(i));
zh = r * (sin(v+w) * sin(i));
xh = r * (cosN * cosvw - sinN * sinvw_cosi);
yh = r * (sinN * cosvw + cosN * sinvw_cosi);
zh = r * (sinvw * sin(i));
// calculate the ecliptic latitude and longitude here
lonEcl = atan2 (yh, xh);
latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
/* Calculate a number of perturbatioin, i.e. disturbances caused by the
* gravitational infuence of the sun and the other major planets.
/* Calculate a number of perturbation, i.e. disturbances caused by the
* gravitational influence of the sun and the other major planets.
* The largest of these even have a name */
Ls = ourSun->getM() + ourSun->getw();
Lm = M + w + N;
D = Lm - Ls;
F = Lm - N;
twoD = 2 * D;
twoM = 2 * M;
FlesstwoD = F - twoD;
MlesstwoD = M - twoD;
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin (M - 2*D)
+0.658 * sin (2*D)
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
+0.658 * sin(twoD)
-0.186 * sin(ourSun->getM())
-0.059 * sin(2*M - 2*D)
-0.057 * sin(M - 2*D + ourSun->getM())
+0.053 * sin(M + 2*D)
+0.046 * sin(2*D - ourSun->getM())
-0.059 * sin(twoM - twoD)
-0.057 * sin(MlesstwoD + ourSun->getM())
+0.053 * sin(M + twoD)
+0.046 * sin(twoD - ourSun->getM())
+0.041 * sin(M - ourSun->getM())
-0.035 * sin(D)
-0.031 * sin(M + ourSun->getM())
-0.015 * sin(2*F - 2*D)
-0.015 * sin(2*F - twoD)
+0.011 * sin(M - 4*D)
);
latEcl += SGD_DEGREES_TO_RADIANS * (-0.173 * sin(F-2*D)
-0.055 * sin(M - F - 2*D)
-0.046 * sin(M + F - 2*D)
+0.033 * sin(F + 2*D)
+0.017 * sin(2*M + F)
latEcl += SGD_DEGREES_TO_RADIANS * (-0.173 * sin(FlesstwoD)
-0.055 * sin(M - FlesstwoD)
-0.046 * sin(M + FlesstwoD)
+0.033 * sin(F + twoD)
+0.017 * sin(twoM + F)
);
r += (-0.58 * cos(M - 2*D)
-0.46 * cos(2*D)
r += (-0.58 * cos(MlesstwoD)
-0.46 * cos(twoD)
);
distance = r;
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
xg = r * cos(lonEcl) * cos(latEcl);
yg = r * sin(lonEcl) * cos(latEcl);
rcoslatEcl = r * cos(latEcl);
xg = cos(lonEcl) * rcoslatEcl;
yg = sin(lonEcl) * rcoslatEcl;
zg = r * sin(latEcl);
xe = xg;
ye = yg * cos(ecl) -zg * sin(ecl);
ze = yg * sin(ecl) +zg * cos(ecl);
ye = yg * cosecl -zg * sinecl;
ze = yg * sinecl +zg * cosecl;
geoRa = atan2(ye, xe);
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
@@ -154,17 +176,17 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
// topocentric ra and dec. i.e. the position as seen from the
// surface of the earth, instead of the center of the earth
// First calculate the moon's parrallax, that is, the apparent size of the
// First calculate the moon's parallax, that is, the apparent size of the
// (equatorial) radius of the earth, as seen from the moon
mpar = asin ( 1 / r);
// SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar );
// SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() );
gclat = lat - 0.003358 *
sin (2 * SGD_DEGREES_TO_RADIANS * lat );
twolat = 2 * SGD_DEGREES_TO_RADIANS * lat;
gclat = lat - 0.003358 * sin(twolat);
// SG_LOG( SG_GENERAL, SG_INFO, "gclat = " << gclat );
rho = 0.99883 + 0.00167 * cos(2 * SGD_DEGREES_TO_RADIANS * lat);
rho = 0.99883 + 0.00167 * cos(twolat);
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
if (geoRa < 0)
@@ -193,4 +215,22 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
/* SG_LOG( SG_GENERAL, SG_INFO,
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
// Moon age and phase calculation
age = lonEcl - ourSun->getlonEcl();
phase = (1 - cos(age)) / 2;
// The log of the illuminance of the moon outside the atmosphere.
// This is the base 10 log of equation 20 from Krisciunas K. and Schaefer B.E.
// (1991). A model of the brightness of moonlight, Publ. Astron. Soc. Pacif.
// 103(667), 1033-1039 (DOI: http://dx.doi.org/10.1086/132921).
alpha = SGD_RADIANS_TO_DEGREES * SGMiscd::normalizeAngle(age + SGMiscd::pi());
log_I = -0.4 * (3.84 + 0.026*fabs(alpha) + 4e-9*pow(alpha, 4.0));
// Convert from foot-candles to lux.
log_I += conv;
// The moon's illuminance factor, bracketed between 0 and 1.
I_factor = (log_I - max_loglux) / (max_loglux - min_loglux) + 1.0;
I_factor = SGMiscd::clip(I_factor, 0, 1);
}

View File

@@ -36,6 +36,13 @@ class MoonPos : public CelestialBody
private:
double xg, yg; // the moon's rectangular geocentric coordinates
double ye, ze; // the moon's rectangular equatorial coordinates
double distance; // the moon's distance to the earth
double age; // the moon's age from 0 to 2pi
double phase; // the moon's phase
double log_I; // the moon's illuminance outside the atmosphere (logged)
double I_factor; // the illuminance factor for the moon, between 0 and 1.
// void TexInit(); // This should move to the constructor eventually.
// GLUquadricObj *moonObject;
@@ -54,7 +61,72 @@ public:
~MoonPos();
void updatePosition(double mjd, double lst, double lat, Star *ourSun);
// void newImage();
double getM() const;
double getw() const;
double getxg() const;
double getyg() const;
double getye() const;
double getze() const;
double getDistance() const;
double getAge() const;
double getPhase() const;
double getLogIlluminance() const;
double getIlluminanceFactor() const;
};
inline double MoonPos::getM() const
{
return M;
}
inline double MoonPos::getw() const
{
return w;
}
inline double MoonPos::getxg() const
{
return xg;
}
inline double MoonPos::getyg() const
{
return yg;
}
inline double MoonPos::getye() const
{
return ye;
}
inline double MoonPos::getze() const
{
return ze;
}
inline double MoonPos::getDistance() const
{
return distance;
}
inline double MoonPos::getAge() const
{
return age;
}
inline double MoonPos::getPhase() const
{
return phase;
}
inline double MoonPos::getLogIlluminance() const
{
return log_I;
}
inline double MoonPos::getIlluminanceFactor() const
{
return I_factor;
}
#endif // _MOONPOS_HXX_

View File

@@ -33,6 +33,7 @@ class Star : public CelestialBody
private:
double lonEcl; // the sun's true longitude
double xs, ys; // the sun's rectangular geocentric coordinates
double ye, ze; // the sun's rectangularequatorial rectangular geocentric coordinates
double distance; // the sun's distance to the earth
@@ -50,6 +51,7 @@ public:
double getye() const;
double getze() const;
double getDistance() const;
double getlonEcl() const;
};
@@ -88,6 +90,10 @@ inline double Star::getDistance() const
return distance;
}
inline double Star::getlonEcl() const
{
return lonEcl;
}
#endif // _STAR_HXX_

View File

@@ -69,6 +69,96 @@ NAPTRRequest::NAPTRRequest( const std::string & dn ) :
_type = DNS_T_NAPTR;
}
SRVRequest::SRVRequest( const std::string & dn ) :
Request(dn)
{
_type = DNS_T_SRV;
}
SRVRequest::SRVRequest( const std::string & dn, const string & service, const string & protocol ) :
Request(dn),
_service(service),
_protocol(protocol)
{
_type = DNS_T_SRV;
}
static bool sortSRV( const SRVRequest::SRV_ptr a, const SRVRequest::SRV_ptr b )
{
if( a->priority > b->priority ) return false;
if( a->priority < b->priority ) return true;
return a->weight > b->weight;
}
static void dnscbSRV(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data)
{
SRVRequest * r = static_cast<SRVRequest*>(data);
if (result) {
r->cname = result->dnssrv_cname;
r->qname = result->dnssrv_qname;
r->ttl = result->dnssrv_ttl;
for (int i = 0; i < result->dnssrv_nrr; i++) {
SRVRequest::SRV_ptr srv(new SRVRequest::SRV);
r->entries.push_back(srv);
srv->priority = result->dnssrv_srv[i].priority;
srv->weight = result->dnssrv_srv[i].weight;
srv->port = result->dnssrv_srv[i].port;
srv->target = result->dnssrv_srv[i].name;
}
std::sort( r->entries.begin(), r->entries.end(), sortSRV );
free(result);
}
r->setComplete();
}
void SRVRequest::submit()
{
// if service is defined, pass service and protocol
if (!dns_submit_srv(NULL, getDn().c_str(), _service.empty() ? NULL : _service.c_str(), _service.empty() ? NULL : _protocol.c_str(), 0, dnscbSRV, this )) {
SG_LOG(SG_IO, SG_ALERT, "Can't submit dns request for " << getDn());
return;
}
_start = time(NULL);
}
TXTRequest::TXTRequest( const std::string & dn ) :
Request(dn)
{
_type = DNS_T_TXT;
}
static void dnscbTXT(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data)
{
TXTRequest * r = static_cast<TXTRequest*>(data);
if (result) {
r->cname = result->dnstxt_cname;
r->qname = result->dnstxt_qname;
r->ttl = result->dnstxt_ttl;
for (int i = 0; i < result->dnstxt_nrr; i++) {
//TODO: interprete the .len field of dnstxt_txt?
string txt = string((char*)result->dnstxt_txt[i].txt);
r->entries.push_back( txt );
string_list tokens = simgear::strutils::split( txt, "=", 1 );
if( tokens.size() == 2 ) {
r->attributes[tokens[0]] = tokens[1];
}
}
free(result);
}
r->setComplete();
}
void TXTRequest::submit()
{
// protocol and service an already encoded in DN so pass in NULL for both
if (!dns_submit_txt(NULL, getDn().c_str(), DNS_C_IN, 0, dnscbTXT, this )) {
SG_LOG(SG_IO, SG_ALERT, "Can't submit dns request for " << getDn());
return;
}
_start = time(NULL);
}
static bool sortNAPTR( const NAPTRRequest::NAPTR_ptr a, const NAPTRRequest::NAPTR_ptr b )
{
if( a->order > b->order ) return false;
@@ -130,7 +220,6 @@ void Client::makeRequest(const Request_ptr& r)
r->submit();
}
void Client::update(int waitTimeout)
{
time_t now = time(NULL);

View File

@@ -31,6 +31,7 @@
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/event_mgr.hxx>
namespace simgear
{
@@ -61,6 +62,7 @@ protected:
time_t _timeout_secs;
time_t _start;
};
typedef SGSharedPtr<Request> Request_ptr;
class NAPTRRequest : public Request
{
@@ -84,7 +86,38 @@ public:
std::string qservice;
};
typedef SGSharedPtr<Request> Request_ptr;
class SRVRequest : public Request
{
public:
SRVRequest( const std::string & dn );
SRVRequest( const std::string & dn, const string & service, const string & protocol );
virtual void submit();
struct SRV : SGReferenced {
int priority;
int weight;
int port;
std::string target;
};
typedef SGSharedPtr<SRV> SRV_ptr;
typedef std::vector<SRV_ptr> SRV_list;
SRV_list entries;
private:
std::string _service;
std::string _protocol;
};
class TXTRequest : public Request
{
public:
TXTRequest( const std::string & dn );
virtual void submit();
typedef std::vector<string> TXT_list;
typedef std::map<std::string,std::string> TXT_Attribute_map;
TXT_list entries;
TXT_Attribute_map attributes;
};
class Client
{
@@ -99,7 +132,6 @@ public:
// void cancelRequest(const Request_ptr& r, std::string reason = std::string());
private:
class ClientPrivate;
std::auto_ptr<ClientPrivate> d;
};

View File

@@ -224,8 +224,7 @@ void Client::makeRequest(const Request_ptr& r)
r->_client = this;
ClientPrivate::RequestCurlMap::iterator rit = d->requests.find(r);
assert(rit == d->requests.end());
assert(d->requests.find(r) == d->requests.end());
CURL* curlRequest = curl_easy_init();
curl_easy_setopt(curlRequest, CURLOPT_URL, r->url().c_str());

View File

@@ -68,7 +68,7 @@ namespace simgear
}
protected:
HTTPDirectory* _directory;
size_t _contentSize;
size_t _contentSize = 0;
};
typedef SGSharedPtr<HTTPRepoGetRequest> RepoRequestPtr;
@@ -756,7 +756,12 @@ size_t HTTPRepository::bytesToDownload() const
}
for (r = _d->activeRequests.begin(); r != _d->activeRequests.end(); ++r) {
result += (*r)->contentSize() - (*r)->responseBytesReceived();
if ((*r)->contentSize() > 0) {
// Content size for root dirindex of a repository is zero,
// and returing a negative value breaks everyting, so just ignore
// it
result += (*r)->contentSize() - (*r)->responseBytesReceived();
}
}
return result;
@@ -1239,7 +1244,7 @@ HTTPRepository::failure() const
void HTTPRepoPrivate::failedToGetRootIndex(HTTPRepository::ResultCode st)
{
SG_LOG(SG_TERRASYNC, SG_WARN, "Failed to get root of repo:" << baseUrl);
SG_LOG(SG_TERRASYNC, SG_WARN, "Failed to get root of repo:" << baseUrl << " " << st);
status = st;
}
@@ -1288,7 +1293,6 @@ HTTPRepository::failure() const
// maybe there was nothing to do
if (activeRequests.empty()) {
status = HTTPRepository::REPO_NO_ERROR;
isUpdating = false;
}
}

View File

@@ -32,6 +32,7 @@ set(HEADERS
sg_geodesy.hxx
sg_types.hxx
sg_random.h
simd.hxx
)
set(SOURCES

View File

@@ -153,17 +153,7 @@ public:
/// Use with care: allways code that you do not need to use that!
static bool isNaN(const T& v)
{
#ifdef HAVE_STD_ISNAN
return std::isnan(v);
#elif defined HAVE_ISNAN
return (isnan(v) != 0);
#else
// Use that every compare involving a NaN returns false
// But be careful, some usual compiler switches like for example
// -fast-math from gcc might optimize that expression to v != v which
// behaves exactly like the opposite ...
return !(v == v);
#endif
}
};

868
simgear/math/simd.hxx Normal file
View File

@@ -0,0 +1,868 @@
// Copyright (C) 2016 Erik Hofman - erik@ehofman.com
//
// 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 __SIMD_H__
#define __SIMD_H__ 1
#include <cstring>
# ifdef __SSE__
# include <xmmintrin.h>
# endif
template<typename T>
class simd4_t
{
public:
~simd4_t() {}
};
template<>
class simd4_t<float>
{
private:
typedef float __vec4_t[4];
# ifdef __SSE__
union {
__m128 v4;
__vec4_t vec;
};
# else
__vec4_t vec;
# endif
public:
simd4_t() {}
simd4_t(float f)
{
vec[0] = vec[1] = vec[2] = vec[3] = f;
}
simd4_t(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(float[4]));
}
simd4_t(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(float[4]));
#endif
}
inline float (&ptr(void))[4] {
return vec;
}
inline const float (&ptr(void) const)[4] {
return vec;
}
inline simd4_t& operator=(float f)
{
vec[0] = vec[1] = vec[2] = vec[3] = f;
return *this;
}
inline simd4_t& operator=(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(float[4]));
return *this;
}
inline simd4_t& operator=(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(float[4]));
#endif
return *this;
}
inline simd4_t operator+(float f)
{
simd4_t r(*this);
r += f;
return r;
}
inline simd4_t operator+(const __vec4_t v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator+(const simd4_t& v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator-()
{
simd4_t r(0.0f);
r -= vec;
return r;
}
inline simd4_t operator-(float f)
{
simd4_t r(*this);
r -= f;
return r;
}
inline simd4_t operator-(const __vec4_t v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator-(simd4_t& v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator*(float f)
{
simd4_t r(*this);
r *= f;
return r;
}
inline simd4_t operator*(const __vec4_t v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator*(simd4_t& v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator/(float f)
{
simd4_t r(*this);
r /= f;
return r;
}
inline simd4_t operator/(const __vec4_t v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t operator/(simd4_t& v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t& operator+=(float f)
{
# ifdef __SSE__
v4 += f;
# else
vec[0] += f;
vec[1] += f;
vec[2] += f;
vec[3] += f;
# endif
return *this;
}
inline simd4_t& operator+=(const __vec4_t v)
{
simd4_t r(v);
*this += r;
return *this;
}
inline simd4_t& operator+=(const simd4_t& v)
{
# ifdef __SSE__
v4 += v.v4;
# else
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
vec[3] += v[3];
#endif
return *this;
}
inline simd4_t& operator-=(float f)
{
# ifdef __SSE__
v4 -= f;
# else
vec[0] -= f;
vec[1] -= f;
vec[2] -= f;
vec[3] -= f;
# endif
return *this;
}
inline simd4_t& operator-=(const __vec4_t v)
{
simd4_t r(v);
*this -= r;
return *this;
}
inline simd4_t& operator-=(const simd4_t& v)
{
# ifdef __SSE__
v4 -= v.v4;
# else
vec[0] -= v[0];
vec[1] -= v[1];
vec[2] -= v[2];
vec[3] -= v[3];
#endif
return *this;
}
inline simd4_t& operator *=(float f)
{
# ifdef __SSE__
v4 *= f;
# else
vec[0] *= f;
vec[1] *= f;
vec[2] *= f;
vec[3] *= f;
# endif
return *this;
}
inline simd4_t& operator*=(const __vec4_t v)
{
simd4_t r(v);
*this *= r;
return *this;
}
inline simd4_t& operator*=(const simd4_t& v)
{
# ifdef __SSE__
v4 *= v.v4;
# else
vec[0] *= v[0];
vec[1] *= v[1];
vec[2] *= v[2];
vec[3] *= v[3];
#endif
return *this;
}
inline simd4_t& operator/=(float f)
{
# ifdef __SSE__
v4 /= f;
# else
vec[0] /= f;
vec[1] /= f;
vec[2] /= f;
vec[3] /= f;
#endif
return *this;
}
inline simd4_t& operator/=(const __vec4_t v)
{
simd4_t r(v);
*this /= r;
return *this;
}
inline simd4_t& operator/=(const simd4_t& v)
{
# ifdef __SSE__
v4 /= v.v4;
# else
vec[0] /= v[0];
vec[1] /= v[1];
vec[2] /= v[2];
vec[3] /= v[3];
#endif
return *this;
}
inline operator const float*() const {
return vec;
}
inline operator float*() {
return vec;
}
};
template<>
class simd4_t<double>
{
private:
typedef double __vec4_t[4];
# ifdef __SSE__
union {
__m128d v4;
__vec4_t vec;
};
# else
__vec4_t vec;
# endif
public:
simd4_t() {}
simd4_t(double d)
{
vec[0] = vec[1] = vec[2] = vec[3] = d;
}
simd4_t(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(double[4]));
}
simd4_t(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(double[4]));
#endif
}
inline double (&ptr(void))[4] {
return vec;
}
inline const double (&ptr(void) const)[4] {
return vec;
}
inline simd4_t& operator=(double d)
{
vec[0] = vec[1] = vec[2] = vec[3] = d;
return *this;
}
inline simd4_t& operator=(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(double[4]));
return *this;
}
inline simd4_t& operator=(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(double[4]));
#endif
return *this;
}
inline simd4_t operator+(double d)
{
simd4_t r(*this);
r += d;
return r;
}
inline simd4_t operator+(const __vec4_t v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator+(const simd4_t& v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator-()
{
simd4_t r(0.0f);
r -= vec;
return r;
}
inline simd4_t operator-(double d)
{
simd4_t r(*this);
r -= d;
return r;
}
inline simd4_t operator-(const __vec4_t v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator-(simd4_t& v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator*(double d)
{
simd4_t r(*this);
r *= d;
return r;
}
inline simd4_t operator*(const __vec4_t v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator*(simd4_t& v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator/(double d)
{
simd4_t r(*this);
r /= d;
return r;
}
inline simd4_t operator/(const __vec4_t v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t operator/(simd4_t& v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t& operator+=(double d)
{
# ifdef __SSE__
v4 += d;
# else
vec[0] += d;
vec[1] += d;
vec[2] += d;
vec[3] += d;
# endif
return *this;
}
inline simd4_t& operator+=(const __vec4_t v)
{
simd4_t r(v);
*this += r;
return *this;
}
inline simd4_t& operator+=(const simd4_t& v)
{
# ifdef __SSE__
v4 += v.v4;
# else
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
vec[3] += v[3];
#endif
return *this;
}
inline simd4_t& operator-=(double d)
{
# ifdef __SSE__
v4 -= d;
# else
vec[0] -= d;
vec[1] -= d;
vec[2] -= d;
vec[3] -= d;
# endif
return *this;
}
inline simd4_t& operator-=(const __vec4_t v)
{
simd4_t r(v);
*this -= r;
return *this;
}
inline simd4_t& operator-=(const simd4_t& v)
{
# ifdef __SSE__
v4 -= v.v4;
# else
vec[0] -= v[0];
vec[1] -= v[1];
vec[2] -= v[2];
vec[3] -= v[3];
#endif
return *this;
}
inline simd4_t& operator *=(double d)
{
# ifdef __SSE__
v4 *= d;
# else
vec[0] *= d;
vec[1] *= d;
vec[2] *= d;
vec[3] *= d;
# endif
return *this;
}
inline simd4_t& operator*=(const __vec4_t v)
{
simd4_t r(v);
*this *= r;
return *this;
}
inline simd4_t& operator*=(const simd4_t& v)
{
# ifdef __SSE__
v4 *= v.v4;
# else
vec[0] *= v[0];
vec[1] *= v[1];
vec[2] *= v[2];
vec[3] *= v[3];
#endif
return *this;
}
inline simd4_t& operator/=(double d)
{
# ifdef __SSE__
v4 /= d;
# else
vec[0] /= d;
vec[1] /= d;
vec[2] /= d;
vec[3] /= d;
#endif
return *this;
}
inline simd4_t& operator/=(const __vec4_t v)
{
simd4_t r(v);
*this /= r;
return *this;
}
inline simd4_t& operator/=(const simd4_t& v)
{
# ifdef __SSE__
v4 /= v.v4;
# else
vec[0] /= v[0];
vec[1] /= v[1];
vec[2] /= v[2];
vec[3] /= v[3];
#endif
return *this;
}
inline operator const double*() const {
return vec;
}
inline operator double*() {
return vec;
}
};
template<>
class simd4_t<int>
{
private:
typedef int __vec4_t[4];
# ifdef __SSE__
union {
__m128i v4;
__vec4_t vec;
};
# else
__vec4_t vec;
# endif
public:
simd4_t() {}
simd4_t(int i)
{
vec[0] = vec[1] = vec[2] = vec[3] = i;
}
simd4_t(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(int[4]));
}
simd4_t(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(int[4]));
#endif
}
inline int (&ptr(void))[4] {
return vec;
}
inline const int (&ptr(void) const)[4] {
return vec;
}
inline simd4_t& operator=(int i)
{
vec[0] = vec[1] = vec[2] = vec[3] = i;
return *this;
}
inline simd4_t& operator=(const __vec4_t v)
{
std::memcpy(vec, v, sizeof(int[4]));
return *this;
}
inline simd4_t& operator=(const simd4_t& v)
{
# ifdef __SSE__
v4 = v.v4;
#else
std::memcpy(vec, v.vec, sizeof(int[4]));
#endif
return *this;
}
inline simd4_t operator+(int i)
{
simd4_t r(*this);
r += i;
return r;
}
inline simd4_t operator+(const __vec4_t v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator+(const simd4_t& v)
{
simd4_t r(*this);
r += v;
return r;
}
inline simd4_t operator-()
{
simd4_t r(0.0f);
r -= vec;
return r;
}
inline simd4_t operator-(int i)
{
simd4_t r(*this);
r -= i;
return r;
}
inline simd4_t operator-(const __vec4_t v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator-(simd4_t& v)
{
simd4_t r(*this);
r -= v;
return r;
}
inline simd4_t operator*(int i)
{
simd4_t r(*this);
r *= i;
return r;
}
inline simd4_t operator*(const __vec4_t v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator*(simd4_t& v)
{
simd4_t r(*this);
r *= v;
return r;
}
inline simd4_t operator/(int i)
{
simd4_t r(*this);
r /= i;
return r;
}
inline simd4_t operator/(const __vec4_t v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t operator/(simd4_t& v)
{
simd4_t r(*this);
r /= v;
return r;
}
inline simd4_t& operator+=(int i)
{
# ifdef __SSE__
v4 += i;
# else
vec[0] += i;
vec[1] += i;
vec[2] += i;
vec[3] += i;
# endif
return *this;
}
inline simd4_t& operator+=(const __vec4_t v)
{
simd4_t r(v);
*this += r;
return *this;
}
inline simd4_t& operator+=(const simd4_t& v)
{
# ifdef __SSE__
v4 += v.v4;
# else
vec[0] += v[0];
vec[1] += v[1];
vec[2] += v[2];
vec[3] += v[3];
#endif
return *this;
}
inline simd4_t& operator-=(int i)
{
# ifdef __SSE__
v4 -= i;
# else
vec[0] -= i;
vec[1] -= i;
vec[2] -= i;
vec[3] -= i;
# endif
return *this;
}
inline simd4_t& operator-=(const __vec4_t v)
{
simd4_t r(v);
*this -= r;
return *this;
}
inline simd4_t& operator-=(const simd4_t& v)
{
# ifdef __SSE__
v4 -= v.v4;
# else
vec[0] -= v[0];
vec[1] -= v[1];
vec[2] -= v[2];
vec[3] -= v[3];
#endif
return *this;
}
inline simd4_t& operator *=(int i)
{
# ifdef __SSE__
v4 *= i;
# else
vec[0] *= i;
vec[1] *= i;
vec[2] *= i;
vec[3] *= i;
# endif
return *this;
}
inline simd4_t& operator*=(const __vec4_t v)
{
simd4_t r(v);
*this *= r;
return *this;
}
inline simd4_t& operator*=(const simd4_t& v)
{
# ifdef __SSE__
v4 *= v.v4;
# else
vec[0] *= v[0];
vec[1] *= v[1];
vec[2] *= v[2];
vec[3] *= v[3];
#endif
return *this;
}
inline simd4_t& operator/=(int i)
{
# ifdef __SSE__
v4 /= i;
# else
vec[0] /= i;
vec[1] /= i;
vec[2] /= i;
vec[3] /= i;
#endif
return *this;
}
inline simd4_t& operator/=(const __vec4_t v)
{
simd4_t r(v);
*this /= r;
return *this;
}
inline simd4_t& operator/=(const simd4_t& v)
{
# ifdef __SSE__
v4 /= v.v4;
# else
vec[0] /= v[0];
vec[1] /= v[1];
vec[2] /= v[2];
vec[3] /= v[3];
#endif
return *this;
}
inline operator const int*() const {
return vec;
}
inline operator int*() {
return vec;
}
};
#endif /* __SIMD_H__ */

View File

@@ -53,9 +53,9 @@ static const char sgDirPathSep = '/';
static const char sgDirPathSepBad = '\\';
#ifdef _WIN32
static const char sgSearchPathSep = ';';
const char SGPath::pathListSep = ';';
#else
static const char sgSearchPathSep = ':';
const char SGPath::pathListSep = ':';
#endif
#ifdef _WIN32
@@ -334,7 +334,7 @@ SGPath SGPath::operator/( const std::string& p ) const
#if defined(ENABLE_OLD_PATH_API)
//add a new path component to the existing path string
void SGPath::add( const string& p ) {
append( sgSearchPathSep+p );
append( SGPath::pathListSep+p );
}
#endif
@@ -644,7 +644,7 @@ string_list sgPathSplit( const string &search_path ) {
bool done = false;
while ( !done ) {
int index = tmp.find(sgSearchPathSep);
int index = tmp.find(SGPath::pathListSep);
if (index >= 0) {
result.push_back( tmp.substr(0, index) );
tmp = tmp.substr( index + 1 );

View File

@@ -52,6 +52,9 @@ class SGPath {
public:
// OS-dependent separator used in paths lists
static const char pathListSep;
struct Permissions
{
bool read : 1;

View File

@@ -25,6 +25,8 @@
#include <ctype.h> // isspace()
#include <cerrno>
#include <zlib.h>
#include "sgstream.hxx"
#include <simgear/misc/sg_path.hxx>
@@ -41,10 +43,11 @@ sg_gzifstream::sg_gzifstream()
//
// Open a possibly gzipped file for reading.
//
sg_gzifstream::sg_gzifstream( const SGPath& name, ios_openmode io_mode )
sg_gzifstream::sg_gzifstream( const SGPath& name, ios_openmode io_mode,
bool use_exact_name )
: istream(&gzbuf)
{
this->open( name, io_mode );
this->open( name, io_mode, use_exact_name );
}
//-----------------------------------------------------------------------------
@@ -60,17 +63,20 @@ sg_gzifstream::sg_gzifstream( int fd, ios_openmode io_mode )
//-----------------------------------------------------------------------------
//
// Open a possibly gzipped file for reading.
// If the initial open fails and the filename has a ".gz" extension then
// remove the extension and try again.
// If the initial open fails and the filename doesn't have a ".gz" extension
// then append ".gz" and try again.
// If 'use_exact_name' is true, just try to open the indicated file, nothing
// else. Otherwise:
// - if the initial open fails and the filename has a ".gz" extension, then
// remove it and try again;
// - if the initial open fails and the filename doesn't have a ".gz"
// extension, then append ".gz" and try again.
//
void
sg_gzifstream::open( const SGPath& name, ios_openmode io_mode )
sg_gzifstream::open( const SGPath& name, ios_openmode io_mode,
bool use_exact_name )
{
std::string s = name.utf8Str();
gzbuf.open( s.c_str(), io_mode );
if ( ! gzbuf.is_open() )
if ( ! (gzbuf.is_open() || use_exact_name) )
{
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
{
@@ -95,6 +101,11 @@ sg_gzifstream::attach( int fd, ios_openmode io_mode )
gzbuf.attach( fd, io_mode );
}
z_off_t
sg_gzifstream::approxOffset() {
return gzbuf.approxOffset();
}
//
// Manipulators
//

View File

@@ -39,6 +39,7 @@
#include <string>
#include <zlib.h>
#include <simgear/misc/zfstream.hxx>
class SGPath;
@@ -53,13 +54,15 @@ public:
sg_gzifstream();
/**
* Constructor that attempt to open a file with and without
* ".gz" extension.
* Constructor that attempts to open a file.
* @param name name of file
* @param io_mode file open mode(s) "or'd" together
* @param use_exact_name if false, try to add or remove a ".gz" extension
* in case the indicated file can't be opened
*/
sg_gzifstream( const SGPath& name,
ios_openmode io_mode = ios_in | ios_binary );
ios_openmode io_mode = ios_in | ios_binary,
bool use_exact_name = false );
/**
* Constructor that attaches itself to an existing file descriptor.
@@ -69,12 +72,15 @@ public:
sg_gzifstream( int fd, ios_openmode io_mode = ios_in|ios_binary );
/**
* Attempt to open a file with and without ".gz" extension.
* Attempt to open a file.
* @param name name of file
* @param io_mode file open mode(s) "or'd" together
* @param use_exact_name if false, try to add or remove a ".gz" extension
* in case the indicated file can't be opened
*/
void open( const SGPath& name,
ios_openmode io_mode = ios_in|ios_binary );
ios_openmode io_mode = ios_in|ios_binary,
bool use_exact_name = false );
/**
* Attach to an existing file descriptor.
@@ -91,6 +97,15 @@ public:
/** @return true if the file is successfully opened, false otherwise. */
bool is_open() { return gzbuf.is_open(); }
/**
* @return the current offset in the file being read or written.
* The offset corresponds to compressed data if the file is compressed,
* and is influenced by buffering performed in zlib, hence the "approx"
* qualifier. It should be suitable for progress indicators and such,
* though.
*/
z_off_t approxOffset();
private:
// Not defined!
sg_gzifstream( const sg_gzifstream& );

View File

@@ -27,6 +27,10 @@
#include <string.h> // strerror_r() and strerror_s()
#include <errno.h>
#if defined(HAVE_CPP11_CODECVT)
#include <codecvt> // new in C++11
#endif
#include "strutils.hxx"
#include <simgear/debug/logstream.hxx>
@@ -400,7 +404,11 @@ std::wstring convertUtf8ToWString(const std::string& a)
{
#ifdef SG_WINDOWS
return convertMultiByteToWString(CP_UTF8, a);
#elif defined(HAVE_CPP11_CODECVT)
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> ucs2conv;
return ucs2conv.from_bytes(a);
#else
return std::wstring();
#endif
}
@@ -408,8 +416,11 @@ std::string convertWStringToUtf8(const std::wstring& w)
{
#ifdef SG_WINDOWS
return convertWStringToMultiByte(CP_UTF8, w);
#elif defined(HAVE_CPP11_CODECVT)
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> ucs2conv;
return ucs2conv.to_bytes(w);
#else
return std::string();
#endif
}

View File

@@ -40,20 +40,39 @@ BOOST_AUTO_TEST_CASE( strutils_functions )
BOOST_CHECK_EQUAL(strutils::to_int("0000000"), 0);
BOOST_CHECK_EQUAL(strutils::to_int("-10000"), -10000);
string_list la = strutils::split("zero one two three four five");
BOOST_CHECK_EQUAL(la[2], "two");
BOOST_CHECK_EQUAL(la[5], "five");
BOOST_CHECK_EQUAL(la.size(), 6);
string_list l = strutils::split("zero one two three four five");
BOOST_CHECK_EQUAL(l[2], "two");
BOOST_CHECK_EQUAL(l[5], "five");
BOOST_CHECK_EQUAL(l.size(), 6);
string_list lb = strutils::split("alpha:beta:gamma:delta", ":", 2);
BOOST_CHECK_EQUAL(lb.size(), 3);
BOOST_CHECK_EQUAL(lb[0], "alpha");
BOOST_CHECK_EQUAL(lb[1], "beta");
BOOST_CHECK_EQUAL(lb[2], "gamma:delta");
std::string j = strutils::join(la, "&");
std::string j = strutils::join(l, "&");
BOOST_CHECK_EQUAL(j, "zero&one&two&three&four&five");
l = strutils::split("alpha:beta:gamma:delta", ":", 2);
BOOST_CHECK_EQUAL(l.size(), 3);
BOOST_CHECK_EQUAL(l[0], "alpha");
BOOST_CHECK_EQUAL(l[1], "beta");
BOOST_CHECK_EQUAL(l[2], "gamma:delta");
l = strutils::split("", ",");
BOOST_CHECK_EQUAL(l.size(), 1);
BOOST_CHECK_EQUAL(l[0], "");
l = strutils::split(",", ",");
BOOST_CHECK_EQUAL(l.size(), 2);
BOOST_CHECK_EQUAL(l[0], "");
BOOST_CHECK_EQUAL(l[1], "");
l = strutils::split(",,", ",");
BOOST_CHECK_EQUAL(l.size(), 3);
BOOST_CHECK_EQUAL(l[0], "");
BOOST_CHECK_EQUAL(l[1], "");
BOOST_CHECK_EQUAL(l[2], "");
l = strutils::split(" ", ",");
BOOST_CHECK_EQUAL(l.size(), 1);
BOOST_CHECK_EQUAL(l[0], " ");
BOOST_CHECK_EQUAL(strutils::unescape("\\ \\n\\t\\x41\\117a"), " \n\tAOa");
}

View File

@@ -35,4 +35,9 @@
exit(1); \
}
#define SG_TEST_FAIL(msg) \
std::cerr << "failure:" << msg; \
exit(1);
#endif // of SG_MISC_TEST_MACROS_HXX

View File

@@ -30,7 +30,10 @@
#include <fcntl.h>
#include <simgear/misc/strutils.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <zlib.h>
#include "zfstream.hxx"
//
@@ -180,6 +183,27 @@ gzfilebuf::setcompressionstrategy( int comp_strategy )
return gzsetparams(file, -2, comp_strategy);
}
z_off_t
gzfilebuf::approxOffset() {
z_off_t res = gzoffset(file);
if (res == -1) {
int errnum;
std::string errMsg = "gzoffset() error: ";
const char *gzMsg = gzerror(file, &errnum);
if (errnum == Z_ERRNO) {
errMsg += simgear::strutils::error_string(errno);
} else {
errMsg += std::string(gzMsg);
}
SG_LOG( SG_GENERAL, SG_ALERT, errMsg );
throw sg_io_exception(errMsg);
}
return res;
}
std::streampos
gzfilebuf::seekoff( std::streamoff, ios_seekdir, ios_openmode )

View File

@@ -89,6 +89,15 @@ public:
/** @return true if open, false otherwise */
bool is_open() const { return (file != NULL); }
/**
* @return the current offset in the file being read or written.
* The offset corresponds to compressed data if the file is compressed,
* and is influenced by buffering performed in zlib, hence the "approx"
* qualifier. It should be suitable for progress indicators and such,
* though.
*/
z_off_t approxOffset();
/** @return stream position */
virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, ios_openmode which );

View File

@@ -1,10 +1,9 @@
#ifndef _NAREF_H
#define _NAREF_H
#if (defined(__x86_64) && defined(__linux__)) || defined(__sparcv9) || \
defined(__powerpc64__)
#if (defined(__x86_64) && defined(__linux__))
/* NASAL_NAN64 mode requires 64 bit pointers that only use the
* lower 48 bits; Win64 and Irix should work with this too, but
* lower 48 bits; x86 Win64 and Irix should work with this too, but
* have not been tested */
# define NASAL_NAN64
#elif defined(__BYTE_ORDER__)

View File

@@ -150,6 +150,48 @@ int parseTest()
COMPARE(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
COMPARE(p2->description(), "A plane made by Cessna");
pkg::Package::ThumbnailVec thumbs = p2->thumbnailsForVariant(0);
COMPARE(thumbs.size(), 3);
auto index = std::find_if(thumbs.begin(), thumbs.end(), [](const pkg::Package::Thumbnail& t)
{ return (t.type == pkg::Package::Thumbnail::Type::EXTERIOR); });
VERIFY(index != thumbs.end());
COMPARE(index->path, "thumb-exterior.png");
COMPARE(index->url, "http://foo.bar.com/thumb-exterior.png");
VERIFY(index->type == pkg::Package::Thumbnail::Type::EXTERIOR);
index = std::find_if(thumbs.begin(), thumbs.end(), [](const pkg::Package::Thumbnail& t)
{ return (t.type == pkg::Package::Thumbnail::Type::PANEL); });
VERIFY(index != thumbs.end());
COMPARE(index->path, "thumb-panel.png");
COMPARE(index->url, "http://foo.bar.com/thumb-panel.png");
VERIFY(index->type == pkg::Package::Thumbnail::Type::PANEL);
// test variants
try {
p2->indexOfVariant("fofofo");
SG_TEST_FAIL("lookup of non-existant variant did not throw");
} catch (sg_exception& e) {
// expected
}
unsigned int skisVariantFull = p2->indexOfVariant("org.flightgear.test.catalog1.c172p-skis");
VERIFY(skisVariantFull > 0);
unsigned int skisVariant = p2->indexOfVariant("c172p-skis");
VERIFY(skisVariant > 0);
COMPARE(skisVariant, skisVariantFull);
pkg::Package::ThumbnailVec thumbs2 = p2->thumbnailsForVariant(skisVariant);
COMPARE(thumbs2.size(), 2);
index = std::find_if(thumbs2.begin(), thumbs2.end(), [](const pkg::Package::Thumbnail& t)
{ return (t.type == pkg::Package::Thumbnail::Type::EXTERIOR); });
VERIFY(index != thumbs2.end());
COMPARE(index->path, "thumb-exterior-skis.png");
COMPARE(index->url, "http://foo.bar.com/thumb-exterior-skis.png");
VERIFY(index->type == pkg::Package::Thumbnail::Type::EXTERIOR);
// test filtering / searching too
@@ -454,7 +496,7 @@ int main(int argc, char* argv[])
parseTest();
testInstallPackage(&cl);
testUninstall(&cl);
testRemoveCatalog(&cl);

View File

@@ -29,9 +29,11 @@ namespace pkg
class Install;
class Catalog;
class Package;
typedef SGSharedPtr<Catalog> CatalogRef;
typedef SGSharedPtr<Install> InstallRef;
typedef SGSharedPtr<Package> PackageRef;
/**
* package delegate is the mechanism to discover progress / completion /
@@ -68,6 +70,8 @@ public:
virtual void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) = 0;
virtual void finishInstall(InstallRef aInstall, StatusCode aReason) = 0;
virtual void finishUninstall(const PackageRef& aPackage) {};
/**
* Notification when catalogs/packages are added or removed
*/

View File

@@ -21,7 +21,7 @@
#include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <simgear/debug/logstream.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/package/Catalog.hxx>
@@ -29,7 +29,7 @@
#include <simgear/package/Root.hxx>
namespace simgear {
namespace pkg {
Package::Package(const SGPropertyNode* aProps, CatalogRef aCatalog) :
@@ -103,7 +103,7 @@ bool Package::matches(const SGPropertyNode* aFilter) const
else
SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term:" << filter_name);
} // of filter props iteration
return true;
}
@@ -127,7 +127,7 @@ InstallRef Package::install()
if (ins) {
return ins;
}
// start a new install
ins = new Install(this, pathOnDisk());
m_catalog->root()->scheduleToUpdate(ins);
@@ -190,10 +190,10 @@ unsigned int Package::revision() const
if (!m_props) {
return 0;
}
return m_props->getIntValue("revision");
}
std::string Package::name() const
{
return m_props->getStringValue("name");
@@ -203,7 +203,7 @@ size_t Package::fileSizeBytes() const
{
return m_props->getIntValue("file-size-bytes");
}
std::string Package::description() const
{
return getLocalisedProp("description");
@@ -213,7 +213,7 @@ string_set Package::tags() const
{
return m_tags;
}
SGPropertyNode* Package::properties() const
{
return m_props.ptr();
@@ -225,7 +225,7 @@ string_list Package::thumbnailUrls() const
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
r.push_back(dl->getStringValue());
}
@@ -238,20 +238,20 @@ string_list Package::thumbnails() const
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail-path")) {
r.push_back(dl->getStringValue());
}
return r;
}
string_list Package::downloadUrls() const
{
string_list r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
r.push_back(dl->getStringValue());
}
@@ -272,41 +272,41 @@ std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char*
return localeRoot->getStringValue(aName);
}
}
return aRoot->getStringValue(aName);
}
PackageList Package::dependencies() const
{
PackageList result;
BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
std::string depName = dep->getStringValue("id");
unsigned int rev = dep->getIntValue("revision", 0);
// prefer local hangar package if possible, in case someone does something
// silly with naming. Of course flightgear's aircraft search doesn't know
// about hangars, so names still need to be unique.
PackageRef depPkg = m_catalog->getPackageById(depName);
if (!depPkg) {
if (!depPkg) {
Root* rt = m_catalog->root();
depPkg = rt->getPackageById(depName);
if (!depPkg) {
throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
}
}
if (depPkg->revision() < rev) {
throw sg_range_exception("Couldn't find suitable revision of " + depName);
}
// forbid recursive dependency graphs, we don't need that level
// of complexity for aircraft resources
assert(depPkg->dependencies() == PackageList());
result.push_back(depPkg);
}
return result;
}
@@ -338,6 +338,36 @@ std::string Package::nameForVariant(const std::string& vid) const
throw sg_exception("Unknow variant +" + vid + " in package " + id());
}
unsigned int Package::indexOfVariant(const std::string& vid) const
{
// accept fully-qualified IDs here
std::string actualId = vid;
size_t lastDot = vid.rfind('.');
if (lastDot != std::string::npos) {
std::string catalogId = vid.substr(0, lastDot);
if (catalogId != catalog()->id()) {
throw sg_exception("Bad fully-qualified ID:" + vid + ", package mismatch" );
}
actualId = vid.substr(lastDot + 1);
}
if (actualId == id()) {
return 0;
}
unsigned int result = 1;
for (SGPropertyNode* var : m_props->getChildren("variant")) {
if (var->getStringValue("id") == actualId) {
return result;
}
result++;
}
throw sg_exception("Unknow variant " + vid + " in package " + id());
}
std::string Package::nameForVariant(const unsigned int vIndex) const
{
if (vIndex == 0)
@@ -351,6 +381,48 @@ std::string Package::nameForVariant(const unsigned int vIndex) const
throw sg_exception("Unknow variant in package " + id());
}
Package::ThumbnailVec Package::thumbnailsForVariant(unsigned int vIndex) const
{
if (vIndex == 0) {
return thumbnailsFromProps(m_props);
}
SGPropertyNode_ptr var = m_props->getChild("variant", vIndex - 1);
if (!var) {
throw sg_exception("Unknow variant in package " + id());
}
return thumbnailsFromProps(var);
}
Package::Thumbnail::Type thumbnailTypeFromString(const std::string& s)
{
if (s == "exterior") return Package::Thumbnail::Type::EXTERIOR;
if (s == "interior") return Package::Thumbnail::Type::INTERIOR;
if (s == "panel") return Package::Thumbnail::Type::PANEL;
return Package::Thumbnail::Type::UNKNOWN;
}
Package::Thumbnail::Thumbnail(const std::string& aUrl, const std::string& aPath, Type aType) :
url(aUrl),
path(aPath),
type(aType)
{
}
Package::ThumbnailVec Package::thumbnailsFromProps(const SGPropertyNode_ptr& ptr) const
{
ThumbnailVec result;
for (auto thumbNode : ptr->getChildren("thumbnail")) {
Thumbnail t(thumbNode->getStringValue("url"),
thumbNode->getStringValue("path"),
thumbnailTypeFromString(thumbNode->getStringValue("type")));
result.push_back(t);
}
return result;
}
} // of namespace pkg

View File

@@ -80,7 +80,12 @@ public:
* Fully-qualified ID, including our catalog'd ID
*/
std::string qualifiedVariantId(const unsigned int variantIndex) const;
/**
*
*/
unsigned int indexOfVariant(const std::string& vid) const;
/**
* human-readable name - note this is probably not localised,
* although this is not ruled out for the future.
@@ -133,6 +138,35 @@ public:
* thumbnail file paths within the package on disk
*/
string_list thumbnails() const;
/**
* information about a thumbnail
*/
struct Thumbnail {
enum class Type
{
UNKNOWN,
PANEL,
INTERIOR,
EXTERIOR
// NIGHT / GROUND as modifiers? does this add any
// actual value for GUIs?
};
Thumbnail(const std::string& url, const std::string& path, Type ty = Type::UNKNOWN);
std::string url;
std::string path;
Type type = Type::UNKNOWN;
};
typedef std::vector<Thumbnail> ThumbnailVec;
/**
* retrieve all the thumbnails for a variant
*/
ThumbnailVec thumbnailsForVariant(unsigned int vIndex) const;
/**
* Packages we depend upon.
@@ -159,7 +193,9 @@ private:
void updateFromProps(const SGPropertyNode* aProps);
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
ThumbnailVec thumbnailsFromProps(const SGPropertyNode_ptr& ptr) const;
SGPropertyNode_ptr m_props;
std::string m_id;
string_set m_tags;

View File

@@ -153,6 +153,12 @@ public:
}
}
void fireFinishUninstall(PackageRef pkg)
{
std::for_each(delegates.begin(), delegates.end(),
[pkg](Delegate* d) {d->finishUninstall(pkg);});
}
DelegateVec delegates;
SGPath path;
@@ -652,6 +658,7 @@ void Root::unregisterInstall(InstallRef ins)
}
d->m_installs.erase(ins->package());
d->fireFinishUninstall(ins->package());
}
} // of namespace pkg

View File

@@ -48,6 +48,23 @@
<revision>10</revision>
</depends>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior.png</path>
<url>http://foo.bar.com/thumb-exterior.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
<thumbnail>
<path>thumb-something.png</path>
<url>http://foo.bar.com/thumb-something.png</url>
</thumbnail>
<variant>
<id>c172p-2d-panel</id>
<name>C172 with 2d panel only</name>
@@ -56,11 +73,35 @@
<variant>
<id>c172p-floats</id>
<name>C172 with floats</name>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior-floats.png</path>
<url>http://foo.bar.com/thumb-exterior-floats.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
</variant>
<variant>
<id>c172p-skis</id>
<name>C172 with skis</name>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior-skis.png</path>
<url>http://foo.bar.com/thumb-exterior-skis.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
</variant>
<md5>ec0e2ffdf98d6a5c05c77445e5447ff5</md5>
@@ -99,6 +140,18 @@
<md5>a94ca5704f305b90767f40617d194ed6</md5>
<url>http://localhost:2000/catalogTest1/b737.tar.gz</url>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior.png</path>
<url>http://foo.bar.com/thumb-exterior.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
</package>

View File

@@ -48,6 +48,23 @@
<revision>10</revision>
</depends>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior.png</path>
<url>http://foo.bar.com/thumb-exterior.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
<thumbnail>
<path>thumb-something.png</path>
<url>http://foo.bar.com/thumb-something.png</url>
</thumbnail>
<variant>
<id>c172p-2d-panel</id>
<name>C172 with 2d panel only</name>
@@ -56,11 +73,35 @@
<variant>
<id>c172p-floats</id>
<name>C172 with floats</name>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior-floats.png</path>
<url>http://foo.bar.com/thumb-exterior-floats.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
</variant>
<variant>
<id>c172p-skis</id>
<name>C172 with skis</name>
<thumbnail>
<type>exterior</type>
<path>thumb-exterior-skis.png</path>
<url>http://foo.bar.com/thumb-exterior-skis.png</url>
</thumbnail>
<thumbnail>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</thumbnail>
</variant>
<md5>ec0e2ffdf98d6a5c05c77445e5447ff5</md5>

View File

@@ -38,12 +38,6 @@ using std::cerr;
# include "PropertyInterpolationMgr.hxx"
# include "vectorPropTemplates.hxx"
# if ( _MSC_VER == 1200 )
// MSVC 6 is buggy, and needs something strange here
using std::vector<SGPropertyNode_ptr>;
using std::vector<SGPropertyChangeListener *>;
using std::vector<SGPropertyNode *>;
# endif
#endif
using std::endl;

View File

@@ -136,7 +136,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
const SGPropertyNode *props,
SGPropertyNode *prop_root)
{
float default_object_range = prop_root->getFloatValue("/sim/rendering/static-lod/rough", SG_OBJECT_RANGE);
float default_object_range = prop_root->getFloatValue("/sim/rendering/static-lod/rough", SG_OBJECT_RANGE_ROUGH);
std::vector<bool> dds;
std::vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
for (unsigned int i = 0; i < textures.size(); i++)

View File

@@ -39,6 +39,10 @@ CheckSceneryVisitor::CheckSceneryVisitor(osgDB::DatabasePager* dbp, const osg::V
setFrameStamp(framestamp);
}
CheckSceneryVisitor::~CheckSceneryVisitor()
{
}
void CheckSceneryVisitor::apply(osg::Node& node)
{
traverse(node);

View File

@@ -37,6 +37,7 @@ class CheckSceneryVisitor : public osg::NodeVisitor
{
public:
CheckSceneryVisitor(osgDB::DatabasePager* dbp, const osg::Vec3 &position, double range, osg::FrameStamp* framestamp);
~CheckSceneryVisitor();
virtual void apply(osg::Node& node);
virtual void apply(osg::ProxyNode& node);

View File

@@ -1,6 +1,6 @@
// ModelRegistry.hxx -- interface to the OSG model registry
//
// Copyright (C) 2005-2007 Mathias Froehlich
// Copyright (C) 2005-2007 Mathias Froehlich
// Copyright (C) 2007 Tim Moore <timoore@redhat.com>
//
// This program is free software; you can redistribute it and/or
@@ -44,6 +44,8 @@
#include <osgDB/SharedStateManager>
#include <osgUtil/Optimizer>
#include <simgear/sg_inlines.h>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/SGStateAttributeVisitor.hxx>
#include <simgear/scene/util/SGTextureStateAttributeVisitor.hxx>
@@ -155,7 +157,7 @@ public:
Image* image = texture->getImage(0);
if (!image)
return;
texture->setDataVariance(Object::STATIC);
}
@@ -201,7 +203,7 @@ ModelRegistry::readImage(const string& fileName,
SG_LOG(SG_IO, SG_WARN, "Image loading failed:" << res.message());
return res;
}
if (res.loadedFromCache())
SG_LOG(SG_IO, SG_BULK, "Returning cached image \""
<< res.getImage()->getFileName() << "\"");
@@ -224,7 +226,7 @@ ModelRegistry::readImage(const string& fileName,
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
// GL_EXT_texture_sRGB
// patented, no way to decompress these
#ifndef GL_EXT_texture_sRGB
@@ -237,7 +239,7 @@ ModelRegistry::readImage(const string& fileName,
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
// GL_TDFX_texture_compression_FXT1
// can decompress these in software but
// no code present in simgear.
@@ -247,7 +249,7 @@ ModelRegistry::readImage(const string& fileName,
#endif
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
// GL_EXT_texture_compression_rgtc
// can decompress these in software but
// no code present in simgear.
@@ -475,7 +477,7 @@ struct ACProcessPolicy {
osg::Group* root = new Group;
MatrixTransform* transform = new MatrixTransform;
root->addChild(transform);
transform->setDataVariance(Object::STATIC);
transform->setMatrix(m);
transform->addChild(node);
@@ -489,7 +491,27 @@ typedef ModelRegistryCallback<ACProcessPolicy, DefaultCachePolicy,
OSGSubstitutePolicy, BuildLeafBVHPolicy>
ACCallback;
struct OBJProcessPolicy {
OBJProcessPolicy(const string& extension) {}
Node* process(Node* node, const string& filename,
const Options* opt)
{
SG_UNUSED(filename);
SG_UNUSED(opt);
return node;
}
};
typedef ModelRegistryCallback<OBJProcessPolicy,
DefaultCachePolicy,
ACOptimizePolicy,
OSGSubstitutePolicy, BuildLeafBVHPolicy>
OBJCallback;
namespace
{
ModelRegistryCallbackProxy<ACCallback> g_acRegister("ac");
ModelRegistryCallbackProxy<OBJCallback> g_objRegister("obj");
}

View File

@@ -68,7 +68,7 @@ void SGModelLib::setPanelFunc(panel_func pf)
static_panelFunc = pf;
}
std::string SGModelLib::findDataFile(const std::string& file,
std::string SGModelLib::findDataFile(const std::string& file,
const osgDB::Options* opts,
SGPath currentPath)
{
@@ -97,8 +97,10 @@ osg::Node* loadFile(const string& path, SGReaderWriterOptions* options)
{
using namespace osg;
using namespace osgDB;
if (boost::iends_with(path, ".ac"))
if (boost::iends_with(path, ".ac") || boost::iends_with(path, ".obj")) {
options->setInstantiateEffects(true);
}
ref_ptr<Node> model = readRefNodeFile(path, options);
if (!model)
return 0;
@@ -118,11 +120,11 @@ SGModelLib::loadModel(const string &path,
opt->getDatabasePathList().push_front( osgDB::getFilePath(path) );
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
if (load2DPanels) {
opt->setLoadPanel(static_panelFunc);
}
osg::Node *n = loadFile(path, opt.get());
if (n && n->getName().empty())
n->setName("Direct loaded model \"" + path + "\"");
@@ -145,8 +147,11 @@ SGModelLib::loadDeferredModel(const string &path, SGPropertyNode *prop_root,
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
opt->setLoadPanel(static_panelFunc);
if (SGPath(path).lower_extension() == "ac")
std::string lext = SGPath(path).lower_extension();
if ((lext == "ac") || (lext == "obj")) {
opt->setInstantiateEffects(true);
}
if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
opt->setObjectCacheHint(osgDB::Options::CACHE_ALL);
else
@@ -171,8 +176,12 @@ SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root,
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
opt->setLoadPanel(static_panelFunc);
if (SGPath(path).lower_extension() == "ac")
std::string lext = SGPath(path).lower_extension();
if ((lext == "ac") || (lext == "obj")) {
opt->setInstantiateEffects(true);
}
if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
opt->setObjectCacheHint(osgDB::Options::CACHE_ALL);
else

View File

@@ -81,7 +81,7 @@ static SGBucket bucketIndexFromFileName(const std::string& fileName)
ss >> index;
if (ss.fail())
return SGBucket();
return SGBucket(index);
}
@@ -93,7 +93,7 @@ struct ReaderWriterSTG::_ModelBin {
osg::ref_ptr<SGReaderWriterOptions> _options;
};
struct _ObjectStatic {
_ObjectStatic() : _agl(false), _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0), _range(SG_OBJECT_RANGE) { }
_ObjectStatic() : _agl(false), _proxy(false), _lon(0), _lat(0), _elev(0), _hdg(0), _pitch(0), _roll(0), _range(SG_OBJECT_RANGE_ROUGH) { }
std::string _errorLocation;
std::string _token;
std::string _name;
@@ -195,21 +195,24 @@ struct ReaderWriterSTG::_ModelBin {
signBuilder.addSign(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev), i->_hdg, i->_name, i->_size);
if (signBuilder.getSignsGroup())
group->addChild(signBuilder.getSignsGroup());
return group.release();
}
mt _seed;
std::list<_ObjectStatic> _objectStaticList;
std::list<_Sign> _signList;
/// The original options to use for this bunch of models
osg::ref_ptr<SGReaderWriterOptions> _options;
SGBucket _bucket;
};
_ModelBin() :
_object_range(SG_OBJECT_RANGE),
_object_range_bare(SG_OBJECT_RANGE_BARE),
_object_range_rough(SG_OBJECT_RANGE_ROUGH),
_object_range_detailed(SG_OBJECT_RANGE_DETAILED),
_building_mesh_enabled(false),
_foundBase(false)
{ }
@@ -222,14 +225,14 @@ struct ReaderWriterSTG::_ModelBin {
SGPath path = filePath;
path.append(".."); path.append(".."); path.append("..");
sharedOptions->getDatabasePathList().push_back(path.local8BitStr());
// ensure Models directory synced via TerraSync is searched before the copy in
// FG_ROOT, so that updated models can be used.
std::string terrasync_root = options->getPluginStringData("SimGear::TERRASYNC_ROOT");
if (!terrasync_root.empty()) {
sharedOptions->getDatabasePathList().push_back(terrasync_root);
}
std::string fg_root = options->getPluginStringData("SimGear::FG_ROOT");
sharedOptions->getDatabasePathList().push_back(fg_root);
@@ -268,21 +271,27 @@ struct ReaderWriterSTG::_ModelBin {
{
SGVec3d start = SGVec3d::fromGeod(SGGeod::fromGeodM(geod, 10000));
SGVec3d end = SGVec3d::fromGeod(SGGeod::fromGeodM(geod, -1000));
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector;
intersector = new osgUtil::LineSegmentIntersector(toOsg(start), toOsg(end));
osgUtil::IntersectionVisitor visitor(intersector.get());
group.accept(visitor);
if (!intersector->containsIntersections())
return 0;
SGVec3d cart = toSG(intersector->getFirstIntersection().getWorldIntersectPoint());
return SGGeod::fromCart(cart).getElevationM();
}
bool read(const std::string& absoluteFileName, const osgDB::Options* options)
{
// Determine object ranges. Mesh size of 2000mx2000m needs to be accounted for.
_object_range_bare = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_BARE").c_str());
_object_range_rough = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_ROUGH").c_str());
_object_range_detailed = 1414.0f + atof(options->getPluginStringData("SimGear::LOD_RANGE_DETAILED").c_str());
_building_mesh_enabled = (options->getPluginStringData("SimGear::RENDER_BUILDING_MESH") == "true");
if (absoluteFileName.empty())
return false;
@@ -291,7 +300,7 @@ struct ReaderWriterSTG::_ModelBin {
return false;
SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName);
std::string filePath = osgDB::getFilePath(absoluteFileName);
// Bucket provides a consistent seed
@@ -304,7 +313,7 @@ struct ReaderWriterSTG::_ModelBin {
bool onlyAirports = options->getPluginStringData("SimGear::FG_ONLY_AIRPORTS") == "ON";
// do only load terrain btg files
bool onlyTerrain = options->getPluginStringData("SimGear::FG_ONLY_TERRAIN") == "ON";
while (!stream.eof()) {
// read a line
std::string line;
@@ -314,30 +323,24 @@ struct ReaderWriterSTG::_ModelBin {
std::string::size_type hash_pos = line.find('#');
if (hash_pos != std::string::npos)
line.resize(hash_pos);
// and process further
std::stringstream in(line);
std::string token;
in >> token;
// No comment
if (token.empty())
continue;
// Then there is always a name
std::string name;
in >> name;
SGPath path = filePath;
path.append(name);
// Determine an appropriate range for the object, which has some randomness
double range = _object_range;
double lrand = mt_rand(&seed);
if (lrand < 0.1) range = range * 2.0;
else if (lrand < 0.4) range = range * 1.5;
if (token == "OBJECT_BASE") {
// Load only once (first found)
SG_LOG( SG_TERRAIN, SG_BULK, " " << token << " " << name );
@@ -350,7 +353,7 @@ struct ReaderWriterSTG::_ModelBin {
obj._options = staticOptions(filePath, options);
_objectList.push_back(obj);
}
} else if (token == "OBJECT") {
if (!onlyAirports || isAirportBtg(name)) {
_Object obj;
@@ -360,81 +363,109 @@ struct ReaderWriterSTG::_ModelBin {
obj._options = staticOptions(filePath, options);
_objectList.push_back(obj);
}
} else {
// Always OK to load
} else if (!onlyTerrain) {
// Load non-terrain objects
// Determine an appropriate range for the object, which has some randomness
double range = _object_range_rough;
double lrand = mt_rand(&seed);
if (lrand < 0.1) range = range * 2.0;
else if (lrand < 0.4) range = range * 1.5;
if (token == "OBJECT_STATIC" || token == "OBJECT_STATIC_AGL") {
if (!onlyTerrain) {
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = staticOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = (token == "OBJECT_STATIC_AGL");
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
obj._range = range;
obj._options = opt;
_objectStaticList.push_back(obj);
}
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = staticOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = (token == "OBJECT_STATIC_AGL");
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
obj._range = range;
obj._options = opt;
_objectStaticList.push_back(obj);
} else if (token == "OBJECT_SHARED" || token == "OBJECT_SHARED_AGL") {
if (!onlyTerrain) {
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = sharedOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = (token == "OBJECT_SHARED_AGL");
obj._proxy = false;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
obj._range = range;
obj._options = opt;
_objectStaticList.push_back(obj);
}
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = sharedOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = (token == "OBJECT_SHARED_AGL");
obj._proxy = false;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
obj._range = range;
obj._options = opt;
_objectStaticList.push_back(obj);
} else if (token == "OBJECT_SIGN" || token == "OBJECT_SIGN_AGL") {
if (!onlyTerrain) {
_Sign sign;
sign._token = token;
sign._name = name;
sign._agl = (token == "OBJECT_SIGN_AGL");
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
_signList.push_back(sign);
}
_Sign sign;
sign._token = token;
sign._name = name;
sign._agl = (token == "OBJECT_SIGN_AGL");
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
_signList.push_back(sign);
} else if (token == "OBJECT_BUILDING_MESH_ROUGH" || token == "OBJECT_BUILDING_MESH_DETAILED") {
// Only load if building mesh enabled to avoid impacting low-powered systems
if (_building_mesh_enabled) {
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = staticOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = false;
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
if (token == "OBJECT_BUILDING_MESH_DETAILED") {
// Apply a lower LOD range if this is a detailed building
range = _object_range_detailed;
double lrand = mt_rand(&seed);
if (lrand < 0.1) range = range * 2.0;
else if (lrand < 0.4) range = range * 1.5;
}
obj._range = range;
obj._options = opt;
_objectStaticList.push_back(obj);
}
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
<< ": Unknown token '" << token << "'" );
}
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
<< ": Unknown token '" << token << "'" );
}
}
return true;
}
osg::Node* load(const SGBucket& bucket, const osgDB::Options* opt)
{
osg::ref_ptr<SGReaderWriterOptions> options;
options = SGReaderWriterOptions::copyOrCreate(opt);
// Determine object ranges
_object_range = atof(options->getPluginStringData("SimGear::ROUGH_LOD_RANGE").c_str());
osg::ref_ptr<osg::Group> terrainGroup = new osg::Group;
terrainGroup->setDataVariance(osg::Object::STATIC);
terrainGroup->setName("terrain");
if (_foundBase) {
for (std::list<_Object>::iterator i = _objectList.begin(); i != _objectList.end(); ++i) {
osg::ref_ptr<osg::Node> node;
@@ -448,7 +479,7 @@ struct ReaderWriterSTG::_ModelBin {
}
} else {
SG_LOG(SG_TERRAIN, SG_INFO, " Generating ocean tile: " << bucket.gen_base_path() << "/" << bucket.gen_index_str());
osg::Node* node = SGOceanTile(bucket, options->getMaterialLib());
if (node) {
node->setName("SGOceanTile");
@@ -464,7 +495,7 @@ struct ReaderWriterSTG::_ModelBin {
continue;
i->_elev += elevation(*terrainGroup, SGGeod::fromDeg(i->_lon, i->_lat));
}
for (std::list<_Sign>::iterator i = _signList.begin(); i != _signList.end(); ++i) {
if (!i->_agl)
continue;
@@ -478,7 +509,7 @@ struct ReaderWriterSTG::_ModelBin {
osg::PagedLOD* pagedLOD = new osg::PagedLOD;
pagedLOD->setCenterMode(osg::PagedLOD::USE_BOUNDING_SPHERE_CENTER);
pagedLOD->setName("pagedObjectLOD");
// This should be visible in any case.
// If this is replaced by some lower level of detail, the parent LOD node handles this.
pagedLOD->addChild(terrainGroup, 0, std::numeric_limits<float>::max());
@@ -492,17 +523,20 @@ struct ReaderWriterSTG::_ModelBin {
osg::ref_ptr<osgDB::Options> callbackOptions = new osgDB::Options;
callbackOptions->setReadFileCallback(readFileCallback.get());
pagedLOD->setDatabaseOptions(callbackOptions.get());
pagedLOD->setFileName(pagedLOD->getNumChildren(), "Dummy name - use the stored data in the read file callback");
// Objects may end up displayed up to 2x the object range.
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2.0 * _object_range + SG_TILE_RADIUS);
pagedLOD->setRange(pagedLOD->getNumChildren(), 0, 2.0 * _object_range_rough + SG_TILE_RADIUS);
return pagedLOD;
}
}
double _object_range;
double _object_range_bare;
double _object_range_rough;
double _object_range_detailed;
bool _building_mesh_enabled;
bool _foundBase;
std::list<_Object> _objectList;
std::list<_ObjectStatic> _objectStaticList;
@@ -541,11 +575,11 @@ ReaderWriterSTG::readNode(const std::string& fileName, const osgDB::Options* opt
// For stg meta files, we need options for the search path.
if (!options)
return ReadResult::FILE_NOT_FOUND;
SG_LOG(SG_TERRAIN, SG_INFO, "Loading tile " << fileName);
std::string basePath = bucket.gen_base_path();
// Stop scanning once an object base is found
// This is considered a meta file, so apply the scenery path search
const osgDB::FilePathList& filePathList = options->getDatabasePathList();
@@ -556,7 +590,7 @@ ReaderWriterSTG::readNode(const std::string& fileName, const osgDB::Options* opt
objects.append(basePath);
objects.append(fileName);
modelBin.read(objects.local8BitStr(), options);
SGPath terrain(*i);
terrain.append("Terrain");
terrain.append(basePath);

View File

@@ -992,7 +992,7 @@ public:
bool use_random_buildings = false;
float vegetation_density = 1.0f;
float building_density = 1.0f;
float object_range = SG_OBJECT_RANGE;
float object_range = SG_OBJECT_RANGE_ROUGH;
bool useVBOs = false;
osg::ref_ptr<osg::Group> randomObjects;

View File

@@ -52,7 +52,7 @@ SGLoadBTG(const std::string& path, const simgear::SGReaderWriterOptions* options
double ratio = SG_SIMPLIFIER_RATIO;
double maxLength = SG_SIMPLIFIER_MAX_LENGTH;
double maxError = SG_SIMPLIFIER_MAX_ERROR;
double object_range = SG_OBJECT_RANGE;
double object_range = SG_OBJECT_RANGE_ROUGH;
double tile_min_expiry = SG_TILE_MIN_EXPIRY;
if (options) {

View File

@@ -496,6 +496,13 @@ void SGTerraSync::WorkerThread::run()
}
}
if (_httpServer.empty()) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "ERROR: no http-server found, terrasync will be disabled");
SGGuard<SGMutex> g(_stateLock);
_running = false;
return;
}
runInternal();
{

View File

@@ -9,7 +9,7 @@
#cmakedefine HAVE_FTIME
#cmakedefine HAVE_RINT
#cmakedefine HAVE_TIMEGM
#cmakedefine HAVE_ISNAN
#cmakedefine HAVE_STD_ISNAN
#cmakedefine HAVE_WINDOWS_H
#cmakedefine HAVE_MKDTEMP

View File

@@ -757,14 +757,14 @@ void SGSoundMgr::sample_destroy( SGSoundSample *sample )
bool SGSoundMgr::is_sample_stopped(SGSoundSample *sample)
{
#ifdef ENABLE_SOUND
assert(sample->is_valid_source());
unsigned int source = sample->get_source();
int result;
alGetSourcei( source, AL_SOURCE_STATE, &result );
return (result == AL_STOPPED);
#else
return true;
if ( sample->is_valid_source() ) {
ALint source = sample->get_source();
ALint result;
alGetSourcei( source, AL_SOURCE_STATE, &result );
return (result == AL_STOPPED);
}
#endif
return true;
}
void SGSoundMgr::update_sample_config( SGSoundSample *sample, SGVec3d& position, SGVec3f& orientation, SGVec3f& velocity )

View File

@@ -50,10 +50,8 @@
#endif
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGMisc.hxx>
#if defined(HAVE_STD_ISNAN) && !defined(HAVE_ISNAN)
using std::isnan;
#endif
class SGSampleGroup;
struct refUint {
@@ -74,7 +72,7 @@ typedef sample_group_map::iterator sample_group_map_iterator;
typedef sample_group_map::const_iterator const_sample_group_map_iterator;
inline bool isNaN(float *v) {
return (isnan(v[0]) || isnan(v[1]) || isnan(v[2]));
return (SGMisc<float>::isNaN(v[0]) || SGMisc<float>::isNaN(v[1]) || SGMisc<float>::isNaN(v[2]));
}
#endif // _SG_SOUNDMGR_OPENAL_PRIVATE_HXX

View File

@@ -1 +1 @@
2016.3.1
2016.4.3